@@ -22,111 +22,94 @@ import (
22
22
"log"
23
23
"os"
24
24
"os/exec"
25
- "path/filepath"
26
- "strings"
27
25
28
26
"github.com/spf13/cobra"
29
27
flag "github.com/spf13/pflag"
30
28
31
29
"sigs.k8s.io/kubebuilder/cmd/util"
32
30
"sigs.k8s.io/kubebuilder/pkg/scaffold"
33
- "sigs.k8s.io/kubebuilder/pkg/scaffold/controller"
34
- "sigs.k8s.io/kubebuilder/pkg/scaffold/input"
35
- "sigs.k8s.io/kubebuilder/pkg/scaffold/resource"
31
+ "sigs.k8s.io/kubebuilder/pkg/scaffold/v1/resource"
36
32
)
37
33
38
34
type apiOptions struct {
39
- r * resource.Resource
40
- resourceFlag , controllerFlag * flag.Flag
41
- doResource , doController , doMake bool
35
+ apiScaffolder scaffold.API
36
+ resourceFlag , controllerFlag * flag.Flag
37
+
38
+ // runMake indicates whether to run make or not after scaffolding APIs
39
+ runMake bool
42
40
}
43
41
44
- // APICmd represents the resource command
42
+ func (o * apiOptions ) bindCmdFlags (cmd * cobra.Command ) {
43
+ cmd .Flags ().BoolVar (& o .runMake , "make" , true ,
44
+ "if true, run make after generating files" )
45
+ cmd .Flags ().BoolVar (& o .apiScaffolder .DoResource , "resource" , true ,
46
+ "if set, generate the resource without prompting the user" )
47
+ o .resourceFlag = cmd .Flag ("resource" )
48
+ cmd .Flags ().BoolVar (& o .apiScaffolder .DoController , "controller" , true ,
49
+ "if set, generate the controller without prompting the user" )
50
+ o .controllerFlag = cmd .Flag ("controller" )
51
+ o .apiScaffolder .Resource = resourceForFlags (cmd .Flags ())
52
+ }
53
+
54
+ // resourceForFlags registers flags for Resource fields and returns the Resource
55
+ func resourceForFlags (f * flag.FlagSet ) * resource.Resource {
56
+ r := & resource.Resource {}
57
+ f .StringVar (& r .Kind , "kind" , "" , "resource Kind" )
58
+ f .StringVar (& r .Group , "group" , "" , "resource Group" )
59
+ f .StringVar (& r .Version , "version" , "" , "resource Version" )
60
+ f .BoolVar (& r .Namespaced , "namespaced" , true , "resource is namespaced" )
61
+ f .BoolVar (& r .CreateExampleReconcileBody , "example" , true ,
62
+ "if true an example reconcile body should be written while scaffolding a resource." )
63
+ return r
64
+ }
45
65
66
+ // APICmd represents the resource command
46
67
func (o * apiOptions ) runAddAPI () {
47
68
dieIfNoProject ()
48
69
49
70
reader := bufio .NewReader (os .Stdin )
50
71
if ! o .resourceFlag .Changed {
51
72
fmt .Println ("Create Resource under pkg/apis [y/n]?" )
52
- o .doResource = util .Yesno (reader )
73
+ o .apiScaffolder . DoResource = util .Yesno (reader )
53
74
}
54
75
55
76
if ! o .controllerFlag .Changed {
56
77
fmt .Println ("Create Controller under pkg/controller [y/n]?" )
57
- o .doController = util .Yesno (reader )
78
+ o .apiScaffolder . DoController = util .Yesno (reader )
58
79
}
59
80
60
- if o .r .Group == "" {
61
- log .Fatalf ("Must specify --group" )
62
- }
63
- if o .r .Version == "" {
64
- log .Fatalf ("Must specify --version" )
65
- }
66
- if o .r .Kind == "" {
67
- log .Fatalf ("Must specify --kind" )
81
+ if err := o .apiScaffolder .Validate (); err != nil {
82
+ log .Fatalln (err )
68
83
}
69
84
70
85
fmt .Println ("Writing scaffold for you to edit..." )
71
86
72
- r := o .r
73
- if o .doResource {
74
- fmt .Println (filepath .Join ("pkg" , "apis" , r .Group , r .Version ,
75
- fmt .Sprintf ("%s_types.go" , strings .ToLower (r .Kind ))))
76
- fmt .Println (filepath .Join ("pkg" , "apis" , r .Group , r .Version ,
77
- fmt .Sprintf ("%s_types_test.go" , strings .ToLower (r .Kind ))))
78
-
79
- err := (& scaffold.Scaffold {}).Execute (input.Options {},
80
- & resource.Register {Resource : r },
81
- & resource.Types {Resource : r },
82
- & resource.VersionSuiteTest {Resource : r },
83
- & resource.TypesTest {Resource : r },
84
- & resource.Doc {Resource : r },
85
- & resource.Group {Resource : r },
86
- & resource.AddToScheme {Resource : r },
87
- & resource.CRDSample {Resource : r },
88
- )
89
- if err != nil {
90
- log .Fatal (err )
91
- }
92
- } else {
93
- // disable generation of example reconcile body if not scaffolding resource
94
- // because this could result in a fork-bomb of k8s resources where watching a
95
- // deployment, replicaset etc. results in generating deployment which
96
- // end up generating replicaset, pod etc recursively.
97
- r .CreateExampleReconcileBody = false
87
+ if err := o .apiScaffolder .Scaffold (); err != nil {
88
+ log .Fatal (err )
98
89
}
99
90
100
- if o .doController {
101
- fmt .Println (filepath .Join ("pkg" , "controller" , strings .ToLower (r .Kind ),
102
- fmt .Sprintf ("%s_controller.go" , strings .ToLower (r .Kind ))))
103
- fmt .Println (filepath .Join ("pkg" , "controller" , strings .ToLower (r .Kind ),
104
- fmt .Sprintf ("%s_controller_test.go" , strings .ToLower (r .Kind ))))
105
-
106
- err := (& scaffold.Scaffold {}).Execute (input.Options {},
107
- & controller.Controller {Resource : r },
108
- & controller.AddController {Resource : r },
109
- & controller.Test {Resource : r },
110
- & controller.SuiteTest {Resource : r },
111
- )
112
- if err != nil {
113
- log .Fatal (err )
114
- }
91
+ if err := o .postScaffold (); err != nil {
92
+ log .Fatal (err )
115
93
}
94
+ }
116
95
117
- if o .doMake {
96
+ func (o * apiOptions ) postScaffold () error {
97
+ if o .runMake {
118
98
fmt .Println ("Running make..." )
119
99
cm := exec .Command ("make" ) // #nosec
120
100
cm .Stderr = os .Stderr
121
101
cm .Stdout = os .Stdout
122
102
if err := cm .Run (); err != nil {
123
- log . Fatal ( err )
103
+ return fmt . Errorf ( "error running make: %v" , err )
124
104
}
125
105
}
106
+ return nil
126
107
}
127
108
128
109
func newAPICommand () * cobra.Command {
129
- o := apiOptions {}
110
+ options := apiOptions {
111
+ apiScaffolder : scaffold.API {},
112
+ }
130
113
131
114
apiCmd := & cobra.Command {
132
115
Use : "create api" ,
@@ -158,19 +141,11 @@ After the scaffold is written, api will run make on the project.
158
141
make run
159
142
` ,
160
143
Run : func (cmd * cobra.Command , args []string ) {
161
- o .runAddAPI ()
144
+ options .runAddAPI ()
162
145
},
163
146
}
164
147
165
- apiCmd .Flags ().BoolVar (& o .doMake , "make" , true ,
166
- "if true, run make after generating files" )
167
- apiCmd .Flags ().BoolVar (& o .doResource , "resource" , true ,
168
- "if set, generate the resource without prompting the user" )
169
- o .resourceFlag = apiCmd .Flag ("resource" )
170
- apiCmd .Flags ().BoolVar (& o .doController , "controller" , true ,
171
- "if set, generate the controller without prompting the user" )
172
- o .controllerFlag = apiCmd .Flag ("controller" )
173
- o .r = ResourceForFlags (apiCmd .Flags ())
148
+ options .bindCmdFlags (apiCmd )
174
149
175
150
return apiCmd
176
151
}
@@ -181,15 +156,3 @@ func dieIfNoProject() {
181
156
log .Fatalf ("Command must be run from a directory containing %s" , "PROJECT" )
182
157
}
183
158
}
184
-
185
- // ResourceForFlags registers flags for Resource fields and returns the Resource
186
- func ResourceForFlags (f * flag.FlagSet ) * resource.Resource {
187
- r := & resource.Resource {}
188
- f .StringVar (& r .Kind , "kind" , "" , "resource Kind" )
189
- f .StringVar (& r .Group , "group" , "" , "resource Group" )
190
- f .StringVar (& r .Version , "version" , "" , "resource Version" )
191
- f .BoolVar (& r .Namespaced , "namespaced" , true , "resource is namespaced" )
192
- f .BoolVar (& r .CreateExampleReconcileBody , "example" , true ,
193
- "if true an example reconcile body should be written while scaffolding a resource." )
194
- return r
195
- }
0 commit comments