github.skymusic.top/operator-framework/operator-sdk@v0.8.2/cmd/operator-sdk/add/api.go (about) 1 // Copyright 2018 The Operator-SDK Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package add 16 17 import ( 18 "fmt" 19 20 "github.com/operator-framework/operator-sdk/cmd/operator-sdk/internal/genutil" 21 "github.com/operator-framework/operator-sdk/internal/pkg/scaffold" 22 "github.com/operator-framework/operator-sdk/internal/pkg/scaffold/input" 23 "github.com/operator-framework/operator-sdk/internal/util/projutil" 24 25 log "github.com/sirupsen/logrus" 26 "github.com/spf13/cobra" 27 ) 28 29 var ( 30 apiVersion string 31 kind string 32 ) 33 34 func newAddApiCmd() *cobra.Command { 35 apiCmd := &cobra.Command{ 36 Use: "api", 37 Short: "Adds a new api definition under pkg/apis", 38 Long: `operator-sdk add api --kind=<kind> --api-version=<group/version> creates the 39 api definition for a new custom resource under pkg/apis. This command must be 40 run from the project root directory. If the api already exists at 41 pkg/apis/<group>/<version> then the command will not overwrite and return an 42 error. 43 44 This command runs Kubernetes deepcopy and OpenAPI V3 generators on tagged 45 types in all paths under pkg/apis. Go code is generated under 46 pkg/apis/<group>/<version>/zz_generated.{deepcopy,openapi}.go. CRD's are 47 generated, or updated if they exist for a particular group + version + kind, 48 under deploy/crds/<group>_<version>_<kind>_crd.yaml; OpenAPI V3 validation YAML 49 is generated as a 'validation' object. 50 51 Example: 52 $ operator-sdk add api --api-version=app.example.com/v1alpha1 --kind=AppService 53 $ tree pkg/apis 54 pkg/apis/ 55 ├── addtoscheme_app_appservice.go 56 ├── apis.go 57 └── app 58 └── v1alpha1 59 ├── doc.go 60 ├── register.go 61 ├── appservice_types.go 62 ├── zz_generated.deepcopy.go 63 ├── zz_generated.openapi.go 64 $ tree deploy/crds 65 ├── deploy/crds/app_v1alpha1_appservice_cr.yaml 66 ├── deploy/crds/app_v1alpha1_appservice_crd.yaml 67 `, 68 RunE: apiRun, 69 } 70 71 apiCmd.Flags().StringVar(&apiVersion, "api-version", "", "Kubernetes APIVersion that has a format of $GROUP_NAME/$VERSION (e.g app.example.com/v1alpha1)") 72 if err := apiCmd.MarkFlagRequired("api-version"); err != nil { 73 log.Fatalf("Failed to mark `api-version` flag for `add api` subcommand as required") 74 } 75 apiCmd.Flags().StringVar(&kind, "kind", "", "Kubernetes resource Kind name. (e.g AppService)") 76 if err := apiCmd.MarkFlagRequired("kind"); err != nil { 77 log.Fatalf("Failed to mark `kind` flag for `add api` subcommand as required") 78 } 79 80 return apiCmd 81 } 82 83 func apiRun(cmd *cobra.Command, args []string) error { 84 projutil.MustInProjectRoot() 85 86 // Only Go projects can add apis. 87 if err := projutil.CheckGoProjectCmd(cmd); err != nil { 88 return err 89 } 90 91 log.Infof("Generating api version %s for kind %s.", apiVersion, kind) 92 93 // Create and validate new resource. 94 r, err := scaffold.NewResource(apiVersion, kind) 95 if err != nil { 96 return err 97 } 98 99 absProjectPath := projutil.MustGetwd() 100 101 cfg := &input.Config{ 102 Repo: projutil.CheckAndGetProjectGoPkg(), 103 AbsProjectPath: absProjectPath, 104 } 105 106 s := &scaffold.Scaffold{} 107 err = s.Execute(cfg, 108 &scaffold.Types{Resource: r}, 109 &scaffold.AddToScheme{Resource: r}, 110 &scaffold.Register{Resource: r}, 111 &scaffold.Doc{Resource: r}, 112 &scaffold.CR{Resource: r}, 113 &scaffold.CRD{Resource: r, IsOperatorGo: projutil.IsOperatorGo()}, 114 ) 115 if err != nil { 116 return fmt.Errorf("api scaffold failed: (%v)", err) 117 } 118 119 // update deploy/role.yaml for the given resource r. 120 if err := scaffold.UpdateRoleForResource(r, absProjectPath); err != nil { 121 return fmt.Errorf("failed to update the RBAC manifest for the resource (%v, %v): (%v)", r.APIVersion, r.Kind, err) 122 } 123 124 // Run k8s codegen for deepcopy 125 if err := genutil.K8sCodegen(); err != nil { 126 return err 127 } 128 129 // Generate a validation spec for the new CRD. 130 if err := genutil.OpenAPIGen(); err != nil { 131 return err 132 } 133 134 log.Info("API generation complete.") 135 return nil 136 }