|
1 | 1 | package cmds |
2 | 2 |
|
3 | 3 | import ( |
4 | | - "github.com/rancher/terraform-controller/pkg/apis/terraformcontroller.cattle.io/v1" |
5 | | - "github.com/rancher/terraform-controller/pkg/terraform/execution" |
| 4 | + v1 "github.com/rancher/terraform-controller/pkg/apis/terraformcontroller.cattle.io/v1" |
6 | 5 | "github.com/urfave/cli" |
7 | 6 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" |
8 | 7 | ) |
9 | 8 |
|
10 | | -var simpleExecutionTableHeader = []string{"NAME", "RUNNER NAME", "STATUS"} |
| 9 | +var simpleRunTableHeaders = []string{"RUN NAME", "EXECUTION NAME", "APPROVAL"} |
11 | 10 |
|
12 | | -func ExecutionCommand() cli.Command { |
| 11 | +func RunCommand() cli.Command { |
13 | 12 | return cli.Command{ |
14 | | - Name: "executions", |
15 | | - Aliases: []string{"execution"}, |
16 | | - Usage: "Operations on TF Operator modules", |
| 13 | + Name: "runs", |
| 14 | + Aliases: []string{"run"}, |
| 15 | + Usage: "Manage executions", |
17 | 16 | Action: executionList, |
18 | 17 | Subcommands: []cli.Command{ |
19 | 18 | { |
20 | 19 | Name: "ls", |
21 | | - Usage: "List Executions", |
| 20 | + Usage: "List runs", |
22 | 21 | ArgsUsage: "None", |
23 | 22 | Action: executionList, |
24 | 23 | }, |
25 | 24 | { |
26 | | - Name: "create", |
27 | | - Usage: "Create new executions pointing to a module", |
28 | | - ArgsUsage: "[EXECUTION NAME] [MODULE NAME]", |
29 | | - Action: createExecution, |
30 | | - Flags: []cli.Flag{ |
31 | | - cli.StringFlag{ |
32 | | - Name: "image", |
33 | | - Usage: "Set the image for the execution environment [registry]:org/repo:tag", |
34 | | - Value: execution.DefaultExecutorImage, |
35 | | - }, |
36 | | - cli.BoolFlag{ |
37 | | - Name: "destroy-on-delete", |
38 | | - Usage: "If this execution is deleted a TF destroy is also run", |
39 | | - }, |
40 | | - cli.BoolFlag{ |
41 | | - Name: "autoconfirm", |
42 | | - Usage: "Autoapply TF updates", |
43 | | - }, |
44 | | - cli.StringSliceFlag{ |
45 | | - Name: "secret", |
46 | | - Usage: "Name of Kubernetes secret to use during execution run(Must be in same namespace and pre-created)", |
47 | | - }, |
48 | | - cli.StringSliceFlag{ |
49 | | - Name: "configmap", |
50 | | - Usage: "Name of Kubernetes configmap to use during execution run(Must be in same namespace and pre-created)", |
51 | | - }, |
52 | | - }, |
| 25 | + Name: "approve", |
| 26 | + Usage: "Approves a run", |
| 27 | + ArgsUsage: "[RUN NAME]", |
| 28 | + Action: approveExecution, |
53 | 29 | }, |
54 | 30 | { |
55 | | - Name: "delete", |
56 | | - Usage: "Delete execution", |
57 | | - ArgsUsage: "[EXECUTION NAME]", |
58 | | - Action: deleteExecution, |
59 | | - }, |
60 | | - { |
61 | | - Name: "run", |
62 | | - Usage: "Run the execution", |
63 | | - Action: runExecution, |
64 | | - ArgsUsage: "[EXECUTION NAME]", |
| 31 | + Name: "deny", |
| 32 | + Usage: "Deny approval for a run", |
| 33 | + ArgsUsage: "[RUN NAME]", |
| 34 | + Action: denyExecution, |
65 | 35 | }, |
66 | 36 | }, |
67 | 37 | } |
68 | 38 | } |
69 | 39 |
|
70 | 40 | func executionList(c *cli.Context) error { |
71 | | - kubeConfig := c.GlobalString("kubeconfig") |
72 | 41 | namespace := c.GlobalString("namespace") |
| 42 | + kubeConfig := c.GlobalString("kubeconfig") |
73 | 43 |
|
74 | | - executions, err := getExecutionList(namespace, kubeConfig) |
| 44 | + runs, err := getRunList(namespace, kubeConfig) |
75 | 45 | if err != nil { |
76 | 46 | return err |
77 | 47 | } |
78 | 48 |
|
79 | | - NewTableWriter(getSimpleExecutionTableHeader(), executionListToTableStrings(executions)).Write() |
| 49 | + NewTableWriter(getSimpleRunTableHeader(), runsListToTableStrings(runs)).Write() |
80 | 50 |
|
81 | 51 | return nil |
82 | 52 | } |
83 | 53 |
|
84 | | -func createExecution(c *cli.Context) error { |
85 | | - kubeConfig := c.GlobalString("kubeconfig") |
| 54 | +func approveExecution(c *cli.Context) error { |
86 | 55 | namespace := c.GlobalString("namespace") |
87 | | - |
88 | | - if len(c.Args()) != 2 { |
89 | | - return InvalidArgs{} |
90 | | - } |
91 | | - |
92 | | - executionName := c.Args()[0] |
93 | | - moduleName := c.Args()[1] |
94 | | - |
95 | | - execution := &v1.Execution{ |
96 | | - Spec: v1.ExecutionSpec{ |
97 | | - ModuleName: moduleName, |
98 | | - Image: c.String("image"), |
99 | | - DestroyOnDelete: c.Bool("destroy-on-delete"), |
100 | | - AutoConfirm: c.Bool("autoconfirm"), |
101 | | - Variables: v1.Variables{ |
102 | | - SecretNames: c.StringSlice("secret"), |
103 | | - EnvConfigName: c.StringSlice("configmap"), |
104 | | - }, |
105 | | - }, |
106 | | - } |
107 | | - |
108 | | - execution.Name = executionName |
109 | | - |
110 | | - return doExecutionCreate(namespace, kubeConfig, execution) |
111 | | -} |
112 | | - |
113 | | -func runExecution(c *cli.Context) error { |
114 | 56 | kubeConfig := c.GlobalString("kubeconfig") |
115 | | - namespace := c.GlobalString("namespace") |
116 | 57 |
|
117 | 58 | if len(c.Args()) != 1 { |
118 | 59 | return InvalidArgs{} |
119 | 60 | } |
120 | 61 |
|
121 | 62 | name := c.Args()[0] |
122 | 63 |
|
123 | | - execution, err := getExecution(namespace, kubeConfig, name) |
| 64 | + run, err := getExecution(namespace, kubeConfig, name) |
124 | 65 | if err != nil { |
125 | 66 | return err |
126 | 67 | } |
127 | 68 |
|
128 | | - // Not really an ideal or safe operation. |
129 | | - // Need to create something on the execution type to lock |
130 | | - execution.Spec.Version += 1 |
| 69 | + run.Annotations["approved"] = "yes" |
131 | 70 |
|
132 | | - _, err = saveExecution(kubeConfig, namespace, execution) |
| 71 | + _, err = saveExecution(kubeConfig, namespace, run) |
133 | 72 | return err |
134 | 73 | } |
135 | 74 |
|
136 | | -func deleteExecution(c *cli.Context) error { |
137 | | - kubeConfig := c.GlobalString("kubeconfig") |
| 75 | +func denyExecution(c *cli.Context) error { |
138 | 76 | namespace := c.GlobalString("namespace") |
| 77 | + kubeConfig := c.GlobalString("kubeconfig") |
139 | 78 |
|
140 | 79 | if len(c.Args()) != 1 { |
141 | 80 | return InvalidArgs{} |
142 | 81 | } |
143 | 82 |
|
144 | | - executionName := c.Args()[0] |
145 | | - |
146 | | - return doExecutionDelete(namespace, kubeConfig, executionName) |
147 | | -} |
148 | | - |
149 | | -func doExecutionDelete(namespace, kubeConfig, executionName string) error { |
150 | | - controllers, err := getControllers(kubeConfig, namespace) |
151 | | - |
152 | | - if err != nil { |
153 | | - return err |
154 | | - } |
155 | | - return controllers.executions.Delete(namespace, executionName, &metav1.DeleteOptions{}) |
156 | | -} |
| 83 | + name := c.Args()[0] |
157 | 84 |
|
158 | | -func doExecutionCreate(namespace, kubeConfig string, execution *v1.Execution) error { |
159 | | - controllers, err := getControllers(kubeConfig, namespace) |
| 85 | + run, err := getExecution(namespace, kubeConfig, name) |
160 | 86 | if err != nil { |
161 | 87 | return err |
162 | 88 | } |
163 | 89 |
|
164 | | - execution.Namespace = namespace |
| 90 | + run.Annotations["approved"] = "no" |
165 | 91 |
|
166 | | - _, err = controllers.executions.Create(execution) |
| 92 | + _, err = saveExecution(kubeConfig, namespace, run) |
167 | 93 | return err |
168 | 94 | } |
169 | 95 |
|
170 | | -func getExecution(namespace, kubeConfig, executionName string) (*v1.Execution, error) { |
| 96 | +func getSimpleRunTableHeader() []string { |
| 97 | + return simpleRunTableHeaders |
| 98 | +} |
| 99 | + |
| 100 | +func getRunList(namespace, kubeConfig string) (*v1.ExecutionList, error) { |
171 | 101 | controllers, err := getControllers(kubeConfig, namespace) |
172 | 102 | if err != nil { |
173 | 103 | return nil, err |
174 | 104 | } |
175 | | - return controllers.executions.Get(namespace, executionName, metav1.GetOptions{}) |
| 105 | + |
| 106 | + return controllers.executions.List(namespace, metav1.ListOptions{}) |
176 | 107 | } |
177 | 108 |
|
178 | | -func saveExecution(kubeConfig, namespace string, execution *v1.Execution) (*v1.Execution, error) { |
179 | | - controllers, err := getControllers(kubeConfig, namespace) |
180 | | - if err != nil { |
181 | | - return nil, err |
| 109 | +func runsListToTableStrings(runs *v1.ExecutionList) [][]string { |
| 110 | + var values [][]string |
| 111 | + |
| 112 | + for _, run := range runs.Items { |
| 113 | + approved := "True" |
| 114 | + if approvalStatus, ok := run.Annotations["approved"]; ok && approvalStatus == "" || approvalStatus == "no" { |
| 115 | + approved = "False" |
| 116 | + } |
| 117 | + |
| 118 | + values = append(values, []string{ |
| 119 | + run.Name, |
| 120 | + run.ObjectMeta.OwnerReferences[0].Name, |
| 121 | + approved, |
| 122 | + }) |
182 | 123 | } |
183 | | - return controllers.executions.Update(execution) |
| 124 | + |
| 125 | + return values |
184 | 126 | } |
185 | 127 |
|
186 | | -func getExecutionList(namespace, kubeConfig string) (*v1.ExecutionList, error) { |
| 128 | +func saveExecution(kubeConfig, namespace string, run *v1.Execution) (*v1.Execution, error) { |
187 | 129 | controllers, err := getControllers(kubeConfig, namespace) |
188 | 130 | if err != nil { |
189 | 131 | return nil, err |
190 | 132 | } |
191 | | - return controllers.executions.List(namespace, metav1.ListOptions{}) |
192 | | -} |
193 | 133 |
|
194 | | -func getSimpleExecutionTableHeader() []string { |
195 | | - return simpleExecutionTableHeader |
| 134 | + return controllers.executions.Update(run) |
196 | 135 | } |
197 | 136 |
|
198 | | -func executionListToTableStrings(executions *v1.ExecutionList) [][]string { |
199 | | - var values [][]string |
200 | | - |
201 | | - for _, execution := range executions.Items { |
202 | | - values = append(values, []string{ |
203 | | - execution.Name, |
204 | | - execution.Status.ExecutionRunName, |
205 | | - execution.Status.Conditions[len(execution.Status.Conditions)-1].Type, |
206 | | - }) |
| 137 | +func getExecution(namespace, kubeConfig, name string) (*v1.Execution, error) { |
| 138 | + controllers, err := getControllers(kubeConfig, namespace) |
| 139 | + if err != nil { |
| 140 | + return nil, err |
207 | 141 | } |
208 | 142 |
|
209 | | - return values |
| 143 | + return controllers.executions.Get(namespace, name, metav1.GetOptions{}) |
210 | 144 | } |
0 commit comments