From 812d754d937e6946c4df022a2918d5f5b39f7fe3 Mon Sep 17 00:00:00 2001 From: fanmin shi Date: Thu, 3 May 2018 10:25:19 -0700 Subject: [PATCH 1/2] *: move crd definition of the operator.yaml into crd.yaml --- pkg/generator/deploy_tmpl.go | 7 +++--- pkg/generator/gen_deploy.go | 43 +++++++++++++++++++++----------- pkg/generator/gen_olm_catalog.go | 11 ++++---- pkg/generator/generator.go | 16 +++++++++--- pkg/generator/util.go | 7 ++++++ 5 files changed, 58 insertions(+), 26 deletions(-) create mode 100644 pkg/generator/util.go diff --git a/pkg/generator/deploy_tmpl.go b/pkg/generator/deploy_tmpl.go index 712dc745f3..13ec4ec017 100644 --- a/pkg/generator/deploy_tmpl.go +++ b/pkg/generator/deploy_tmpl.go @@ -14,7 +14,7 @@ package generator -const operatorYamlTmpl = `apiVersion: apiextensions.k8s.io/v1beta1 +const crdYamlTmpl = `apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: {{.KindPlural}}.{{.GroupName}} @@ -27,8 +27,9 @@ spec: singular: {{.KindSingular}} scope: Namespaced version: {{.Version}} ---- -apiVersion: apps/v1 +` + +const operatorYamlTmpl = `apiVersion: apps/v1 kind: Deployment metadata: name: {{.ProjectName}} diff --git a/pkg/generator/gen_deploy.go b/pkg/generator/gen_deploy.go index 4c1122a79f..58b3e96f99 100644 --- a/pkg/generator/gen_deploy.go +++ b/pkg/generator/gen_deploy.go @@ -22,40 +22,55 @@ import ( ) const ( + crdTmplName = "deploy/crd.yaml" operatorTmplName = "deploy/operator.yaml" rbacTmplName = "deploy/rbac.yaml" crTmplName = "deploy/cr.yaml" ) -// OperatorYaml contains all the customized data needed to generate deploy/operator.yaml for a new operator -// when pairing with operatorYamlTmpl template. -type OperatorYaml struct { +// CRDYaml contains data needed to generate deploy/crd.yaml +type CRDYaml struct { Kind string KindSingular string KindPlural string GroupName string Version string - ProjectName string - Image string +} + +// renderCRDYaml generates deploy/crd.yaml +func renderCRDYaml(w io.Writer, kind, apiVersion string) error { + t := template.New(crTmplName) + t, err := t.Parse(crdYamlTmpl) + if err != nil { + return fmt.Errorf("failed to parse crd yaml template: %v", err) + } + + ks := strings.ToLower(kind) + o := CRDYaml{ + Kind: kind, + KindSingular: ks, + KindPlural: toPlural(ks), + GroupName: groupName(apiVersion), + Version: version(apiVersion), + } + return t.Execute(w, o) +} + +// OperatorYaml contains data needed to generate deploy/operator.yaml +type OperatorYaml struct { + ProjectName string + Image string } // renderOperatorYaml generates deploy/operator.yaml. -func renderOperatorYaml(w io.Writer, kind, apiVersion, projectName, image string) error { +func renderOperatorYaml(w io.Writer, projectName, image string) error { t := template.New(operatorTmplName) t, err := t.Parse(operatorYamlTmpl) if err != nil { return fmt.Errorf("failed to parse operator yaml template: %v", err) } - ks := strings.ToLower(kind) o := OperatorYaml{ - Kind: kind, - KindSingular: ks, - // suffix KindSingular with "s" to create KindPlural. - // TODO: make this more grammatically correct for special nouns. - KindPlural: ks + "s", - GroupName: groupName(apiVersion), - Version: version(apiVersion), ProjectName: projectName, Image: image, } diff --git a/pkg/generator/gen_olm_catalog.go b/pkg/generator/gen_olm_catalog.go index 2c54574315..a21a08e28a 100644 --- a/pkg/generator/gen_olm_catalog.go +++ b/pkg/generator/gen_olm_catalog.go @@ -24,7 +24,8 @@ import ( const ( // Sample catalog resource values // TODO: Make this configurable - packageChannel = "alpha" + packageChannel = "alpha" + catalogCRDTmplName = "deploy/olm-catalog/crd.yaml" ) // CatalogPackageConfig contains the data needed to generate deploy/olm-catalog/package.yaml @@ -60,9 +61,9 @@ type CRDConfig struct { Version string } -// renderCRD generates deploy/olm-catalog/crd.yaml -func renderCRD(w io.Writer, config *Config) error { - t := template.New(catalogCRDYaml) +// renderCatalogCRD generates deploy/olm-catalog/crd.yaml +func renderCatalogCRD(w io.Writer, config *Config) error { + t := template.New(catalogCRDTmplName) t, err := t.Parse(crdTmpl) if err != nil { return fmt.Errorf("failed to parse catalog CRD template: %v", err) @@ -72,7 +73,7 @@ func renderCRD(w io.Writer, config *Config) error { crdConfig := CRDConfig{ Kind: config.Kind, KindSingular: kindSingular, - KindPlural: kindSingular + "s", + KindPlural: toPlural(kindSingular), GroupName: groupName(config.APIVersion), Version: version(config.APIVersion), } diff --git a/pkg/generator/generator.go b/pkg/generator/generator.go index 82b184650a..4ae5c01be5 100644 --- a/pkg/generator/generator.go +++ b/pkg/generator/generator.go @@ -58,7 +58,7 @@ const ( crYaml = "cr.yaml" catalogPackageYaml = "package.yaml" catalogCSVYaml = "csv.yaml" - catalogCRDYaml = "crd.yaml" + crdYaml = "crd.yaml" ) type Generator struct { @@ -184,6 +184,14 @@ func renderDeployFiles(deployDir, projectName, apiVersion, kind string) error { return err } + buf = &bytes.Buffer{} + if err := renderCRDYaml(buf, kind, apiVersion); err != nil { + return err + } + if err := writeFileAndPrint(filepath.Join(deployDir, crdYaml), buf.Bytes(), defaultFileMode); err != nil { + return err + } + buf = &bytes.Buffer{} if err := renderCustomResourceYaml(buf, apiVersion, kind); err != nil { return err @@ -194,7 +202,7 @@ func renderDeployFiles(deployDir, projectName, apiVersion, kind string) error { // RenderOperatorYaml generates "deploy/operator.yaml" func RenderOperatorYaml(c *Config, image string) error { buf := &bytes.Buffer{} - if err := renderOperatorYaml(buf, c.Kind, c.APIVersion, c.ProjectName, image); err != nil { + if err := renderOperatorYaml(buf, c.ProjectName, image); err != nil { return err } return ioutil.WriteFile(operatorYaml, buf.Bytes(), defaultFileMode) @@ -225,10 +233,10 @@ func RenderOlmCatalog(c *Config, image, version string) error { // deploy/olm-catalog/crd.yaml buf = &bytes.Buffer{} - if err := renderCRD(buf, c); err != nil { + if err := renderCatalogCRD(buf, c); err != nil { return err } - path = filepath.Join(olmDir, catalogCRDYaml) + path = filepath.Join(olmDir, crdYaml) if err := ioutil.WriteFile(path, buf.Bytes(), defaultFileMode); err != nil { return err } diff --git a/pkg/generator/util.go b/pkg/generator/util.go new file mode 100644 index 0000000000..7d7a654b99 --- /dev/null +++ b/pkg/generator/util.go @@ -0,0 +1,7 @@ +package generator + +// toPlural makes "input" word plural. +// TODO: make this more grammatically correct for special nouns. +func toPlural(input string) string { + return input + "s" +} From aa96f4f5f314e08b1b1000e5ac58e12244ddf410 Mon Sep 17 00:00:00 2001 From: fanmin shi Date: Thu, 3 May 2018 10:26:26 -0700 Subject: [PATCH 2/2] pkg/generator: refactor and update test for deploy/* generation --- pkg/generator/gen_deploy.go | 2 +- pkg/generator/gen_deploy_test.go | 117 +++++++++++++++++++++++++++++++ pkg/generator/generator_test.go | 114 ------------------------------ pkg/generator/test_constants.go | 13 ++++ 4 files changed, 131 insertions(+), 115 deletions(-) create mode 100644 pkg/generator/gen_deploy_test.go create mode 100644 pkg/generator/test_constants.go diff --git a/pkg/generator/gen_deploy.go b/pkg/generator/gen_deploy.go index 58b3e96f99..9bf7e1c734 100644 --- a/pkg/generator/gen_deploy.go +++ b/pkg/generator/gen_deploy.go @@ -39,7 +39,7 @@ type CRDYaml struct { // renderCRDYaml generates deploy/crd.yaml func renderCRDYaml(w io.Writer, kind, apiVersion string) error { - t := template.New(crTmplName) + t := template.New(crdTmplName) t, err := t.Parse(crdYamlTmpl) if err != nil { return fmt.Errorf("failed to parse crd yaml template: %v", err) diff --git a/pkg/generator/gen_deploy_test.go b/pkg/generator/gen_deploy_test.go new file mode 100644 index 0000000000..1f956ab9de --- /dev/null +++ b/pkg/generator/gen_deploy_test.go @@ -0,0 +1,117 @@ +package generator + +import ( + "bytes" + "testing" +) + +const crdYamlExp = `apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: appservices.app.example.com +spec: + group: app.example.com + names: + kind: AppService + listKind: AppServiceList + plural: appservices + singular: appservice + scope: Namespaced + version: v1alpha1 +` + +const operatorYamlExp = `apiVersion: apps/v1 +kind: Deployment +metadata: + name: app-operator +spec: + replicas: 1 + selector: + matchLabels: + name: app-operator + template: + metadata: + labels: + name: app-operator + spec: + containers: + - name: app-operator + image: quay.io/example-inc/app-operator:0.0.1 + command: + - app-operator + imagePullPolicy: Always +` + +const rbacYamlExp = `kind: Role +apiVersion: rbac.authorization.k8s.io/v1beta1 +metadata: + name: app-operator +rules: +- apiGroups: + - app.example.com + resources: + - "*" + verbs: + - "*" +- apiGroups: + - "" + resources: + - pods + - services + - endpoints + - persistentvolumeclaims + - events + - configmaps + - secrets + verbs: + - "*" +- apiGroups: + - apps + resources: + - deployments + - daemonsets + - replicasets + - statefulsets + verbs: + - "*" + +--- + +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1beta1 +metadata: + name: default-account-app-operator +subjects: +- kind: ServiceAccount + name: default +roleRef: + kind: Role + name: app-operator + apiGroup: rbac.authorization.k8s.io +` + +func TestGenDeploy(t *testing.T) { + buf := &bytes.Buffer{} + if err := renderCRDYaml(buf, appKind, appAPIVersion); err != nil { + t.Error(err) + } + if crdYamlExp != buf.String() { + t.Errorf("want %v, got %v", crdYamlExp, buf.String()) + } + + buf = &bytes.Buffer{} + if err := renderOperatorYaml(buf, appProjectName, appImage); err != nil { + t.Error(err) + } + if operatorYamlExp != buf.String() { + t.Errorf("want %v, got %v", operatorYamlExp, buf.String()) + } + + buf = &bytes.Buffer{} + if err := renderRBACYaml(buf, appProjectName, appGroupName); err != nil { + t.Error(err) + } + if rbacYamlExp != buf.String() { + t.Errorf("want %v, got %v", rbacYamlExp, buf.String()) + } +} diff --git a/pkg/generator/generator_test.go b/pkg/generator/generator_test.go index baa379de44..e60dc4b76a 100644 --- a/pkg/generator/generator_test.go +++ b/pkg/generator/generator_test.go @@ -19,17 +19,6 @@ import ( "testing" ) -const ( - // test constants for app-operator - appRepoPath = "github.com/example-inc/" + appProjectName - appKind = "AppService" - appApiDirName = "app" - appAPIVersion = appGroupName + "/" + appVersion - appVersion = "v1alpha1" - appGroupName = "app.example.com" - appProjectName = "app-operator" -) - const mainExp = `package main import ( @@ -378,106 +367,3 @@ func TestGenConfig(t *testing.T) { t.Errorf("want %v, got %v", configExp, buf.String()) } } - -const operatorYamlExp = `apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: appservices.app.example.com -spec: - group: app.example.com - names: - kind: AppService - listKind: AppServiceList - plural: appservices - singular: appservice - scope: Namespaced - version: v1alpha1 ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: app-operator -spec: - replicas: 1 - selector: - matchLabels: - name: app-operator - template: - metadata: - labels: - name: app-operator - spec: - containers: - - name: app-operator - image: quay.io/coreos/operator-sdk-dev:app-operator - command: - - app-operator - imagePullPolicy: Always -` - -const rbacYamlExp = `kind: Role -apiVersion: rbac.authorization.k8s.io/v1beta1 -metadata: - name: app-operator -rules: -- apiGroups: - - app.example.com - resources: - - "*" - verbs: - - "*" -- apiGroups: - - "" - resources: - - pods - - services - - endpoints - - persistentvolumeclaims - - events - - configmaps - - secrets - verbs: - - "*" -- apiGroups: - - apps - resources: - - deployments - - daemonsets - - replicasets - - statefulsets - verbs: - - "*" - ---- - -kind: RoleBinding -apiVersion: rbac.authorization.k8s.io/v1beta1 -metadata: - name: default-account-app-operator -subjects: -- kind: ServiceAccount - name: default -roleRef: - kind: Role - name: app-operator - apiGroup: rbac.authorization.k8s.io -` - -func TestGenDeploy(t *testing.T) { - buf := &bytes.Buffer{} - if err := renderOperatorYaml(buf, appKind, appAPIVersion, appProjectName, "quay.io/coreos/operator-sdk-dev:app-operator"); err != nil { - t.Error(err) - } - if operatorYamlExp != buf.String() { - t.Errorf("want %v, got %v", operatorYamlExp, buf.String()) - } - - buf = &bytes.Buffer{} - if err := renderRBACYaml(buf, appProjectName, appGroupName); err != nil { - t.Error(err) - } - if rbacYamlExp != buf.String() { - t.Errorf("want %v, got %v", rbacYamlExp, buf.String()) - } - -} diff --git a/pkg/generator/test_constants.go b/pkg/generator/test_constants.go new file mode 100644 index 0000000000..4ff7e5cf3f --- /dev/null +++ b/pkg/generator/test_constants.go @@ -0,0 +1,13 @@ +package generator + +const ( + // test constants for app-operator + appImage = "quay.io/example-inc/app-operator:0.0.1" + appRepoPath = "github.com/example-inc/" + appProjectName + appKind = "AppService" + appApiDirName = "app" + appAPIVersion = appGroupName + "/" + appVersion + appVersion = "v1alpha1" + appGroupName = "app.example.com" + appProjectName = "app-operator" +)