diff --git a/cmd/kubebuilder/build/build.go b/cmd/kubebuilder/build/build.go deleted file mode 100644 index 302e05548fb..00000000000 --- a/cmd/kubebuilder/build/build.go +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package build - -import ( - "github.com/spf13/cobra" - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/docs" - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/generate" -) - -var buildCmd = &cobra.Command{ - Use: "build", - Short: "Command group for building source into artifacts.", - Long: `Command group for building source into artifacts.`, - Example: `# Generate code and build the apiserver and controller-manager binaries into bin/ -kubebuilder build docs - -# Rebuild generated code -kubebuilder build generated -`, - Run: RunBuild, - Deprecated: "`build generated` and `build docs` have been moved to `generate` and `docs`", -} - -func AddBuild(cmd *cobra.Command) { - cmd.AddCommand(buildCmd) - - buildCmd.AddCommand(docs.GetDocs()) - buildCmd.AddCommand(generate.GetGenerate()) -} - -func RunBuild(cmd *cobra.Command, args []string) { - cmd.Help() -} diff --git a/cmd/kubebuilder/create/config/config.go b/cmd/kubebuilder/create/config/config.go deleted file mode 100644 index 3327492e386..00000000000 --- a/cmd/kubebuilder/create/config/config.go +++ /dev/null @@ -1,87 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package config - -import ( - "fmt" - "log" - "path/filepath" - - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" - "github.com/spf13/cobra" -) - -// configCmd represents the config command -var configCmd = &cobra.Command{ - Use: "config", - Short: "Generate installation config for the API", - Long: `Generate installation config for the API. - -May create config for just CRDs or for controller-manager and CRDs. -`, - Example: `# Generate config to install controller-manager and CRDs into a cluster -kubebuilder create config --controller-image myimage:v1 --name myextensionname - -# Generate config to install only CRDs -kubebuilder create config --crds - -# Generate config to install controller-manager and CRDs using a Deployment -kubebuilder create config --controller-image myimage:v1 --name myextensionname --controller-type deployment - -# Generate config file at a specific location -kubebuilder create config --crds --output myextensionname.yaml - -`, - Run: func(cmd *cobra.Command, args []string) { - if controllerType != "statefulset" && controllerType != "deployment" { - fmt.Printf( - "Invalid value %s for --controller-type, must be statefulset or deployment.\n", controllerType) - return - } - if controllerImage == "" && !crds { - fmt.Printf("Must either specify --controller-image or set --crds.\n") - return - } - if name == "" && !crds { - fmt.Printf("Must either specify the name of the extension with --name or set --crds.\n") - return - } - generated, err := CodeGenerator{SkipMapValidation: skipMapValidation}.Execute() - if err != nil { - fmt.Printf("%v\n", err) - } else { - util.WriteString(output, generated) - log.Printf("Config written to %s", output) - } - }, -} - -var ( - controllerType, controllerImage, name, output, crdNamespace string - crds, skipMapValidation bool -) - -func AddCreateConfig(cmd *cobra.Command) { - cmd.AddCommand(configCmd) - configCmd.Flags().StringVar(&controllerType, "controller-type", "statefulset", "either statefulset or deployment.") - configCmd.Flags().BoolVar(&crds, "crds", false, "if set to true, only generate crd definitions") - configCmd.Flags().StringVar(&crdNamespace, "crd-namespace", "", "if set, install CRDs to this namespace.") - configCmd.Flags().StringVar(&controllerImage, "controller-image", "", "name of the controller container to run.") - configCmd.Flags().StringVar(&name, "name", "", "name of the installation. used to generate the namespace and resource names.") - configCmd.Flags().StringVar(&output, "output", filepath.Join("hack", "install.yaml"), "location to write yaml to") - configCmd.Flags().BoolVar(&skipMapValidation, "skip-map-validation", true, "if set to true, skip generating validation schema for map type in CRD.") -} diff --git a/cmd/kubebuilder/create/config/gen.go b/cmd/kubebuilder/create/config/gen.go deleted file mode 100644 index 928b1fe331c..00000000000 --- a/cmd/kubebuilder/create/config/gen.go +++ /dev/null @@ -1,336 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package config - -import ( - "fmt" - "sort" - "strings" - - "github.com/ghodss/yaml" - "github.com/golang/glog" - "github.com/kubernetes-sigs/kubebuilder/cmd/internal/codegen/parse" - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/version" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - rbacv1 "k8s.io/api/rbac/v1" - extensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" - "k8s.io/apimachinery/pkg/api/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/gengo/args" -) - -// CodeGenerator generates code for Kubernetes resources and controllers -type CodeGenerator struct { - SkipMapValidation bool -} - -var kblabels = map[string]string{ - "kubebuilder.k8s.io": version.GetVersion().KubeBuilderVersion, -} - -func addLabels(m map[string]string) map[string]string { - for k, v := range kblabels { - m[k] = v - } - m["api"] = name - return m -} - -// Execute parses packages and executes the code generators against the resource and controller packages -func (g CodeGenerator) Execute() (string, error) { - arguments := args.Default() - b, err := arguments.NewBuilder() - if err != nil { - return "", fmt.Errorf("Failed making a parser: %v", err) - } - for _, d := range []string{"./pkg/apis", "./pkg/controller", "./pkg/inject"} { - if err := b.AddDirRecursive(d); err != nil { - return "", fmt.Errorf("Failed making a parser: %v", err) - } - } - c, err := parse.NewContext(b) - if err != nil { - return "", fmt.Errorf("Failed making a context: %v", err) - } - - arguments.CustomArgs = &parse.ParseOptions{SkipMapValidation: g.SkipMapValidation} - - p := parse.NewAPIs(c, arguments) - if crds { - return strings.Join(getCrds(p), "---\n"), nil - } - - result := append([]string{}, - getNamespace(p), - getClusterRole(p), - getClusterRoleBinding(p), - ) - result = append(result, getCrds(p)...) - if controllerType == "deployment" { - result = append(result, getDeployment(p)) - } else { - result = append(result, getStatefuleSetService(p)) - result = append(result, getStatefuleSet(p)) - } - - return strings.Join(result, "---\n"), nil -} - -func getClusterRole(p *parse.APIs) string { - rules := []rbacv1.PolicyRule{} - for _, rule := range p.Rules { - rules = append(rules, rule) - } - for _, g := range p.APIs.Groups { - rule := rbacv1.PolicyRule{ - APIGroups: []string{g.Group + "." + g.Domain}, - Resources: []string{"*"}, - Verbs: []string{"*"}, - } - rules = append(rules, rule) - } - role := rbacv1.ClusterRole{ - TypeMeta: metav1.TypeMeta{ - Kind: "ClusterRole", - APIVersion: "rbac.authorization.k8s.io/v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name + "-role", - Labels: addLabels(map[string]string{}), - }, - Rules: rules, - } - s, err := yaml.Marshal(role) - if err != nil { - glog.Fatalf("Error: %v", err) - } - return string(s) -} - -func getClusterRoleBinding(p *parse.APIs) string { - rolebinding := &rbacv1.ClusterRoleBinding{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "rbac.authorization.k8s.io/v1", - Kind: "ClusterRoleBinding", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("%s-rolebinding", name), - Namespace: fmt.Sprintf("%s-system", name), - Labels: addLabels(map[string]string{}), - }, - Subjects: []rbacv1.Subject{ - { - Name: "default", - Namespace: fmt.Sprintf("%v-system", name), - Kind: "ServiceAccount", - }, - }, - RoleRef: rbacv1.RoleRef{ - Name: fmt.Sprintf("%v-role", name), - Kind: "ClusterRole", - APIGroup: "rbac.authorization.k8s.io", - }, - } - - s, err := yaml.Marshal(rolebinding) - if err != nil { - glog.Fatalf("Error: %v", err) - } - return string(s) -} - -func getDeployment(p *parse.APIs) string { - var replicas int32 = 1 - labels := addLabels(map[string]string{ - "control-plane": "controller-manager", - }) - dep := appsv1.Deployment{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "apps/v1", - Kind: "Deployment", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("%v-controller-manager", name), - Namespace: fmt.Sprintf("%v-system", name), - Labels: labels, - }, - Spec: appsv1.DeploymentSpec{ - Replicas: &replicas, - Selector: &metav1.LabelSelector{ - MatchLabels: labels, - }, - Template: getPodTemplate(labels), - }, - } - - s, err := yaml.Marshal(dep) - if err != nil { - glog.Fatalf("Error: %v", err) - } - return string(s) -} - -func getStatefuleSet(p *parse.APIs) string { - var replicas int32 = 1 - labels := addLabels(map[string]string{ - "control-plane": "controller-manager", - }) - statefulset := appsv1.StatefulSet{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "apps/v1", - Kind: "StatefulSet", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("%v-controller-manager", name), - Namespace: fmt.Sprintf("%v-system", name), - Labels: labels, - }, - Spec: appsv1.StatefulSetSpec{ - ServiceName: fmt.Sprintf("%v-controller-manager-service", name), - Replicas: &replicas, - Selector: &metav1.LabelSelector{ - MatchLabels: labels, - }, - Template: getPodTemplate(labels), - }, - } - - s, err := yaml.Marshal(statefulset) - if err != nil { - glog.Fatalf("Error: %v", err) - } - return string(s) - -} - -func getStatefuleSetService(p *parse.APIs) string { - labels := addLabels(map[string]string{ - "control-plane": "controller-manager", - }) - statefulsetservice := corev1.Service{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "v1", - Kind: "Service", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("%v-controller-manager-service", name), - Namespace: fmt.Sprintf("%v-system", name), - Labels: labels, - }, - Spec: corev1.ServiceSpec{ - Selector: labels, - ClusterIP: "None", - }, - } - - s, err := yaml.Marshal(statefulsetservice) - if err != nil { - glog.Fatalf("Error: %v", err) - } - return string(s) - -} - -func getPodTemplate(labels map[string]string) corev1.PodTemplateSpec { - var terminationPeriod int64 = 10 - return corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: labels, - }, - Spec: corev1.PodSpec{ - TerminationGracePeriodSeconds: &terminationPeriod, - Containers: []corev1.Container{ - { - Name: "controller-manager", - Image: controllerImage, - Command: []string{"/root/controller-manager"}, - Args: []string{"--install-crds=false"}, - Resources: corev1.ResourceRequirements{ - Requests: map[corev1.ResourceName]resource.Quantity{ - "cpu": resource.MustParse("100m"), - "memory": resource.MustParse("20Mi"), - }, - Limits: map[corev1.ResourceName]resource.Quantity{ - "cpu": resource.MustParse("100m"), - "memory": resource.MustParse("30Mi"), - }, - }, - }, - }, - }, - } -} - -func getCrds(p *parse.APIs) []string { - crds := []extensionsv1beta1.CustomResourceDefinition{} - for _, g := range p.APIs.Groups { - for _, v := range g.Versions { - for _, r := range v.Resources { - crd := r.CRD - if len(crdNamespace) > 0 { - crd.Namespace = crdNamespace - } - crd.Labels = addLabels(map[string]string{}) - crds = append(crds, crd) - } - } - } - - sort.Slice(crds, func(i, j int) bool { - iGroup := crds[i].Spec.Group - jGroup := crds[j].Spec.Group - - if iGroup != jGroup { - return iGroup < jGroup - } - - iKind := crds[i].Spec.Names.Kind - jKind := crds[j].Spec.Names.Kind - - return iKind < jKind - }) - - result := []string{} - for i := range crds { - s, err := yaml.Marshal(crds[i]) - if err != nil { - glog.Fatalf("Error: %v", err) - } - result = append(result, string(s)) - } - - return result -} - -func getNamespace(p *parse.APIs) string { - ns := corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("%v-system", name), - Labels: addLabels(map[string]string{}), - }, - TypeMeta: metav1.TypeMeta{ - APIVersion: "v1", - Kind: "Namespace", - }, - } - s, err := yaml.Marshal(ns) - if err != nil { - glog.Fatalf("Error: %v", err) - } - return string(s) -} diff --git a/cmd/kubebuilder/create/controller/controller.go b/cmd/kubebuilder/create/controller/controller.go deleted file mode 100644 index 92eb1fb8008..00000000000 --- a/cmd/kubebuilder/create/controller/controller.go +++ /dev/null @@ -1,128 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controller - -import ( - "fmt" - "path/filepath" - "strings" - - createutil "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/create/util" - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" -) - -type controllerTemplateArgs struct { - BoilerPlate string - Domain string - Group string - Version string - Kind string - Resource string - Repo string - PluralizedKind string - NonNamespacedKind bool - CoreType bool -} - -func doController(dir string, args controllerTemplateArgs) bool { - path := filepath.Join(dir, "pkg", "controller", strings.ToLower(createutil.KindName), "controller.go") - fmt.Printf("\t%s\n", filepath.Join( - "pkg", "controller", strings.ToLower(createutil.KindName), "controller.go")) - return util.WriteIfNotFound(path, "resource-controller-template", resourceControllerTemplate, args) -} - -var resourceControllerTemplate = `{{.BoilerPlate}} - -package {{lower .Kind}} - -import ( - "log" - - "github.com/kubernetes-sigs/kubebuilder/pkg/controller" - "github.com/kubernetes-sigs/kubebuilder/pkg/controller/types" - "k8s.io/client-go/tools/record" - {{if .CoreType}} - {{.Group}}{{.Version}}client "k8s.io/client-go/kubernetes/typed/{{.Group}}/{{.Version}}" - {{.Group}}{{.Version}}lister "k8s.io/client-go/listers/{{.Group}}/{{.Version}}" - {{.Group}}{{.Version}} "k8s.io/api/{{.Group}}/{{.Version}}" - {{.Group}}{{.Version}}informer "k8s.io/client-go/informers/{{.Group}}/{{.Version}}" - {{else}} - {{.Group}}{{.Version}}client "{{.Repo}}/pkg/client/clientset/versioned/typed/{{.Group}}/{{.Version}}" - {{.Group}}{{.Version}}lister "{{.Repo}}/pkg/client/listers/{{.Group}}/{{.Version}}" - {{.Group}}{{.Version}} "{{.Repo}}/pkg/apis/{{.Group}}/{{.Version}}" - {{.Group}}{{.Version}}informer "{{.Repo}}/pkg/client/informers/externalversions/{{.Group}}/{{.Version}}" - {{end}} - "{{.Repo}}/pkg/inject/args" -) - -// EDIT THIS FILE -// This files was created by "kubebuilder create resource" for you to edit. -// Controller implementation logic for {{.Kind}} resources goes here. - -func (bc *{{.Kind}}Controller) Reconcile(k types.ReconcileKey) error { - // INSERT YOUR CODE HERE - log.Printf("Implement the Reconcile function on {{lower .Kind}}.{{.Kind}}Controller to reconcile %s\n", k.Name) - return nil -} -{{if .CoreType}}// +kubebuilder:informers:group={{ .Group }},version={{ .Version }},kind={{ .Kind }}{{end}} -{{if .CoreType}}// +kubebuilder:rbac:groups={{ .Group }},resources={{ .Resource }},verbs=get;watch;list{{end}} -// +kubebuilder:controller:group={{ .Group }},version={{ .Version }},kind={{ .Kind}},resource={{ .Resource }} -type {{.Kind}}Controller struct { - // INSERT ADDITIONAL FIELDS HERE - {{lower .Kind}}Lister {{.Group}}{{.Version}}lister.{{.Kind}}Lister - {{lower .Kind}}client {{.Group}}{{.Version}}client.{{title .Group}}{{title .Version}}Interface - // recorder is an event recorder for recording Event resources to the - // Kubernetes API. - {{lower .Kind}}recorder record.EventRecorder -} - -// ProvideController provides a controller that will be run at startup. Kubebuilder will use codegeneration -// to automatically register this controller in the inject package -func ProvideController(arguments args.InjectArgs) (*controller.GenericController, error) { - // INSERT INITIALIZATIONS FOR ADDITIONAL FIELDS HERE - bc := &{{.Kind}}Controller{ - {{lower .Kind}}Lister: arguments.ControllerManager.GetInformerProvider(&{{.Group}}{{.Version}}.{{.Kind}}{}).({{.Group}}{{.Version}}informer.{{.Kind}}Informer).Lister(), - {{if .CoreType}}{{lower .Kind}}client: arguments.KubernetesClientSet.{{title .Group}}{{title .Version}}(),{{else}} - {{lower .Kind}}client: arguments.Clientset.{{title .Group}}{{title .Version}}(),{{end}} - {{lower .Kind}}recorder: arguments.CreateRecorder("{{.Kind}}Controller"), - } - - // Create a new controller that will call {{.Kind}}Controller.Reconcile on changes to {{.Kind}}s - gc := &controller.GenericController{ - Name: "{{.Kind}}Controller", - Reconcile: bc.Reconcile, - InformerRegistry: arguments.ControllerManager, - } - if err := gc.Watch(&{{.Group}}{{.Version}}.{{.Kind}}{}); err != nil { - return gc, err - } - - // IMPORTANT: - // To watch additional resource types - such as those created by your controller - add gc.Watch* function calls here - // Watch function calls will transform each object event into a {{.Kind}} Key to be reconciled by the controller. - // - // ********** - // For any new Watched types, you MUST add the appropriate // +kubebuilder:informer and // +kubebuilder:rbac - // annotations to the {{.Kind}}Controller and run "kubebuilder generate. - // This will generate the code to start the informers and create the RBAC rules needed for running in a cluster. - // See: - // https://godoc.org/github.com/kubernetes-sigs/kubebuilder/pkg/gen/controller#example-package - // ********** - - return gc, nil -} -` diff --git a/cmd/kubebuilder/create/controller/controllertest.go b/cmd/kubebuilder/create/controller/controllertest.go deleted file mode 100644 index 8f09c65065b..00000000000 --- a/cmd/kubebuilder/create/controller/controllertest.go +++ /dev/null @@ -1,178 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controller - -import ( - "fmt" - "path/filepath" - "strings" - - createutil "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/create/util" - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" -) - -func doControllerTest(dir string, args controllerTemplateArgs) bool { - path := filepath.Join(dir, "pkg", "controller", strings.ToLower(createutil.KindName), - fmt.Sprintf("%s_suite_test.go", - strings.ToLower(createutil.KindName))) - util.WriteIfNotFound(path, "resource-controller-suite-test-template", controllerSuiteTestTemplate, args) - - path = filepath.Join(dir, "pkg", "controller", strings.ToLower(createutil.KindName), "controller_test.go") - fmt.Printf("\t%s\n", filepath.Join( - "pkg", "controller", strings.ToLower(createutil.KindName), "controller_test.go")) - return util.WriteIfNotFound(path, "controller-test-template", controllerTestTemplate, args) -} - -var controllerSuiteTestTemplate = ` -{{.BoilerPlate}} - -package {{lower .Kind}}_test - -import ( - "testing" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "github.com/kubernetes-sigs/kubebuilder/pkg/controller" - "github.com/kubernetes-sigs/kubebuilder/pkg/inject/run" - "github.com/kubernetes-sigs/kubebuilder/pkg/test" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" - {{if not .CoreType}}"{{ .Repo }}/pkg/client/clientset/versioned"{{end}} - "{{ .Repo }}/pkg/inject" - "{{ .Repo }}/pkg/inject/args" -) - -var ( - testenv *test.TestEnvironment - config *rest.Config - {{if not .CoreType}} - cs *versioned.Clientset - {{end}} - ks *kubernetes.Clientset - shutdown chan struct{} - ctrl *controller.GenericController -) - -func TestBee(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecsWithDefaultAndCustomReporters(t, "{{ .Kind }} Suite", []Reporter{test.NewlineReporter{}}) -} - -var _ = BeforeSuite(func() { - testenv = &test.TestEnvironment{CRDs: inject.Injector.CRDs} - var err error - config, err = testenv.Start() - Expect(err).NotTo(HaveOccurred()) - {{if not .CoreType}} - cs = versioned.NewForConfigOrDie(config) - {{end}} - ks = kubernetes.NewForConfigOrDie(config) - - shutdown = make(chan struct{}) - arguments := args.CreateInjectArgs(config) - go func() { - defer GinkgoRecover() - Expect(inject.RunAll(run.RunArguments{Stop: shutdown}, arguments)). - To(BeNil()) - }() - - // Wait for RunAll to create the controllers and then set the reference - defer GinkgoRecover() - Eventually(func() interface{} { return arguments.ControllerManager.GetController("{{.Kind}}Controller") }). - Should(Not(BeNil())) - ctrl = arguments.ControllerManager.GetController("{{.Kind}}Controller") -}) - -var _ = AfterSuite(func() { - close(shutdown) - testenv.Stop() -}) -` - -var controllerTestTemplate = ` -{{.BoilerPlate}} - -package {{ lower .Kind }}_test - -import ( - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - - "github.com/kubernetes-sigs/kubebuilder/pkg/controller/types" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - {{if .CoreType}} - . "k8s.io/api/{{.Group}}/{{.Version}}" - . "k8s.io/client-go/kubernetes/typed/{{.Group}}/{{.Version}}" - {{else}} - . "{{ .Repo }}/pkg/apis/{{ .Group }}/{{ .Version }}" - . "{{ .Repo }}/pkg/client/clientset/versioned/typed/{{ .Group }}/{{ .Version }}" - {{end}} -) - -// EDIT THIS FILE! -// Created by "kubebuilder create resource" for you to implement controller logic tests - -var _ = Describe("{{ .Kind }} controller", func() { - var instance {{ .Kind }} - var expectedKey types.ReconcileKey - var client {{ .Kind }}Interface - - BeforeEach(func() { - instance = {{ .Kind }}{} - instance.Name = "instance-1" - expectedKey = types.ReconcileKey{ - Namespace: "{{ if not .NonNamespacedKind }}default{{ end }}", - Name: "instance-1", - } - }) - - AfterEach(func() { - client.Delete(instance.Name, &metav1.DeleteOptions{}) - }) - - Describe("when creating a new object", func() { - It("invoke the reconcile method", func() { - after := make(chan struct{}) - ctrl.AfterReconcile = func(key types.ReconcileKey, err error) { - defer func() { - // Recover in case the key is reconciled multiple times - defer func() { recover() }() - close(after) - }() - defer GinkgoRecover() - Expect(key).To(Equal(expectedKey)) - Expect(err).ToNot(HaveOccurred()) - } - - // Create the instance - {{if .CoreType}} - client = ks.{{title .Group}}{{title .Version}}().{{ plural .Kind }}({{ if not .NonNamespacedKind }}"default"{{ end }}) - {{else}} - client = cs.{{title .Group}}{{title .Version}}().{{ plural .Kind }}({{ if not .NonNamespacedKind }}"default"{{ end }}) - {{end}} - _, err := client.Create(&instance) - Expect(err).ShouldNot(HaveOccurred()) - - // Wait for reconcile to happen - Eventually(after, "10s", "100ms").Should(BeClosed()) - - // INSERT YOUR CODE HERE - test conditions post reconcile - }) - }) -}) -` diff --git a/cmd/kubebuilder/create/controller/run.go b/cmd/kubebuilder/create/controller/run.go deleted file mode 100644 index e0cc5b45950..00000000000 --- a/cmd/kubebuilder/create/controller/run.go +++ /dev/null @@ -1,119 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controller - -import ( - "fmt" - "log" - "os" - - "strings" - - createutil "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/create/util" - generatecmd "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/generate" - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" - "github.com/markbates/inflect" - "github.com/spf13/cobra" -) - -type ControllerArguments struct { - nonNamespacedKind bool - generate bool - CoreType bool - SkipRBACValidation bool -} - -func AddCreateController(cmd *cobra.Command) { - var c ControllerArguments - - createControllerCmd := &cobra.Command{ - Use: "controller", - Short: "Creates a controller for an API group, version and resource", - Long: `Creates a controller for an API group, version and resource. - -Also creates: -- controller reconcile function -- tests for the controller -`, - Example: `# Create a controller for resource "Bee" in the "insect" group with version "v1beta" -kubebuilder create controller --group insect --version v1beta1 --kind Bee - -# Create a controller for k8s core type "Deployment" in the "apps" group with version "v1beta2" -kubebuilder create controller --group apps --version v1beta2 --kind Deployment --core-type -`, - Run: c.RunCreateController, - } - createutil.RegisterResourceFlags(createControllerCmd) - createControllerCmd.Flags().BoolVar(&c.nonNamespacedKind, "non-namespaced", false, "if set, the API kind will be non namespaced") - createControllerCmd.Flags().BoolVar(&c.generate, "generate", true, "generate controller code") - createControllerCmd.Flags().BoolVar(&c.CoreType, "core-type", false, "generate controller for core type") - createControllerCmd.Flags().BoolVar(&c.SkipRBACValidation, "skip-rbac-validation", false, "if set to true, skip validation for RBAC annotations for the controller.") - cmd.AddCommand(createControllerCmd) -} - -func (c *ControllerArguments) RunCreateController(cmd *cobra.Command, args []string) { - if _, err := os.Stat("pkg"); err != nil { - log.Fatalf("could not find 'pkg' directory. must run kubebuilder init before creating controller") - } - - util.GetDomain() - c.Validate() - - cr := util.GetCopyright(createutil.Copyright) - - fmt.Printf("Creating controller ...\n") - c.CreateController(cr) - if c.generate { - fmt.Printf("Generating code for new controller... " + - "Regenerate after editing controller files by running `kubebuilder generate clean; kubebuilder generate`.\n") - if c.SkipRBACValidation { - args = append(args, "--skip-rbac-validation") - } - generatecmd.RunGenerate(cmd, args) - } - fmt.Printf("Next: Run the controller and create an instance with:\n" + - "$ GOBIN=${PWD}/bin go install ${PWD#$GOPATH/src/}/cmd/controller-manager\n" + - "$ bin/controller-manager --kubeconfig ~/.kube/config\n" + - "$ kubectl apply -f hack/sample/" + strings.ToLower(createutil.KindName) + ".yaml\n") -} - -func (c *ControllerArguments) Validate() { - createutil.ValidateResourceFlags() -} - -func (c *ControllerArguments) CreateController(boilerplate string) { - args := controllerTemplateArgs{ - boilerplate, - util.Domain, - createutil.GroupName, - createutil.VersionName, - createutil.KindName, - createutil.ResourceName, - util.Repo, - inflect.NewDefaultRuleset().Pluralize(createutil.KindName), - c.nonNamespacedKind, - c.CoreType, - } - - dir, err := os.Getwd() - if err != nil { - log.Fatal(err) - } - fmt.Printf("Edit your controller function...\n") - doController(dir, args) - doControllerTest(dir, args) -} diff --git a/cmd/kubebuilder/create/create.go b/cmd/kubebuilder/create/create.go deleted file mode 100644 index f75d40452a5..00000000000 --- a/cmd/kubebuilder/create/create.go +++ /dev/null @@ -1,50 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package create - -import ( - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/create/config" - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/create/controller" - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/create/example" - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/create/resource" - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/create/util" - "github.com/spf13/cobra" -) - -var createCmd = &cobra.Command{ - Use: "create", - Short: "Command group for bootstrapping new resources.", - Long: `Command group for bootstrapping new resources.`, - Example: `# Create new resource "Bee" in the "insect" group with version "v1beta" -# Will also create a test, controller and controller test for the resource -kubebuilder create resource --group insect --version v1beta --kind Bee -`, - Run: RunCreate, -} - -func AddCreate(cmd *cobra.Command) { - cmd.AddCommand(createCmd) - util.RegisterCopyrightFlag(cmd) - resource.AddCreateResource(createCmd) - config.AddCreateConfig(createCmd) - example.AddCreateExample(createCmd) - controller.AddCreateController(createCmd) -} - -func RunCreate(cmd *cobra.Command, args []string) { - cmd.Help() -} diff --git a/cmd/kubebuilder/create/example/example.go b/cmd/kubebuilder/create/example/example.go deleted file mode 100644 index ae3256267b1..00000000000 --- a/cmd/kubebuilder/create/example/example.go +++ /dev/null @@ -1,104 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package example - -import ( - "fmt" - "log" - "os" - "path/filepath" - - "strings" - - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" - "github.com/spf13/cobra" -) - -// configCmd represents the config command -var configCmd = &cobra.Command{ - Use: "example", - Short: "Create the docs example scaffolding for an API", - Long: `Create the docs example scaffoling for an API. - -Example is written to docs/reference/examples//.yaml -`, - Example: `# Create a new documentation example under docs/reference/examples/mykind/mykind.yaml -kubebuilder create example --kind MyKind --version v1beta1 --group mygroup.my.domain -`, - Run: func(cmd *cobra.Command, args []string) { - if kind == "" { - fmt.Printf("Must specify --kind\n") - return - } - if version == "" { - fmt.Printf("Must specify --version\n") - return - } - if group == "" { - fmt.Printf("Must specify --group\n") - return - } - wd, err := os.Getwd() - if err != nil { - log.Fatalf("error: %v\n", err) - } - path := filepath.Join(wd, outputDir, "examples", strings.ToLower(kind), strings.ToLower(kind)+".yaml") - CodeGenerator{}.Execute(path) - fmt.Printf("Edit your controller function...\n") - fmt.Printf("\t%s\n", path) - }, -} - -var kind, version, group, outputDir string - -func AddCreateExample(cmd *cobra.Command) { - cmd.AddCommand(configCmd) - configCmd.Flags().StringVar(&kind, "kind", "", "api Kind.") - configCmd.Flags().StringVar(&group, "group", "", "api group.") - configCmd.Flags().StringVar(&version, "version", "", "api version.") - configCmd.Flags().StringVar(&outputDir, "output-dir", filepath.Join("docs", "reference"), "reference docs location") - -} - -// CodeGenerator generates code for Kubernetes resources and controllers -type CodeGenerator struct{} - -// Execute parses packages and executes the code generators against the resource and controller packages -func (g CodeGenerator) Execute(path string) error { - os.Remove(path) - args := ConfigArgs{ - Group: group, - Version: version, - Kind: strings.ToLower(kind), - } - util.WriteIfNotFound(path, "example-config-template", exampleConfigTemplate, args) - return nil -} - -type ConfigArgs struct { - Group, Version, Kind string -} - -var exampleConfigTemplate = `note: {{ .Kind }} example -sample: | - apiVersion: {{ .Version }} - kind: {{ .Kind }} - metadata: - name: {{ lower .Kind }} - spec: - todo: "write me" -` diff --git a/cmd/kubebuilder/create/resource/example.go b/cmd/kubebuilder/create/resource/example.go deleted file mode 100644 index 358d96987ac..00000000000 --- a/cmd/kubebuilder/create/resource/example.go +++ /dev/null @@ -1,44 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package resource - -import ( - "fmt" - "os" - "path/filepath" - "strings" - - createutil "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/create/util" - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" -) - -func doExample(dir string, args resourceTemplateArgs) bool { - os.MkdirAll(filepath.Join("docs", "examples"), 0700) - docpath := filepath.Join("docs", "examples", - strings.ToLower(createutil.KindName), - fmt.Sprintf("%s.yaml", strings.ToLower(createutil.KindName))) - return util.WriteIfNotFound(docpath, "example-template", exampleTemplate, args) -} - -var exampleTemplate = `note: {{ .Kind }} Example -sample: | - apiVersion: {{ .Group }}.{{ .Domain }}/{{ .Version }} - kind: {{ .Kind }} - metadata: - name: {{ lower .Kind }}-example - spec: -` diff --git a/cmd/kubebuilder/create/resource/group.go b/cmd/kubebuilder/create/resource/group.go deleted file mode 100644 index 6635e3345ce..00000000000 --- a/cmd/kubebuilder/create/resource/group.go +++ /dev/null @@ -1,68 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package resource - -import ( - "log" - "os" - "path/filepath" - - createutil "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/create/util" - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" -) - -func createGroup(boilerplate string) { - dir, err := os.Getwd() - if err != nil { - log.Fatal(err) - } - - a := groupTemplateArgs{ - boilerplate, - util.Domain, - createutil.GroupName, - } - - path := filepath.Join(dir, "pkg", "apis", createutil.GroupName, "doc.go") - util.WriteIfNotFound(path, "group-template", groupTemplate, a) - - //path = filepath.Join(dir, "pkg", "apis", createutil.GroupName, "install", "doc.go") - //util.WriteIfNotFound(path, "install-template", installTemplate, a) -} - -type groupTemplateArgs struct { - BoilerPlate string - Domain string - Name string -} - -var groupTemplate = ` -{{.BoilerPlate}} - - -// +k8s:deepcopy-gen=package,register -// +groupName={{.Name}}.{{.Domain}} - -// Package api is the internal version of the API. -package {{.Name}} -` - -var installTemplate = ` -{{.BoilerPlate}} - -package install -` diff --git a/cmd/kubebuilder/create/resource/resource.go b/cmd/kubebuilder/create/resource/resource.go deleted file mode 100644 index 6c26766458e..00000000000 --- a/cmd/kubebuilder/create/resource/resource.go +++ /dev/null @@ -1,92 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package resource - -import ( - "fmt" - "path/filepath" - "strings" - - createutil "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/create/util" - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" -) - -type resourceTemplateArgs struct { - BoilerPlate string - Domain string - Group string - Version string - Kind string - Resource string - Repo string - PluralizedKind string - NonNamespacedKind bool - HasStatusSubresource bool - Categories []string -} - -func doResource(dir string, args resourceTemplateArgs) bool { - typesFileName := fmt.Sprintf("%s_types.go", strings.ToLower(createutil.KindName)) - path := filepath.Join(dir, "pkg", "apis", createutil.GroupName, createutil.VersionName, typesFileName) - fmt.Printf("\t%s\n", filepath.Join( - "pkg", "apis", createutil.GroupName, createutil.VersionName, typesFileName)) - return util.WriteIfNotFound(path, "resource-template", resourceTemplate, args) -} - -var resourceTemplate = ` -{{.BoilerPlate}} - -package {{.Version}} - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// EDIT THIS FILE! -// Created by "kubebuilder create resource" for you to implement the {{.Kind}} resource schema definition -// as a go struct. -// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. - -// {{.Kind}}Spec defines the desired state of {{.Kind}} -type {{.Kind}}Spec struct { - // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster - // Important: Run "kubebuilder generate" to regenerate code after modifying this file -} - -// {{.Kind}}Status defines the observed state of {{.Kind}} -type {{.Kind}}Status struct { - // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster - // Important: Run "kubebuilder generate" to regenerate code after modifying this file -} - -// +genclient -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -{{- if .NonNamespacedKind }} -// +genclient:nonNamespaced -{{- end }} - -// {{.Kind}} -// +k8s:openapi-gen=true -// +kubebuilder:resource:path={{.Resource}} -type {{.Kind}} struct { - metav1.TypeMeta ` + "`" + `json:",inline"` + "`" + ` - metav1.ObjectMeta ` + "`" + `json:"metadata,omitempty"` + "`" + ` - - Spec {{.Kind}}Spec ` + "`" + `json:"spec,omitempty"` + "`" + ` - Status {{.Kind}}Status ` + "`" + `json:"status,omitempty"` + "`" + ` -} -` diff --git a/cmd/kubebuilder/create/resource/resourcetest.go b/cmd/kubebuilder/create/resource/resourcetest.go deleted file mode 100644 index d2a9ce8d354..00000000000 --- a/cmd/kubebuilder/create/resource/resourcetest.go +++ /dev/null @@ -1,152 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package resource - -import ( - "fmt" - "path/filepath" - "strings" - - createutil "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/create/util" - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" -) - -func doResourceTest(dir string, args resourceTemplateArgs) bool { - typesFileName := fmt.Sprintf("%s_suite_test.go", strings.ToLower(createutil.VersionName)) - path := filepath.Join(dir, "pkg", "apis", createutil.GroupName, createutil.VersionName, typesFileName) - util.WriteIfNotFound(path, "version-suite-test-template", resourceSuiteTestTemplate, args) - - typesFileName = fmt.Sprintf("%s_types_test.go", strings.ToLower(createutil.KindName)) - path = filepath.Join(dir, "pkg", "apis", createutil.GroupName, createutil.VersionName, typesFileName) - fmt.Printf("\t%s\n", filepath.Join( - "pkg", "apis", createutil.GroupName, createutil.VersionName, typesFileName, - )) - return util.WriteIfNotFound(path, "resource-test-template", resourceTestTemplate, args) -} - -var resourceSuiteTestTemplate = ` -{{.BoilerPlate}} - -package {{.Version}}_test - -import ( - "testing" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "github.com/kubernetes-sigs/kubebuilder/pkg/test" - "k8s.io/client-go/rest" - - "{{ .Repo }}/pkg/inject" - "{{ .Repo }}/pkg/client/clientset/versioned" -) - -var testenv *test.TestEnvironment -var config *rest.Config -var cs *versioned.Clientset - -func Test{{title .Version}}(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecsWithDefaultAndCustomReporters(t, "v1 Suite", []Reporter{test.NewlineReporter{}}) -} - -var _ = BeforeSuite(func() { - testenv = &test.TestEnvironment{CRDs: inject.Injector.CRDs} - - var err error - config, err = testenv.Start() - Expect(err).NotTo(HaveOccurred()) - - cs = versioned.NewForConfigOrDie(config) -}) - -var _ = AfterSuite(func() { - testenv.Stop() -}) -` - -var resourceTestTemplate = ` -{{.BoilerPlate}} - -package {{.Version}}_test - -import ( - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - . "{{.Repo}}/pkg/apis/{{.Group}}/{{.Version}}" - . "{{.Repo}}/pkg/client/clientset/versioned/typed/{{.Group}}/{{.Version}}" -) - -// EDIT THIS FILE! -// Created by "kubebuilder create resource" for you to implement the {{.Kind}} resource tests - -var _ = Describe("{{.Kind}}", func() { - var instance {{ .Kind}} - var expected {{ .Kind}} - var client {{ .Kind}}Interface - - BeforeEach(func() { - instance = {{ .Kind}}{} - instance.Name = "instance-1" - - expected = instance - }) - - AfterEach(func() { - client.Delete(instance.Name, &metav1.DeleteOptions{}) - }) - - // INSERT YOUR CODE HERE - add more "Describe" tests - - // Automatically created storage tests - Describe("when sending a storage request", func() { - Context("for a valid config", func() { - It("should provide CRUD access to the object", func() { - client = cs.{{ title .Group}}{{title .Version}}().{{plural .Kind}}({{ if not .NonNamespacedKind }}"default"{{ end }}) - - By("returning success from the create request") - actual, err := client.Create(&instance) - Expect(err).ShouldNot(HaveOccurred()) - - By("defaulting the expected fields") - Expect(actual.Spec).To(Equal(expected.Spec)) - - By("returning the item for list requests") - result, err := client.List(metav1.ListOptions{}) - Expect(err).ShouldNot(HaveOccurred()) - Expect(result.Items).To(HaveLen(1)) - Expect(result.Items[0].Spec).To(Equal(expected.Spec)) - - By("returning the item for get requests") - actual, err = client.Get(instance.Name, metav1.GetOptions{}) - Expect(err).ShouldNot(HaveOccurred()) - Expect(actual.Spec).To(Equal(expected.Spec)) - - By("deleting the item for delete requests") - err = client.Delete(instance.Name, &metav1.DeleteOptions{}) - Expect(err).ShouldNot(HaveOccurred()) - result, err = client.List(metav1.ListOptions{}) - Expect(err).ShouldNot(HaveOccurred()) - Expect(result.Items).To(HaveLen(0)) - }) - }) - }) -}) -` diff --git a/cmd/kubebuilder/create/resource/run.go b/cmd/kubebuilder/create/resource/run.go deleted file mode 100644 index 08ec7be9c3b..00000000000 --- a/cmd/kubebuilder/create/resource/run.go +++ /dev/null @@ -1,136 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package resource - -import ( - "fmt" - "log" - "os" - "strings" - - controllerct "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/create/controller" - createutil "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/create/util" - generatecmd "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/generate" - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" - "github.com/markbates/inflect" - "github.com/spf13/cobra" -) - -var ( - nonNamespacedKind bool - controller bool - generate bool - skipRBACValidation bool -) - -var createResourceCmd = &cobra.Command{ - Use: "resource", - Short: "Creates an API group, version and resource", - Long: `Creates an API group, version and resource. - -Also creates: -- tests for the resource -- controller reconcile function -- tests for the controller -`, - Example: `# Create new resource "Bee" in the "insect" group with version "v1beta" -# Will also create a controller -kubebuilder create resource --group insect --version v1beta1 --kind Bee - -# Create new resource without creating a controller for the resource -kubebuilder create resource --group insect --version v1beta1 --kind Bee --controller=false - -# Create a non-namespaced resource -kubebuilder create resource --group insect --version v1beta1 --kind Bee --non-namespaced=true -`, - Run: RunCreateResource, -} - -func AddCreateResource(cmd *cobra.Command) { - createutil.RegisterResourceFlags(createResourceCmd) - createResourceCmd.Flags().BoolVar(&nonNamespacedKind, "non-namespaced", false, "if set, the API kind will be non namespaced") - createResourceCmd.Flags().BoolVar(&controller, "controller", true, "if true, generate the controller code for the resource") - createResourceCmd.Flags().BoolVar(&generate, "generate", true, "generate source code") - createResourceCmd.Flags().BoolVar(&createutil.AllowPluralKind, "plural-kind", false, "allow the kind to be plural") - createResourceCmd.Flags().BoolVar(&skipRBACValidation, "skip-rbac-validation", false, "if set to true, skip validation for RBAC annotations") - cmd.AddCommand(createResourceCmd) -} - -func RunCreateResource(cmd *cobra.Command, args []string) { - if _, err := os.Stat("pkg"); err != nil { - log.Fatalf("could not find 'pkg' directory. must run kubebuilder init before creating resources") - } - - util.GetDomain() - createutil.ValidateResourceFlags() - - cr := util.GetCopyright(createutil.Copyright) - - fmt.Printf("Creating API files for you to edit...\n") - createGroup(cr) - createVersion(cr) - createResource(cr) - if generate { - fmt.Printf("Generating code for new resource... " + - "Regenerate after editing resources files by running `kubebuilder generate clean; kubebuilder generate`.\n") - if skipRBACValidation { - args = append(args, "--skip-rbac-validation") - } - generatecmd.RunGenerate(cmd, args) - } - fmt.Printf("Next: Install the API, run the controller and create an instance with:\n" + - "$ GOBIN=${PWD}/bin go install ${PWD#$GOPATH/src/}/cmd/controller-manager\n" + - "$ bin/controller-manager --kubeconfig ~/.kube/config\n" + - "$ kubectl apply -f hack/sample/" + strings.ToLower(createutil.KindName) + ".yaml\n") -} - -func createResource(boilerplate string) { - args := resourceTemplateArgs{ - boilerplate, - util.Domain, - createutil.GroupName, - createutil.VersionName, - createutil.KindName, - createutil.ResourceName, - util.Repo, - inflect.NewDefaultRuleset().Pluralize(createutil.KindName), - nonNamespacedKind, - false, - nil, - } - - dir, err := os.Getwd() - if err != nil { - log.Fatal(err) - } - - fmt.Printf("Edit your API schema...\n") - doResource(dir, args) - doResourceTest(dir, args) - - if controller { - fmt.Printf("Creating controller ...\n") - c := controllerct.ControllerArguments{ - CoreType: false, - SkipRBACValidation: skipRBACValidation, - } - c.CreateController(boilerplate) - } - - fmt.Printf("Edit your sample resource instance...\n") - doSample(dir, args) -} diff --git a/cmd/kubebuilder/create/resource/sample.go b/cmd/kubebuilder/create/resource/sample.go deleted file mode 100644 index 713fd701dca..00000000000 --- a/cmd/kubebuilder/create/resource/sample.go +++ /dev/null @@ -1,42 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package resource - -import ( - "fmt" - "os" - "path/filepath" - "strings" - - createutil "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/create/util" - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" -) - -func doSample(dir string, args resourceTemplateArgs) bool { - os.MkdirAll(filepath.Join("hack", "sample"), 0700) - samplepath := filepath.Join("hack", "sample", fmt.Sprintf("%s.yaml", strings.ToLower(createutil.KindName))) - fmt.Printf("\t%s\n", samplepath) - return util.WriteIfNotFound(samplepath, "sample-template", sampleTemplate, args) -} - -var sampleTemplate = `apiVersion: {{ .Group }}.{{ .Domain }}/{{ .Version }} -kind: {{ .Kind }} -metadata: - name: {{ lower .Kind }}-example -spec: - foo: bar -` diff --git a/cmd/kubebuilder/create/resource/sharedinformers.go b/cmd/kubebuilder/create/resource/sharedinformers.go deleted file mode 100644 index 068b1641648..00000000000 --- a/cmd/kubebuilder/create/resource/sharedinformers.go +++ /dev/null @@ -1,52 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package resource - -import ( - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" - "path/filepath" -) - -func doSharedInformers(dir string, args resourceTemplateArgs) bool { - path := filepath.Join(dir, "pkg", "controller", "sharedinformers", "informers.go") - return util.WriteIfNotFound(path, "sharedinformer-template", sharedInformersTemplate, args) -} - -var sharedInformersTemplate = ` -{{.BoilerPlate}} - -package sharedinformers - -// EDIT THIS FILE! -// Created by "kubebuilder create resource" for you to start additional shared informers - -// SetupKubernetesTypes registers the config for watching Kubernetes types -func (si *SharedInformers) SetupKubernetesTypes() bool { - return true -} - -// StartAdditionalInformers starts watching Deployments -func (si *SharedInformers) StartAdditionalInformers(shutdown <-chan struct{}) { - // Start specific Kubernetes API informers here. Note, it is only necessary - // to start 1 informer for each Kind. (e.g. only 1 Deployment informer) - - // Uncomment this to start listening for Deployment Create / Update / Deletes - // go si.KubernetesFactory.Apps().V1beta1().Deployments().Informer().RunInformersAndControllers(shutdown) - - // INSERT YOUR CODE HERE - start additional shared informers -} -` diff --git a/cmd/kubebuilder/create/resource/version.go b/cmd/kubebuilder/create/resource/version.go deleted file mode 100644 index cf431096763..00000000000 --- a/cmd/kubebuilder/create/resource/version.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package resource - -import ( - "log" - "os" - "path/filepath" - - createutil "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/create/util" - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" -) - -func createVersion(boilerplate string) { - dir, err := os.Getwd() - if err != nil { - log.Fatalf("%v\n", err) - os.Exit(-1) - } - path := filepath.Join(dir, "pkg", "apis", createutil.GroupName, createutil.VersionName, "doc.go") - util.WriteIfNotFound(path, "version-template", versionTemplate, versionTemplateArgs{ - boilerplate, - util.Domain, - createutil.GroupName, - createutil.VersionName, - util.Repo, - }) -} - -type versionTemplateArgs struct { - BoilerPlate string - Domain string - Group string - Version string - Repo string -} - -var versionTemplate = ` -{{.BoilerPlate}} - -// Api versions allow the api contract for a resource to be changed while keeping -// backward compatibility by support multiple concurrent versions -// of the same resource - -// +k8s:openapi-gen=true -// +k8s:deepcopy-gen=package,register -// +k8s:conversion-gen={{.Repo}}/pkg/apis/{{.Group}} -// +k8s:defaulter-gen=TypeMeta -// +groupName={{.Group}}.{{.Domain}} -package {{.Version}} // import "{{.Repo}}/pkg/apis/{{.Group}}/{{.Version}}" -` diff --git a/cmd/kubebuilder/create/util/util.go b/cmd/kubebuilder/create/util/util.go deleted file mode 100644 index 84879307e40..00000000000 --- a/cmd/kubebuilder/create/util/util.go +++ /dev/null @@ -1,83 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - "log" - "path/filepath" - "regexp" - "strings" - - "github.com/markbates/inflect" - "github.com/spf13/cobra" - - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" -) - -var ( - GroupName, KindName, VersionName, ResourceName, Copyright string - AllowPluralKind bool -) - -func ValidateResourceFlags() { - util.GetDomain() - if len(GroupName) == 0 { - log.Fatalf("Must specify --group") - } - if len(VersionName) == 0 { - log.Fatalf("Must specify --version") - } - if len(KindName) == 0 { - log.Fatal("Must specify --kind") - } - - rs := inflect.NewDefaultRuleset() - if len(ResourceName) == 0 { - if !AllowPluralKind && rs.Pluralize(KindName) == KindName && rs.Singularize(KindName) != KindName { - log.Fatalf("Client code generation expects singular --kind (e.g. %s)."+ - "Or to be run with --pural-kind=true.", rs.Singularize(KindName)) - } - ResourceName = rs.Pluralize(strings.ToLower(KindName)) - } - - groupMatch := regexp.MustCompile("^[a-z]+$") - if !groupMatch.MatchString(GroupName) { - log.Fatalf("--group must match regex ^[a-z]+$ but was (%s)", GroupName) - } - versionMatch := regexp.MustCompile("^v\\d+(alpha\\d+|beta\\d+)*$") - if !versionMatch.MatchString(VersionName) { - log.Fatalf( - "--version has bad format. must match ^v\\d+(alpha\\d+|beta\\d+)*$. "+ - "e.g. v1alpha1,v1beta1,v1 but was (%s)", VersionName) - } - - kindMatch := regexp.MustCompile("^[A-Z]+[A-Za-z0-9]*$") - if !kindMatch.MatchString(KindName) { - log.Fatalf("--kind must match regex ^[A-Z]+[A-Za-z0-9]*$ but was (%s)", KindName) - } -} - -func RegisterResourceFlags(cmd *cobra.Command) { - cmd.Flags().StringVar(&GroupName, "group", "", "name of the API group. **Must be single lowercase word (match ^[a-z]+$)**.") - cmd.Flags().StringVar(&VersionName, "version", "", "name of the API version. **must match regex v\\d+(alpha\\d+|beta\\d+)** e.g. v1, v1beta1, v1alpha1") - cmd.Flags().StringVar(&KindName, "kind", "", "name of the API kind. **Must be CamelCased (match ^[A-Z]+[A-Za-z0-9]*$)**") - cmd.Flags().StringVar(&ResourceName, "resource", "", "optional name of the API resource, defaults to the plural name of the lowercase kind") -} - -func RegisterCopyrightFlag(cmd *cobra.Command) { - cmd.Flags().StringVar(&Copyright, "copyright", filepath.Join("hack", "boilerplate.go.txt"), "Location of copyright boilerplate file.") -} diff --git a/cmd/kubebuilder/docs/docs.go b/cmd/kubebuilder/docs/docs.go deleted file mode 100644 index 87937f5ca6e..00000000000 --- a/cmd/kubebuilder/docs/docs.go +++ /dev/null @@ -1,215 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package docs - -import ( - "fmt" - "log" - "os" - "os/exec" - "os/user" - "path/filepath" - "strings" - - generatecmd "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/generate" - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" - "github.com/spf13/cobra" -) - -var docsCmd = &cobra.Command{ - Use: "docs", - Short: "Generate API reference docs.", - Long: `Generate API reference docs. - -Documentation will be written to docs/reference/build/index.html - -For creating documentation examples see "kubebuilder create example" -`, - Example: `# Build docs/build/index.html -kubebuilder docs - -# Add examples in the right-most column then rebuild the docs -kubebuilder create example --group group --version version --kind kind -nano -w docs/reference/examples/kind/kind.yaml -kubebuilder docs - - -# Add manual documentation to the generated reference docs by updating the header .md files -# Edit docs/reference/static_includes/*.md -# e.g. docs/reference/static_include/_overview.md - - # API OVERVIEW - Add your markdown here -`, - Run: RunDocs, -} - -var generateConfig bool -var cleanup, verbose bool -var outputDir string -var copyright string -var brodocs bool - -func AddDocs(cmd *cobra.Command) { - docsCmd.Flags().BoolVar(&cleanup, "cleanup", true, "If true, cleanup intermediary files") - docsCmd.Flags().BoolVar(&verbose, "verbose", true, "If true, use verbose output") - docsCmd.Flags().BoolVar(&generateConfig, "generate-config", true, "If true, generate the docs/reference/config.yaml.") - docsCmd.Flags().StringVar(&outputDir, "output-dir", filepath.Join("docs", "reference"), "Build docs into this directory") - docsCmd.Flags().StringVar(©right, "copyright", filepath.Join("hack", "boilerplate.go.txt"), "Location of copyright boilerplate file.") - docsCmd.Flags().BoolVar(&brodocs, "brodocs", true, "Run brodocs to generate html.") - docsCmd.Flags().StringVar(&generatecmd.Docscopyright, "docs-copyright", "Copyright 2018 The Kubernetes Authors.", "html for the copyright text on the docs") - docsCmd.Flags().StringVar(&generatecmd.Docstitle, "title", "API Reference", "title of the docs page") - cmd.AddCommand(docsCmd) - docsCmd.AddCommand(docsCleanCmd) -} - -func GetDocs() *cobra.Command { - return docsCmd -} - -var docsCleanCmd = &cobra.Command{ - Use: "clean", - Short: "Removes generated docs", - Long: `Removes generated docs`, - Example: ``, - Run: RunCleanDocs, -} - -func RunCleanDocs(cmd *cobra.Command, args []string) { - os.RemoveAll(filepath.Join(outputDir, "build")) - os.RemoveAll(filepath.Join(outputDir, "includes")) - os.Remove(filepath.Join(outputDir, "manifest.json")) -} - -var openapipkg = filepath.Join("pkg", "generated", "openapi") - -func RunDocs(cmd *cobra.Command, args []string) { - // Delete old build artifacts - os.RemoveAll(filepath.Join(outputDir, "includes")) - os.RemoveAll(filepath.Join(outputDir, "build")) - os.Remove(filepath.Join(outputDir, "manifest.json")) - - os.MkdirAll(filepath.Join(outputDir, "openapi-spec"), 0700) - os.MkdirAll(filepath.Join(outputDir, "static_includes"), 0700) - os.MkdirAll(filepath.Join(outputDir, "examples"), 0700) - - wd, err := os.Getwd() - if err != nil { - log.Fatalf("error: %v\n", err) - } - - if generateConfig { - // Regenerate the config.yaml with the table of contents - os.Remove(filepath.Join(outputDir, "config.yaml")) - CodeGenerator{}.Execute(wd) - } - - // Make sure to generate the openapi - generatecmd.Codegenerators = []string{"openapi"} - generatecmd.RunGenerate(cmd, args) - - // Create the go program to create the swagger.json by serializing the openapi go struct - cr := util.GetCopyright(copyright) - doSwaggerGen(wd, swaggerGenTemplateArgs{ - cr, - util.Repo, - }) - defer func() { - if cleanup { - os.RemoveAll(filepath.Join(wd, filepath.Join("pkg", "generated"))) - os.RemoveAll(filepath.Join(wd, outputDir, "includes")) - os.RemoveAll(filepath.Join(wd, outputDir, "manifest.json")) - os.RemoveAll(filepath.Join(wd, outputDir, "build", "documents")) - os.RemoveAll(filepath.Join(wd, outputDir, "build", "documents")) - os.RemoveAll(filepath.Join(wd, outputDir, "build", "runbrodocs.sh")) - os.RemoveAll(filepath.Join(wd, outputDir, "build", "node_modules", "marked", "Makefile")) - } - }() - - // Run the go program to write the swagger.json output to a file - c := exec.Command("go", "run", filepath.Join(openapipkg, "cmd", "main.go")) - if verbose { - log.Println(strings.Join(c.Args, " ")) - c.Stderr = os.Stderr - c.Stdout = os.Stdout - } - err = c.Run() - if err != nil { - log.Fatalf("error: %v\n", err) - } - - // Call the apidocs code generator to create the markdown files that will be converted into - // html - generatecmd.Codegenerators = []string{"apidocs"} - generatecmd.RunGenerate(cmd, args) - - if brodocs { - user, err := user.Current() - if err != nil { - log.Fatalf("error: %v\n", err) - } - - // Run the docker command to build the docs - c = exec.Command("docker", "run", - "-u", fmt.Sprintf("%s:%s", user.Uid, user.Gid), - "-v", "/etc/group:/etc/group:ro", - "-v", "/etc/passwd:/etc/passwd:ro", - "-v", fmt.Sprintf("%s:%s", filepath.Join(wd, outputDir, "includes"), "/source"), - "-v", fmt.Sprintf("%s:%s", filepath.Join(wd, outputDir, "build"), "/build"), - "-v", fmt.Sprintf("%s:%s", filepath.Join(wd, outputDir, "build"), "/build"), - "-v", fmt.Sprintf("%s:%s", filepath.Join(wd, outputDir), "/manifest"), - "gcr.io/kubebuilder/brodocs:v0.1.11", - ) - if verbose { - log.Println(strings.Join(c.Args, " ")) - c.Stderr = os.Stderr - c.Stdout = os.Stdout - } - err = c.Run() - if err != nil { - log.Fatalf("error: %v\n", err) - } - fmt.Printf("Reference docs written to %s\n", filepath.Join(outputDir, "build", "index.html")) - } -} - -// Scaffolding file for writing the openapi generated structs to a swagger.json file -type swaggerGenTemplateArgs struct { - BoilerPlate string - Repo string -} - -// Create a go file that will take the generated openapi.go file and serialize the go structs into a swagger.json. -func doSwaggerGen(dir string, args swaggerGenTemplateArgs) bool { - path := filepath.Join(dir, openapipkg, "cmd", "main.go") - return util.WriteIfNotFound(path, "swagger-template", swaggerGenTemplate, args) -} - -var swaggerGenTemplate = ` -{{.BoilerPlate}} - -package main - -import ( - "github.com/kubernetes-sigs/kubebuilder/pkg/docs" - "{{ .Repo }}/pkg/generated/openapi" -) - -func main() { - docs.WriteOpenAPI(openapi.GetOpenAPIDefinitions) -} -` diff --git a/cmd/kubebuilder/docs/gen.go b/cmd/kubebuilder/docs/gen.go deleted file mode 100644 index cfb27f8872d..00000000000 --- a/cmd/kubebuilder/docs/gen.go +++ /dev/null @@ -1,133 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package docs - -import ( - "fmt" - "os" - "path/filepath" - "sort" - "strings" - - "github.com/kubernetes-sigs/kubebuilder/cmd/internal/codegen/parse" - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" - "k8s.io/gengo/args" -) - -// CodeGenerator generates code for Kubernetes resources and controllers -type CodeGenerator struct{} - -// Execute parses packages and executes the code generators against the resource and controller packages -func (g CodeGenerator) Execute(dir string) error { - arguments := args.Default() - b, err := arguments.NewBuilder() - if err != nil { - return fmt.Errorf("Failed making a parser: %v", err) - } - for _, d := range []string{"./pkg/apis", "./pkg/inject"} { - if err := b.AddDirRecursive(d); err != nil { - return fmt.Errorf("Failed making a parser: %v", err) - } - } - c, err := parse.NewContext(b) - if err != nil { - return fmt.Errorf("Failed making a context: %v", err) - } - - arguments.CustomArgs = &parse.ParseOptions{SkipMapValidation: true} - - p := parse.NewAPIs(c, arguments) - path := filepath.Join(dir, outputDir, "config.yaml") - - args := ConfigArgs{} - groups := []string{} - for group, _ := range p.ByGroupKindVersion { - groups = append(groups, group) - } - sort.Strings(groups) - for _, group := range groups { - kindversion := p.ByGroupKindVersion[group] - args.Groups = append(args.Groups, strings.Title(group)) - c := Category{ - Name: strings.Title(group), - Include: strings.ToLower(group), - } - m := map[string]Resource{} - s := []string{} - for kind, version := range kindversion { - r := Resource{ - Group: group, - Kind: kind, - } - vs := []string{} - for version := range version { - vs = append(vs, version) - } - sort.Strings(vs) - r.Version = vs[0] - if version[vs[0]] != nil { - annotations := version[vs[0]].DocAnnotation - r.Warning = annotations["warning"] - r.Note = annotations["note"] - } - m[r.Kind] = r - s = append(s, r.Kind) - } - // Sort the resources by name - sort.Strings(s) - for _, k := range s { - c.Resources = append(c.Resources, m[k]) - } - - args.Categories = append(args.Categories, c) - } - - os.Remove(path) - util.Write(path, "docs-config-template", docsConfigTemplate, args) - return nil -} - -type ConfigArgs struct { - Groups []string - Categories []Category -} - -type Category struct { - Name string - Include string - Resources []Resource -} - -type Resource struct { - Kind, Version, Group, Warning, Note string -} - -var docsConfigTemplate = `example_location: "examples" -api_groups: {{ range $group := .Groups }} - - "{{ $group }}" -{{ end -}} -resource_categories: {{ range $category := .Categories }} -- name: "{{ $category.Name }}" - include: "{{ $category.Include}}" - resources: {{ range $resource := $category.Resources }} - - name: "{{ $resource.Kind }}" - version: "{{ $resource.Version }}" - group: "{{ $resource.Group }}"{{ if $resource.Warning }} - description_warning: "{{ $resource.Warning }}"{{ end -}}{{ if $resource.Note }} - description_note: "{{ $resource.Note }}"{{ end -}} - {{ end }} -{{ end }}` diff --git a/cmd/kubebuilder/generate/generate.go b/cmd/kubebuilder/generate/generate.go deleted file mode 100644 index b2f71988fac..00000000000 --- a/cmd/kubebuilder/generate/generate.go +++ /dev/null @@ -1,344 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package generate - -import ( - "io/ioutil" - "os" - "os/exec" - "path" - "path/filepath" - "regexp" - "strings" - - "github.com/golang/glog" - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" - "github.com/spf13/cobra" - "k8s.io/apimachinery/pkg/util/sets" -) - -var ( - versionedAPIs []string - unversionedAPIs []string - Codegenerators []string - copyright string - generators = sets.String{} - vendorDir string - Docscopyright string - Docstitle string - skipRBACValidation bool -) - -var generateCmd = &cobra.Command{ - Use: "generate", - Aliases: []string{"generated"}, - Short: "Run code generators.", - Long: `Run code generators`, - Example: `# Run code generators. -kubebuilder generate`, - Run: RunGenerate, -} - -var extraAPI = strings.Join([]string{ - "k8s.io/apimachinery/pkg/apis/meta/v1", - "k8s.io/apimachinery/pkg/conversion", - "k8s.io/apimachinery/pkg/runtime"}, ",") - -func AddGenerate(cmd *cobra.Command) { - cmd.AddCommand(generateCmd) - generateCmd.Flags().StringVar(©right, "copyright", filepath.Join("hack", "boilerplate.go.txt"), "Location of copyright boilerplate file.") - generateCmd.Flags().StringVar(&vendorDir, "vendor-dir", "", "Location of directory containing vendor files.") - generateCmd.Flags().BoolVar(&skipRBACValidation, "skip-rbac-validation", false, "if set to true, skip validation for RBAC annotations for the controller.") - generateCmd.Flags().StringArrayVar(&versionedAPIs, "api-versions", []string{}, "API version to generate code for. Can be specified multiple times. e.g. --api-versions foo/v1beta1 --api-versions bar/v1 defaults to all versions found under directories pkg/apis//") - generateCmd.Flags().StringArrayVar(&Codegenerators, "generator", []string{}, "list of generators to run. e.g. --generator kubebuilder --generator conversion Valid values: [kubebuilder,client,openapi]") - generateCmd.Flags().StringVar(&Docscopyright, "docs-copyright", "Copyright 2018 The Kubernetes Authors.", "html for the copyright text on the docs") - generateCmd.Flags().StringVar(&Docstitle, "docs-title", "API Reference", "title of the docs page") - generateCmd.AddCommand(generateCleanCmd) -} - -func GetGenerate() *cobra.Command { - return generateCmd -} - -var generateCleanCmd = &cobra.Command{ - Use: "clean", - Short: "Removes generated source code", - Long: `Removes generated source code`, - Run: RunCleanGenerate, -} - -func RunCleanGenerate(cmd *cobra.Command, args []string) { - os.RemoveAll(filepath.Join("pkg", "client", "clientset_generated")) - os.RemoveAll(filepath.Join("pkg", "client", "informers")) - os.RemoveAll(filepath.Join("pkg", "client", "listers")) - - filepath.Walk("pkg", func(path string, info os.FileInfo, err error) error { - if !info.IsDir() && strings.HasPrefix(info.Name(), "zz_generated.") { - return os.Remove(path) - } - return nil - }) -} - -func doGen(g string) bool { - g = strings.Replace(g, "-gen", "", -1) - return generators.Has(g) || generators.Len() == 0 -} - -func RunGenerate(cmd *cobra.Command, args []string) { - initApis() - - for _, g := range Codegenerators { - generators.Insert(strings.Replace(g, "-gen", "", -1)) - } - - util.GetCopyright(copyright) - - root, err := os.Executable() - if err != nil { - glog.Fatalf("error: %v", err) - } - root = filepath.Dir(root) - - all := []string{} - versioned := []string{} - for _, v := range versionedAPIs { - v = filepath.Join(util.Repo, "pkg", "apis", v) - versioned = append(versioned, "--input-dirs", v) - all = append(all, "--input-dirs", v) - } - - unversioned := []string{} - for _, u := range unversionedAPIs { - u = filepath.Join(util.Repo, "pkg", "apis", u) - unversioned = append(unversioned, "--input-dirs", u) - all = append(all, "--input-dirs", u) - } - - if doGen("kubebuilder-gen") { - genArgs := []string{ - "--go-header-file", copyright, - "--input-dirs", filepath.Join(util.Repo, "pkg", "apis", "..."), - "--input-dirs", filepath.Join(util.Repo, "pkg", "controller", "..."), - "--input-dirs", filepath.Join(util.Repo, "pkg", "inject", "..."), - } - if skipRBACValidation { - genArgs = append(genArgs, "--skip-rbac-validation") - } - c := exec.Command(filepath.Join(root, "kubebuilder-gen"), genArgs...) - glog.V(4).Infof("%s\n", strings.Join(c.Args, " ")) - out, err := c.CombinedOutput() - if err != nil { - glog.Fatalf("failed to run kubebuilder-gen %s %v", out, err) - } - } - - if generators.Has("conversion-gen") { - c := exec.Command(filepath.Join(root, "conversion-gen"), - append(all, - "-o", util.GoSrc, - "--go-header-file", copyright, - "-O", "zz_generated.conversion", - "--extra-peer-dirs", extraAPI)..., - ) - glog.V(4).Infof("%s\n", strings.Join(c.Args, " ")) - out, err := c.CombinedOutput() - if err != nil { - glog.Fatalf("failed to run conversion-gen %s %v", out, err) - } - } - - if doGen("deepcopy-gen") { - c := exec.Command(filepath.Join(root, "deepcopy-gen"), - append(versioned, - "-o", util.GoSrc, - "--go-header-file", copyright, - "-O", "zz_generated.deepcopy")..., - ) - glog.V(4).Infof("%s\n", strings.Join(c.Args, " ")) - out, err := c.CombinedOutput() - if err != nil { - glog.Fatalf("failed to run deepcopy-gen %s %v", out, err) - } - } - - if generators.Has("openapi") { - apis := []string{ - "k8s.io/apimachinery/pkg/apis/meta/v1", - "k8s.io/apimachinery/pkg/api/resource", - "k8s.io/apimachinery/pkg/version", - "k8s.io/apimachinery/pkg/runtime", - "k8s.io/apimachinery/pkg/util/intstr", - } - - // Add any vendored apis from core - apis = append(apis, getVendorApis(filepath.Join("k8s.io", "api"))...) - apis = append(apis, getVendorApis(filepath.Join("k8s.io", "client-go", "pkg", "apis"))...) - - // Special case 'k8s.io/client-go/pkg/api/v1' because it does not have a group - if _, err := os.Stat(filepath.Join("vendor", "k8s.io", "client-go", "pkg", "api", "v1", "doc.go")); err == nil { - apis = append(apis, filepath.Join("k8s.io", "client-go", "pkg", "api", "v1")) - } - - if _, err := os.Stat(filepath.Join("vendor", "k8s.io", "api", "core", "v1", "doc.go")); err == nil { - apis = append(apis, filepath.Join("k8s.io", "api", "core", "v1")) - } - - c := exec.Command(filepath.Join(root, "openapi-gen"), - append(all, - "-o", util.GoSrc, - "--go-header-file", copyright, - "-i", strings.Join(apis, ","), - "--output-package", filepath.Join(util.Repo, "pkg", "generated", "openapi"))..., - ) - glog.V(4).Infof("%s\n", strings.Join(c.Args, " ")) - out, err := c.CombinedOutput() - if err != nil { - glog.Fatalf("failed to run openapi-gen %s %v", out, err) - } - } - - // Generate reference documentation - if generators.Has("apidocs") { - c := exec.Command(filepath.Join(root, "gen-apidocs"), - "--copyright", Docscopyright, - "--title", Docstitle, - "--config-dir", "docs/reference/", - ) - glog.V(4).Infof("%s\n", strings.Join(c.Args, " ")) - out, err := c.CombinedOutput() - if err != nil { - glog.Fatalf("failed to run gen-apidocs %s %v", out, err) - } - } - - if generators.Has("defaulter-gen") { - c := exec.Command(filepath.Join(root, "defaulter-gen"), - append(all, - "-o", util.GoSrc, - "--go-header-file", copyright, - "-O", "zz_generated.defaults", - "--extra-peer-dirs=", extraAPI)..., - ) - glog.V(4).Infof("%s\n", strings.Join(c.Args, " ")) - out, err := c.CombinedOutput() - if err != nil { - glog.Fatalf("failed to run defaulter-gen %s %v", out, err) - } - } - - if doGen("client-gen") { - // Builder the versioned apis client - clientPkg := filepath.Join(util.Repo, "pkg", "client") - clientset := filepath.Join(clientPkg, "clientset") - c := exec.Command(filepath.Join(root, "client-gen"), - "-o", util.GoSrc, - "--go-header-file", copyright, - "--input-base", filepath.Join(util.Repo, "pkg", "apis"), - "--input", strings.Join(versionedAPIs, ","), - "--clientset-path", clientset, - "--clientset-name", "versioned", - ) - glog.V(4).Infof("%s\n", strings.Join(c.Args, " ")) - out, err := c.CombinedOutput() - if err != nil { - glog.Fatalf("failed to run client-gen %s %v", out, err) - } - - listerPkg := filepath.Join(clientPkg, "listers") - c = exec.Command(filepath.Join(root, "lister-gen"), - append(versioned, - "-o", util.GoSrc, - "--go-header-file", copyright, - "--output-package", listerPkg)..., - ) - glog.V(4).Infof("%s\n", strings.Join(c.Args, " ")) - out, err = c.CombinedOutput() - if err != nil { - glog.Fatalf("failed to run lister-gen %s %v", out, err) - } - - informerPkg := filepath.Join(clientPkg, "informers") - c = exec.Command(filepath.Join(root, "informer-gen"), - append(versioned, - "-o", util.GoSrc, - "--go-header-file", copyright, - "--output-package", informerPkg, - "--listers-package", listerPkg, - "--versioned-clientset-package", filepath.Join(clientset, "versioned"))..., - ) - glog.V(4).Infof("%s\n", strings.Join(c.Args, " ")) - out, err = c.CombinedOutput() - if err != nil { - glog.Fatalf("failed to run informer-gen %s %v", out, err) - } - } -} - -func initApis() { - if len(versionedAPIs) == 0 { - groups, err := ioutil.ReadDir(filepath.Join("pkg", "apis")) - if err != nil { - glog.Fatalf("could not read pkg/apis directory to find api Versions") - } - for _, g := range groups { - if g.IsDir() { - versionFiles, err := ioutil.ReadDir(filepath.Join("pkg", "apis", g.Name())) - if err != nil { - glog.Fatalf("could not read pkg/apis/%s directory to find api Versions", g.Name()) - } - versionMatch := regexp.MustCompile("^v\\d+(alpha\\d+|beta\\d+)*$") - for _, v := range versionFiles { - if v.IsDir() && versionMatch.MatchString(v.Name()) { - versionedAPIs = append(versionedAPIs, filepath.Join(g.Name(), v.Name())) - } - } - } - } - } - u := map[string]bool{} - for _, a := range versionedAPIs { - u[path.Dir(a)] = true - } - for a, _ := range u { - unversionedAPIs = append(unversionedAPIs, a) - } -} - -func getVendorApis(pkg string) []string { - dir := filepath.Join("vendor", pkg) - if len(vendorDir) >= 0 { - dir = filepath.Join(vendorDir, dir) - } - apis := []string{} - if groups, err := ioutil.ReadDir(dir); err == nil { - for _, g := range groups { - p := filepath.Join(dir, g.Name()) - if g.IsDir() { - if versions, err := ioutil.ReadDir(p); err == nil { - for _, v := range versions { - versionMatch := regexp.MustCompile("^v\\d+(alpha\\d+|beta\\d+)*$") - if v.IsDir() && versionMatch.MatchString(v.Name()) { - apis = append(apis, filepath.Join(pkg, g.Name(), v.Name())) - } - } - } - } - } - } - return apis -} diff --git a/cmd/kubebuilder/initproject/apis.go b/cmd/kubebuilder/initproject/apis.go deleted file mode 100644 index bd2c7afd6a4..00000000000 --- a/cmd/kubebuilder/initproject/apis.go +++ /dev/null @@ -1,51 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package initproject - -import ( - "fmt" - "path/filepath" -) - -// createAPIs creates a new package under pkg/apis -func createAPIs(boilerplate, domain string) { - fmt.Printf("\t%s/\n", filepath.Join("pkg", "apis")) - execute( - filepath.Join("pkg", "apis", "doc.go"), - "apis-template", - apisDocTemplate, - apisDocTemplateArguments{ - boilerplate, - domain, - }, - ) -} - -type apisDocTemplateArguments struct { - BoilerPlate string - Domain string -} - -var apisDocTemplate = ` -{{.BoilerPlate}} - -// -// +domain={{.Domain}} - -package apis - -` diff --git a/cmd/kubebuilder/initproject/apiserver.go b/cmd/kubebuilder/initproject/apiserver.go deleted file mode 100644 index be0b4f8089a..00000000000 --- a/cmd/kubebuilder/initproject/apiserver.go +++ /dev/null @@ -1,72 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package initproject - -import ( - "log" - "os" - "path/filepath" - - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" -) - -func runCreateApiserver(boilerplate string) { - dir, err := os.Getwd() - if err != nil { - log.Fatal(err) - } - path := filepath.Join(dir, "cmd", "apiserver", "main.go") - util.WriteIfNotFound(path, "apiserver-template", apiserverTemplate, - apiserverTemplateArguments{ - util.GetDomain(), - util.GetCopyright(boilerplate), - util.Repo, - }) -} - -type apiserverTemplateArguments struct { - Domain string - BoilerPlate string - Repo string -} - -var apiserverTemplate = ` -{{.BoilerPlate}} - -// Note: Ignore this (but don't delete it) if you are using CRDs. If using -// CRDs this file is necessary to generate docs. - -package main - -import ( - // Make sure dep tools picks up these dependencies - _ "k8s.io/apimachinery/pkg/apis/meta/v1" - _ "github.com/go-openapi/loads" - - "github.com/kubernetes-sigs/kubebuilder/pkg/cmd/server" - _ "k8s.io/client-go/plugin/pkg/client/auth" // Enable cloud provider auth - - "{{.Repo}}/pkg/apis" - "{{.Repo}}/pkg/openapi" -) - -// Extension (aggregated) apiserver main. -func main() { - version := "v0" - server.StartApiServer("/registry/{{ .Domain }}", apis.APIMeta.GetAllApiBuilders(), openapi.GetOpenAPIDefinitions, "Api", version) -} -` diff --git a/cmd/kubebuilder/initproject/bazel.go b/cmd/kubebuilder/initproject/bazel.go deleted file mode 100644 index 305c7945f38..00000000000 --- a/cmd/kubebuilder/initproject/bazel.go +++ /dev/null @@ -1,93 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package initproject - -import ( - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" -) - -// createBazelWorkspace creates new WORKSPACE and BUILD.bazel files at the root -func createBazelWorkspace() { - execute("WORKSPACE", "bazel-workspace-template", workspaceTemplate, nil) - execute( - "BUILD.bazel", - "bazel-build-template", - buildTemplate, - buildTemplateArguments{util.Repo}, - ) -} - -type buildTemplateArguments struct { - Repo string -} - -var workspaceTemplate = ` -http_archive( - name = "io_bazel_rules_go", - url = "https://github.com/bazelbuild/rules_go/releases/download/0.9.0/rules_go-0.9.0.tar.gz", - sha256 = "4d8d6244320dd751590f9100cf39fd7a4b75cd901e1f3ffdfd6f048328883695", -) -load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains") -go_rules_dependencies() -go_register_toolchains() -` - -var buildTemplate = ` -# gazelle:proto disable -# gazelle:exclude vendor/github.com/json-iterator/go/skip_tests -# gazelle:exclude vendor/cloud.google.com/go/trace/testdata -# gazelle:exclude vendor/cloud.google.com/go/internal/readme/testdata -# gazelle:exclude vendor/k8s.io/gengo/testdata -# gazelle:exclude vendor/golang.org/x/crypto/ssh/testdata -# gazelle:exclude vendor/golang.org/x/tools/cmd/fiximports/testdata -# gazelle:exclude vendor/golang.org/x/tools/cmd/guru/testdata -# gazelle:exclude vendor/golang.org/x/tools/cmd/goyacc/testdata -# gazelle:exclude vendor/golang.org/x/tools/cmd/stringer/testdata -# gazelle:exclude vendor/golang.org/x/tools/cmd/bundle/testdata -# gazelle:exclude vendor/golang.org/x/tools/cmd/callgraph/testdata -# gazelle:exclude vendor/golang.org/x/tools/cmd/cover/testdata -# gazelle:exclude vendor/golang.org/x/tools/go/internal/gccgoimporter/testdata -# gazelle:exclude vendor/golang.org/x/tools/go/ssa/testdata -# gazelle:exclude vendor/golang.org/x/tools/go/ssa/ssautil/testdata -# gazelle:exclude vendor/golang.org/x/tools/go/ssa/interp/testdata -# gazelle:exclude vendor/golang.org/x/tools/go/loader/testdata -# gazelle:exclude vendor/golang.org/x/tools/go/gcimporter15/testdata -# gazelle:exclude vendor/golang.org/x/tools/go/pointer/testdata -# gazelle:exclude vendor/golang.org/x/tools/go/callgraph/cha/testdata -# gazelle:exclude vendor/golang.org/x/tools/go/callgraph/rta/testdata -# gazelle:exclude vendor/golang.org/x/tools/refactor/eg/testdata -# gazelle:exclude vendor/github.com/davecgh/go-spew/spew/testdata -# gazelle:exclude vendor/github.com/golang/protobuf/proto/testdata -# gazelle:exclude vendor/github.com/golang/protobuf/protoc-gen-go/testdata -# gazelle:exclude vendor/github.com/imdario/mergo/testdata -# gazelle:exclude vendor/github.com/gogo/protobuf/proto/testdata -# gazelle:exclude vendor/github.com/gogo/protobuf/protoc-gen-gogo/testdata -# gazelle:exclude vendor/github.com/json-iterator/go/skip_tests - -load("@io_bazel_rules_go//go:def.bzl", "gazelle") - -gazelle( - name = "gazelle", - command = "fix", - prefix = "{{.Repo}}", - external = "vendored", - args = [ - "-build_file_name", - "BUILD.bazel", - ], -) -` diff --git a/cmd/kubebuilder/initproject/controller.go b/cmd/kubebuilder/initproject/controller.go deleted file mode 100644 index e03c7462fa1..00000000000 --- a/cmd/kubebuilder/initproject/controller.go +++ /dev/null @@ -1,92 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package initproject - -import ( - "fmt" - "path/filepath" - - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" -) - -func createControllerManager(boilerplate string) { - fmt.Printf("\t%s/\n", filepath.Join("cmd", "controller-manager")) - execute( - filepath.Join("cmd", "controller-manager", "main.go"), - "main-template", - controllerManagerTemplate, - controllerManagerTemplateArguments{boilerplate, util.Repo}, - ) -} - -type controllerManagerTemplateArguments struct { - BoilerPlate string - Repo string -} - -var controllerManagerTemplate = `{{.BoilerPlate}} - -package main - -import ( - "flag" - "log" - - // Import auth/gcp to connect to GKE clusters remotely - _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" - - configlib "github.com/kubernetes-sigs/kubebuilder/pkg/config" - "github.com/kubernetes-sigs/kubebuilder/pkg/inject/run" - "github.com/kubernetes-sigs/kubebuilder/pkg/install" - "github.com/kubernetes-sigs/kubebuilder/pkg/signals" - extensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" - - "{{.Repo}}/pkg/inject" - "{{.Repo}}/pkg/inject/args" -) - -var installCRDs = flag.Bool("install-crds", true, "install the CRDs used by the controller as part of startup") - -// Controller-manager main. -func main() { - flag.Parse() - - stopCh := signals.SetupSignalHandler() - - config := configlib.GetConfigOrDie() - - if *installCRDs { - if err := install.NewInstaller(config).Install(&InstallStrategy{crds: inject.Injector.CRDs}); err != nil { - log.Fatalf("Could not create CRDs: %v", err) - } - } - - // Start the controllers - if err := inject.RunAll(run.RunArguments{Stop: stopCh}, args.CreateInjectArgs(config)); err != nil { - log.Fatalf("%v", err) - } -} - -type InstallStrategy struct { - install.EmptyInstallStrategy - crds []*extensionsv1beta1.CustomResourceDefinition -} - -func (s *InstallStrategy) GetCRDs() []*extensionsv1beta1.CustomResourceDefinition { - return s.crds -} -` diff --git a/cmd/kubebuilder/initproject/dep_manifest.go b/cmd/kubebuilder/initproject/dep_manifest.go deleted file mode 100644 index 0a24bf5f2aa..00000000000 --- a/cmd/kubebuilder/initproject/dep_manifest.go +++ /dev/null @@ -1,222 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package initproject - -const depManifestHeader = ` -# Users add deps lines here - -[prune] - go-tests = true - #unused-packages = true - -# Note: Stanzas below are generated by Kubebuilder and may be rewritten when -# upgrading kubebuilder versions. -` - -// depManifestKBMarker acts as a separater between the user managed dependencies -// and KB generated dependencies. Content above this marker is user managed and -// needs to be preserved across 'vendor update' operations. Content below this -// marker is generated by KB and will be updated by KB during 'vendor update'. -const depManifestKBMarker = `# DO NOT MODIFY BELOW THIS LINE.` - -// template for dep's manifest file (Gopkg.toml). This is generated using -// scripts/generate_dep_manifest.sh scripts. -const depManifestOverride = ` -[[override]] -name="cloud.google.com/go" -version="v0.21.0" - -[[override]] -name="github.com/PuerkitoBio/purell" -version="v1.1.0" - -[[override]] -name="github.com/PuerkitoBio/urlesc" -revision="de5bf2ad457846296e2031421a34e2568e304e35" - -[[override]] -name="github.com/davecgh/go-spew" -version="v1.1.0" - -[[override]] -name="github.com/emicklei/go-restful" -version="v2.7.0" - -[[override]] -name="github.com/ghodss/yaml" -version="v1.0.0" - -[[override]] -name="github.com/go-openapi/jsonpointer" -revision="3a0015ad55fa9873f41605d3e8f28cd279c32ab2" - -[[override]] -name="github.com/go-openapi/jsonreference" -revision="3fb327e6747da3043567ee86abd02bb6376b6be2" - -[[override]] -name="github.com/go-openapi/spec" -revision="bcff419492eeeb01f76e77d2ebc714dc97b607f5" - -[[override]] -name="github.com/go-openapi/swag" -revision="811b1089cde9dad18d4d0c2d09fbdbf28dbd27a5" - -[[override]] -name="github.com/gogo/protobuf" -version="v1.0.0" - -[[override]] -name="github.com/golang/glog" -revision="23def4e6c14b4da8ac2ed8007337bc5eb5007998" - -[[override]] -name="github.com/golang/groupcache" -revision="66deaeb636dff1ac7d938ce666d090556056a4b0" - -[[override]] -name="github.com/golang/protobuf" -version="v1.1.0" - -[[override]] -name="github.com/google/gofuzz" -revision="24818f796faf91cd76ec7bddd72458fbced7a6c1" - -[[override]] -name="github.com/googleapis/gnostic" -version="v0.1.0" - -[[override]] -name="github.com/hashicorp/golang-lru" -revision="0fb14efe8c47ae851c0034ed7a448854d3d34cf3" - -[[override]] -name="github.com/howeyc/gopass" -revision="bf9dde6d0d2c004a008c27aaee91170c786f6db8" - -[[override]] -name="github.com/imdario/mergo" -version="v0.3.4" - -[[override]] -name="github.com/json-iterator/go" -version="1.1.3" - -[[override]] -name="github.com/mailru/easyjson" -revision="8b799c424f57fa123fc63a99d6383bc6e4c02578" - -[[override]] -name="github.com/modern-go/concurrent" -version="1.0.3" - -[[override]] -name="github.com/modern-go/reflect2" -version="1.0.0" - -[[override]] -name="github.com/onsi/ginkgo" -version="v1.4.0" - -[[override]] -name="github.com/onsi/gomega" -version="v1.3.0" - -[[override]] -name="github.com/spf13/pflag" -version="v1.0.1" - -[[override]] -name="golang.org/x/crypto" -revision="4ec37c66abab2c7e02ae775328b2ff001c3f025a" - -[[override]] -name="golang.org/x/net" -revision="640f4622ab692b87c2f3a94265e6f579fe38263d" - -[[override]] -name="golang.org/x/oauth2" -revision="cdc340f7c179dbbfa4afd43b7614e8fcadde4269" - -[[override]] -name="golang.org/x/sys" -revision="7db1c3b1a98089d0071c84f646ff5c96aad43682" - -[[override]] -name="golang.org/x/text" -version="v0.3.0" - -[[override]] -name="golang.org/x/time" -revision="fbb02b2291d28baffd63558aa44b4b56f178d650" - -[[override]] -name="google.golang.org/appengine" -version="v1.0.0" - -[[override]] -name="gopkg.in/inf.v0" -version="v0.9.1" - -[[override]] -name="gopkg.in/yaml.v2" -version="v2.2.1" - -[[override]] -name="k8s.io/api" -version="kubernetes-1.10.0" - -[[override]] -name="k8s.io/apiextensions-apiserver" -version="kubernetes-1.10.1" - -[[override]] -name="k8s.io/apimachinery" -version="kubernetes-1.10.0" - -[[override]] -name="k8s.io/client-go" -version="kubernetes-1.10.1" - -[[override]] -name="k8s.io/kube-aggregator" -version="kubernetes-1.10.1" - -[[override]] -name="k8s.io/kube-openapi" -revision="f08db293d3ef80052d6513ece19792642a289fea" - -[[override]] -name="sigs.k8s.io/testing_frameworks" -revision="f53464b8b84b4507805a0b033a8377b225163fea" - -# For dependency below: Refer to issue https://github.com/golang/dep/issues/1799 -[[override]] -name = "gopkg.in/fsnotify.v1" -source = "https://github.com/fsnotify/fsnotify.git" - -[[override]] -name = "github.com/kubernetes-sigs/kubebuilder" -{{ if eq .Version "unknown" -}} -branch="master" -{{ else if eq .Version "master" -}} -branch="master" -{{ else -}} -version="{{.Version}}" -{{ end }} - -` diff --git a/cmd/kubebuilder/initproject/dockerfile.go b/cmd/kubebuilder/initproject/dockerfile.go deleted file mode 100644 index de1ba0fa6ba..00000000000 --- a/cmd/kubebuilder/initproject/dockerfile.go +++ /dev/null @@ -1,185 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package initproject - -import ( - "path/filepath" - - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" -) - -func doDockerfile() bool { - args := templateArgs{ - Repo: util.Repo, - } - //install := util.WriteIfNotFound(filepath.Join("Dockerfile.install"), "install-docker-template", installDockerfileTemplate, args) - //docs := util.WriteIfNotFound(filepath.Join(dir, "Dockerfile.docs"), "docs-docker-template", docsDockerfileTemplate, args) - controller := util.WriteIfNotFound(filepath.Join("Dockerfile.controller"), "controller-docker-template", controllerDockerfileTemplate, args) - //apiserver := util.WriteIfNotFound(filepath.Join(dir, "Dockerfile.apiserver"), "apiserver-docker-template", apiserverDockerfileTemplate, args) - //pod := util.WriteIfNotFound(filepath.Join("hack", "install.yaml"), "install-template", installPodTemplate, args) - return controller -} - -var installDockerfileTemplate = `# Instructions to install API using the installer -# Create a serviceaccount with the cluster-admin role -# $ kubectl create serviceaccount installer -# $ kubectl create clusterrolebinding installer-cluster-admin-binding --clusterrole=cluster-admin --serviceaccount=default:installer -# RunInformersAndControllers the installer image in the cluster as the cluster-admin -# $ kubectl run --serviceaccount=installer --image= --restart=OnFailure -- ./installer --controller-image= --docs-image= --name= - -# To run the install outside of the cluster, you must give your account the cluster-admin role -# kubectl create clusterrolebinding -cluster-admin-binding --clusterrole=cluster-admin --user= - -# Build and test the controller-manager -FROM golang:1.9.3 as builder -WORKDIR /go/src/{{ .Repo }} -COPY pkg/ pkg/ -COPY cmd/ cmd/ -COPY vendor/ vendor/ -RUN go build -a -o installer ./cmd/installer/main.go - -# Copy the controller-manager into a thin image -FROM ubuntu:latest -RUN apt update && apt install openssl -y && apt clean && rm -rf /var/lib/apt/lists/* -WORKDIR /root/ -COPY --from=builder /go/src/{{ .Repo }}/installer . -CMD ["./installer"] -` - -var controllerDockerfileTemplate = `# Instructions to install API using the installer -# Build and test the controller-manager -FROM golang:1.9.3 as builder - -ENV TEST_ASSET_DIR /usr/local/bin -ENV TEST_ASSET_KUBECTL $TEST_ASSET_DIR/kubectl -ENV TEST_ASSET_KUBE_APISERVER $TEST_ASSET_DIR/kube-apiserver -ENV TEST_ASSET_ETCD $TEST_ASSET_DIR/etcd - -# Download test framework binaries -ENV TEST_ASSET_URL https://storage.googleapis.com/k8s-c10s-test-binaries -RUN curl ${TEST_ASSET_URL}/etcd-Linux-x86_64 --output $TEST_ASSET_ETCD -RUN curl ${TEST_ASSET_URL}/kube-apiserver-Linux-x86_64 --output $TEST_ASSET_KUBE_APISERVER -RUN curl https://storage.googleapis.com/kubernetes-release/release/v1.9.2/bin/linux/amd64/kubectl --output $TEST_ASSET_KUBECTL -RUN chmod +x $TEST_ASSET_ETCD -RUN chmod +x $TEST_ASSET_KUBE_APISERVER -RUN chmod +x $TEST_ASSET_KUBECTL - -# Copy in the go src -WORKDIR /go/src/{{ .Repo }} -COPY pkg/ pkg/ -COPY cmd/ cmd/ -COPY vendor/ vendor/ - -# Build and test the API code -RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o controller-manager ./cmd/controller-manager/main.go -RUN go test ./pkg/... ./cmd/... - -# Copy the controller-manager into a thin image -FROM ubuntu:latest -# RUN apk --no-cache add ca-certificates -WORKDIR /root/ -COPY --from=builder /go/src/{{ .Repo }}/controller-manager . -ENTRYPOINT ["./controller-manager"] -CMD ["--install-crds=false"] -` - -//var apiserverDockerfileTemplate = `# Instructions to install API using the installer -//# IGNORE THIS FILE IF YOU ARE USING CRDS. -//# THIS IS ONLY FOR APISERVER AGGREGATION. -//# Build the apiserver -//FROM golang:1.9.3 as builder -// -//# Copy in the go src -//WORKDIR /go/src/{{ .Repo }} -//COPY pkg/ pkg/ -//COPY cmd/ cmd/ -//COPY vendor/ vendor/ -// -//# Build and test the API code -//RUN go build -a -o apiserver ./cmd/apiserver/main.go -// -//# Copy the apiserver into a thin image -//FROM ubuntu:latest -//WORKDIR /root/ -//COPY --from=builder /go/src/{{ .Repo }}/apiserver . -//CMD ["./apiserver"] -//` -// -//var docsDockerfileTemplate = ` -//# Builds a container to host the reference documentation for the APIs -//# To access documentation in the cluster on http://localhost:8989 run -//# kubectl port-forward $(kubectl get pods --namespace=foo-system -l="app=docs" -o="jsonpath={.items[0].metadata.name}") 8989:80 --namespace=-system -//FROM golang:1.9.3 as builder -// -//WORKDIR /go/src/{{ .Repo }} -//RUN go get github.com/kubernetes-incubator/reference-docs/gen-apidocs -// -//COPY pkg/ pkg/ -//COPY cmd/ cmd/ -//COPY vendor/ vendor/ -//COPY docs/ docs/ -// -// -//RUN mkdir docs/openapi-spec || echo "openapi-spec dir exists" -//RUN mkdir docs/static_includes || echo "static_includes dir exists" -//RUN go run ./cmd/apiserver/main.go --etcd-servers=http://localhost:2379 --secure-port=9443 --print-openapi --delegated-auth=false > docs/openapi-spec/swagger.json -//RUN gen-apidocs --build-operations=false --use-tags=true --allow-errors=true --config-dir=docs -// -//# RunInformersAndControllers brodocs against docs set -//FROM pwittrock/brodocs:latest as brodocs -//COPY --from=builder /go/src/{{ .Repo }}/docs docs/ -//RUN mkdir /manifest -//RUN mkdir /build -//RUN cp docs/manifest.json /manifest/manifest.json -//RUN mv docs/includes /source -//RUN ./runbrodocs.sh -// -//# Publish docs in a container -//FROM nginx -//COPY --from=brodocs build/ /usr/share/nginx/html -//` - -var installPodTemplate = ` -# EDIT ME by replacing "/" with your image -# Steps to install -# kubectl create serviceaccount installer -# kubectl create clusterrolebinding installer-cluster-admin-binding --clusterrole=cluster-admin --serviceaccount=default:installer -# kubectl create -f install.yaml -apiVersion: batch/v1 -kind: Job -metadata: - name: - labels: - run: -spec: - template: - metadata: - labels: - run: - spec: - restartPolicy: OnFailure - serviceAccountName: installer - containers: - - args: - - ./installer - - --controller-image=gcr.io//-controller:v1 - - --docs-image=gcr.io//-docs:v1 - - --name= - image: gcr.io//-install:v1 - imagePullPolicy: Always - name: -` diff --git a/cmd/kubebuilder/initproject/dummyimports.go b/cmd/kubebuilder/initproject/dummyimports.go deleted file mode 100644 index f910d627e06..00000000000 --- a/cmd/kubebuilder/initproject/dummyimports.go +++ /dev/null @@ -1,52 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package initproject - -import ( - "path/filepath" - - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" -) - -func doImports(boilerplate string) bool { - args := installImportsArgs{ - BoilerPlate: boilerplate, - } - controller := util.WriteIfNotFound(filepath.Join("hack", "imports.go"), "imports-template", installImportsTemplate, args) - return controller -} - -type installImportsArgs struct { - BoilerPlate string -} - -var installImportsTemplate = `{{.BoilerPlate}} - -package hack - -/* -Package imports imports dependencies required for "dep ensure" to fetch all of the go package dependencies needed -by kubebuilder commands to work without rerunning "dep ensure". - -Example: make sure the testing libraries and apimachinery libraries are fetched by "dep ensure" so that -dep ensure doesn't need to be rerun after "kubebuilder create resource". - -This is necessary for subsequent commands - such as building docs, tests, etc - to work without rerunning "dep ensure" -afterward. -*/ -import _ "github.com/kubernetes-sigs/kubebuilder/pkg/imports" -` diff --git a/cmd/kubebuilder/initproject/empty_package.go b/cmd/kubebuilder/initproject/empty_package.go deleted file mode 100644 index bb271964217..00000000000 --- a/cmd/kubebuilder/initproject/empty_package.go +++ /dev/null @@ -1,54 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package initproject - -import ( - "path/filepath" -) - -// createPackage creates a new go package with a doc.go file -func createPackage(boilerplate, path string) { - pkg := filepath.Base(path) - execute( - filepath.Join(path, "doc.go"), - "pkg-template", packageDocTemplate, - packageDocTemplateArguments{ - boilerplate, - pkg, - }) -} - -type packageDocTemplateArguments struct { - BoilerPlate string - Package string -} - -var packageDocTemplate = ` -{{.BoilerPlate}} - - -package {{.Package}} - -` - -func createBoilerplate() { - execute( - filepath.Join("hack", "boilerplate.go.txt"), - "boilerplate-template", boilerplateTemplate, nil) -} - -var boilerplateTemplate = `` diff --git a/cmd/kubebuilder/initproject/init.go b/cmd/kubebuilder/initproject/init.go index 6d88ab1b83d..36118d30c85 100644 --- a/cmd/kubebuilder/initproject/init.go +++ b/cmd/kubebuilder/initproject/init.go @@ -209,6 +209,11 @@ func checkGoVersion() { } } +func depExists() bool { + _, err := exec.LookPath("dep") + return err == nil +} + func execute(path, templateName, templateValue string, data interface{}) { dir, err := os.Getwd() if err != nil { diff --git a/cmd/kubebuilder/initproject/inject.go b/cmd/kubebuilder/initproject/inject.go deleted file mode 100644 index c1d7bd71b16..00000000000 --- a/cmd/kubebuilder/initproject/inject.go +++ /dev/null @@ -1,117 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package initproject - -import ( - "fmt" - "path/filepath" - - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" -) - -func doInject(boilerplate string) bool { - args := templateArgs{ - Repo: util.Repo, - BoilerPlate: boilerplate, - } - path := filepath.Join("pkg", "inject", "inject.go") - fmt.Printf("\t%s\n", filepath.Join( - "pkg", "inject", "inject.go")) - return util.WriteIfNotFound(path, "inject-controller-template", injectControllerTemplate, args) -} - -var injectControllerTemplate = `{{.BoilerPlate}} - -package inject - -import ( - "github.com/kubernetes-sigs/kubebuilder/pkg/inject/run" - injectargs "github.com/kubernetes-sigs/kubebuilder/pkg/inject/args" - - "{{.Repo}}/pkg/inject/args" -) - -var ( - // Inject is used to add items to the Injector - Inject []func(args.InjectArgs) error - - // Injector runs items - Injector injectargs.Injector -) - -// RunAll starts all of the informers and Controllers -func RunAll(rargs run.RunArguments, iargs args.InjectArgs) error { - // Run functions to initialize injector - for _, i := range Inject { - if err := i(iargs); err != nil { - return err - } - } - Injector.Run(rargs) - <-rargs.Stop - return nil -} -` - -func doArgs(boilerplate string, controllerOnly bool) bool { - args := templateArgs{ - Repo: util.Repo, - BoilerPlate: boilerplate, - ControllerOnly: controllerOnly, - } - path := filepath.Join("pkg", "inject", "args", "args.go") - fmt.Printf("\t%s\n", filepath.Join( - "pkg", "inject", "args", "args.go")) - return util.WriteIfNotFound(path, "args-controller-template", argsControllerTemplate, args) -} - -var argsControllerTemplate = `{{.BoilerPlate}} - -package args - -import ( - {{ if not .ControllerOnly }}"time"{{ end }} - - "github.com/kubernetes-sigs/kubebuilder/pkg/inject/args" - "k8s.io/client-go/rest" - {{ if not .ControllerOnly }} - clientset "{{.Repo}}/pkg/client/clientset/versioned" - informer "{{.Repo}}/pkg/client/informers/externalversions" - {{ end }} -) - -// InjectArgs are the arguments need to initialize controllers -type InjectArgs struct { - args.InjectArgs - {{ if not .ControllerOnly }} - Clientset *clientset.Clientset - Informers informer.SharedInformerFactory - {{ end }} -} - - -// CreateInjectArgs returns new controller args -func CreateInjectArgs(config *rest.Config) InjectArgs { - {{ if not .ControllerOnly }}cs := clientset.NewForConfigOrDie(config){{ end }} - return InjectArgs{ - InjectArgs: args.CreateInjectArgs(config), - {{ if not .ControllerOnly }} - Clientset: cs, - Informers: informer.NewSharedInformerFactory(cs, 2 * time.Minute), {{ end }} - } -} -` diff --git a/cmd/kubebuilder/initproject/installer.go b/cmd/kubebuilder/initproject/installer.go deleted file mode 100644 index ca11c6424d7..00000000000 --- a/cmd/kubebuilder/initproject/installer.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package initproject - -import ( - "fmt" - "path/filepath" - - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" -) - -func createInstaller(boilerplate string) { - fmt.Printf("\t%s/\n", filepath.Join("cmd", "installer")) - execute( - filepath.Join("cmd", "installer", "main.go"), - "installer-template", - installerTemplate, - installerTemplateArguments{boilerplate, util.Repo}, - ) -} - -type installerTemplateArguments struct { - BoilerPlate string - Repo string -} - -var installerTemplate = ` -{{.BoilerPlate}} - -package main - -import ( - "flag" - "log" - - "github.com/kubernetes-sigs/kubebuilder/pkg/install" - configlib "github.com/kubernetes-sigs/kubebuilder/pkg/config" - - "{{ .Repo }}/pkg/inject" -) - -var kubeconfig = flag.String("kubeconfig", "", "path to kubeconfig") -var controllerImage = flag.String("controller-image", "", "name of container image containing the controller binary") -var docsImage = flag.String("docs-image", "", "name of container image the reference docs") -var name = flag.String("name", "", "name of the installation") -var uninstall = flag.Bool("uninstall", false, "uninstall the API") - -func main() { - flag.Parse() - config, err := configlib.GetConfig() - if err != nil { - log.Fatalf("Could not create Config for talking to the apiserver: %v", err) - } - - // Install the API components into the cluster - strategy := &install.CRDInstallStrategy{ - Name: *name, - APIMeta: inject.Injector{}, - ControllerManagerImage: *controllerImage, - DocsImage: *docsImage, - } - - if !*uninstall { - err = install.NewInstaller(config).Install(strategy) - if err != nil { - log.Fatalf("Failed to install API: %v", err) - } - } else { - err = install.NewUninstaller(config).Uninstall(strategy) - if err != nil { - log.Fatalf("Failed to uninstall API: %v", err) - } - } -} -` diff --git a/cmd/kubebuilder/initproject/vendor.go b/cmd/kubebuilder/initproject/vendor.go deleted file mode 100644 index ef8c96e021e..00000000000 --- a/cmd/kubebuilder/initproject/vendor.go +++ /dev/null @@ -1,198 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package initproject - -import ( - "bufio" - "bytes" - "fmt" - "html/template" - "io" - "io/ioutil" - "log" - "os" - "os/exec" - "strings" - - "github.com/spf13/cobra" - - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/version" -) - -const ( - depManifestFile = "Gopkg.toml" -) - -var vendorInstallCmd = &cobra.Command{ - Use: "dep", - Short: "Install Gopkg.toml and update vendor dependencies.", - Long: `Install Gopkg.toml and update vendor dependencies.`, - Example: `Update the vendor dependencies: -kubebuilder update vendor -`, - Run: RunVendorInstall, -} - -var builderCommit string -var Update bool - -func RunVendorInstall(cmd *cobra.Command, args []string) { - if len(args) > 0 { - cr := util.GetCopyright(args[0]) - doImports(cr) - } - if !depExists() { - log.Fatalf("Dep is not installed. Follow steps at: https://golang.github.io/dep/docs/installation.html") - } - if Update && depManifestExists() { - if err := updateDepManifest(); err != nil { - log.Fatalf("error upgrading the dep manifest (Gopkg.toml): %v", err) - } - } else { - createNewDepManifest() - } - if err := runDepEnsure(); err != nil { - fmt.Printf("Error running 'dep ensure': %v\n", err) - return - } -} - -func runDepEnsure() error { - fmt.Printf("Updating vendor dependencies. Running 'dep ensure'....\n") - cmd := exec.Command("dep", "ensure") - o, err := cmd.CombinedOutput() - if err != nil { - fmt.Printf("Failed to run 'dep ensure': %s\n", string(o)) - return err - } - fmt.Printf("Updated vendor dependencies successfully.\n") - return nil -} - -func depExists() bool { - _, err := exec.LookPath("dep") - return err == nil -} - -// depManifestExists checks if DepManifestFile exists or not. It will panic -// if it encounters unknown errors. -func depManifestExists() bool { - _, err := os.Stat(depManifestFile) - if err == nil { - // file exists - return true - } - if os.IsNotExist(err) { - return false - } - // some other error, panic - log.Fatalf("error looking up dep manifest file : %v", err) - return false -} - -func createNewDepManifest() { - depTmplArgs := map[string]string{ - "Version": version.GetVersion().KubeBuilderVersion, - } - depManifestTmpl := fmt.Sprintf("%s\n%s\n%s", depManifestHeader, depManifestKBMarker, depManifestOverride) - util.Write(depManifestFile, "dep-manifest-file", depManifestTmpl, depTmplArgs) -} - -// updateDepManifest updates the existing dep manifest with newer dependencies. -// dep manifest update workflow: -// Try to read user managed dep manifest section. If success, then append the -// user managed dep with KB managed section and update the dep Manifest. -func updateDepManifest() error { - // open the existing dep manifest. - f, err := os.Open(depManifestFile) - if err != nil { - return err - } - defer f.Close() - - // try to read content till the dep marker - userDeps, foundKBMarker, err := tryReadingUserDeps(f) - if err != nil { - return err - } - - if !foundKBMarker { - // depManifest file or abort the operation here. - // for now, aborting. - log.Fatalf(` -Failed to upgrade the dep manifest (Gopkg.toml) file. It seems that the dep manifest -is not being managed by Kubebuilder. You can run the command with --overwrite-dep-manifest -flag if you want to re-initialize the dep manifest file. -`) - } - - b := bytes.NewBufferString(userDeps) - err = addKubeBuilderDeps(b) - if err != nil { - return err - } - - tmpfile, err := ioutil.TempFile(".", "dep") - if err != nil { - return err - } - - defer os.Remove(tmpfile.Name()) // clean up - - _, err = tmpfile.Write(b.Bytes()) - if err != nil { - return err - } - err = tmpfile.Close() - if err != nil { - return err - } - - err = os.Rename(tmpfile.Name(), depManifestFile) - if err != nil { - return err - } - return nil -} - -func tryReadingUserDeps(r io.Reader) (userDeps string, foundMarker bool, err error) { - b := &bytes.Buffer{} - scanner := bufio.NewScanner(r) - - for scanner.Scan() { - line := scanner.Text() - b.WriteString(line) - b.WriteString("\n") - if strings.HasPrefix(line, depManifestKBMarker) { - foundMarker = true - userDeps = b.String() - return - } - } - - err = scanner.Err() - return -} - -func addKubeBuilderDeps(w io.Writer) error { - depTmplArgs := map[string]string{ - "Version": version.GetVersion().KubeBuilderVersion, - } - t := template.Must(template.New("dep-manifest-template").Parse(depManifestOverride)) - return t.Execute(w, depTmplArgs) -} diff --git a/cmd/kubebuilder/initproject/vendor_test.go b/cmd/kubebuilder/initproject/vendor_test.go deleted file mode 100644 index 12e1d6bcd41..00000000000 --- a/cmd/kubebuilder/initproject/vendor_test.go +++ /dev/null @@ -1,84 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package initproject - -import ( - "bytes" - "testing" -) - -func TestTryReadingUserDeps(t *testing.T) { - tests := []struct { - in string - expKBMarker bool - expUserDeps string - }{ - { - in: ` -ABC -ABC -jslsls -sjsslsls - `, - expKBMarker: false, - expUserDeps: "", - }, - { - in: ` -ABC -ABC -# DO NOT MODIFY BELOW THIS LINE. -jslsls -sjsslsls - `, - expKBMarker: true, - expUserDeps: ` -ABC -ABC -# DO NOT MODIFY BELOW THIS LINE. -`, - }, - { - in: ` -ABC -ABC -# DO NOT MODIFY BELOW THIS LINE. - `, - expKBMarker: true, - expUserDeps: ` -ABC -ABC -# DO NOT MODIFY BELOW THIS LINE. -`, - }, - } - - for _, test := range tests { - r := bytes.NewReader([]byte(test.in)) - userDeps, kbMarker, err := tryReadingUserDeps(r) - if err != nil { - t.Errorf("Reading UserDeps should succeed, but got an error: %v", err) - } - if test.expKBMarker != kbMarker { - t.Errorf("KB marker mismatch: exp: '%v' got: '%v'", test.expKBMarker, kbMarker) - } - if test.expUserDeps != userDeps { - t.Errorf("UserDeps don't match: exp: '%v' got: '%v'", test.expUserDeps, userDeps) - } - - } -} diff --git a/cmd/kubebuilder/run/local.go b/cmd/kubebuilder/run/local.go deleted file mode 100644 index d8b191bd04e..00000000000 --- a/cmd/kubebuilder/run/local.go +++ /dev/null @@ -1,111 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package run - -import ( - "fmt" - "log" - "os" - "os/exec" - "path/filepath" - "strings" - - "github.com/spf13/cobra" - - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/build" - "k8s.io/client-go/util/homedir" -) - -var localCmd = &cobra.Command{ - Use: "run", - Short: "Builds and runs the controller-manager locally against a Kubernetes cluster.", - Long: `Builds and runs the controller-manager locally against a Kubernetes cluster. - -Controller-manager will automatically install APIs in the cluster if they are missing. - -To run the controller-manager remotely as a Deployment, see the instructions in the 'Dockerfile'. - -To build and run the controller using Bazel, use: - bazel run gazelle - bazel run cmd/controller-manager:controller-manager -- --kubeconfig ~/.kube/config`, - Example: `# Install APIs and run controller-manager against a cluster -kubebuilder run local - -# RunInformersAndControllers controller-manager without rebuilding the binary -kubebuilder run local --build=false - -# RunInformersAndControllers controller-manager using a specific kubeconfig -kubebuilder run local --config=path/to/kubeconfig`, - Run: RunLocal, -} - -var buildBin bool -var config string -var controllermanager string -var generate bool -var printcontrollermanager bool - -func AddRun(cmd *cobra.Command) { - localCmd.Flags().StringVar(&controllermanager, "controller-manager", "", "path to controller-manager binary to run") - localCmd.Flags().StringVar(&config, "config", filepath.Join(homedir.HomeDir(), ".kube", "config"), "path to the kubeconfig to write for using kubectl") - - localCmd.Flags().BoolVar(&printcontrollermanager, "print-controller-manager", true, "if true, pipe the controller-manager stdout and stderr") - localCmd.Flags().BoolVar(&buildBin, "build", true, "if true, build the binaries before running") - localCmd.Flags().BoolVar(&generate, "generate", true, "if true, generate code before building") - - cmd.AddCommand(localCmd) -} - -func RunLocal(cmd *cobra.Command, args []string) { - if buildBin { - fmt.Printf("Building controller executable...\n.") - build.GenerateForBuild = generate - build.RunBuildExecutables(cmd, args) - } - - fmt.Printf( - "Next: Read the 'Dockerfile.install' for instructions to build an installer for your API and controller.`\n") - - // Start controller manager - fmt.Printf("Starting controller...\n.") - go RunControllerManager() - - select {} // wait forever -} - -func RunControllerManager() *exec.Cmd { - if len(controllermanager) == 0 { - controllermanager = "bin/controller-manager" - } - controllerManagerCmd := exec.Command(controllermanager, - fmt.Sprintf("--kubeconfig=%s", config), - ) - fmt.Printf("%s\n", strings.Join(controllerManagerCmd.Args, " ")) - if printcontrollermanager { - controllerManagerCmd.Stderr = os.Stderr - controllerManagerCmd.Stdout = os.Stdout - } - - err := controllerManagerCmd.Run() - if err != nil { - defer controllerManagerCmd.Process.Kill() - log.Fatalf("Failed to run controller-manager %v", err) - os.Exit(-1) - } - - return controllerManagerCmd -} diff --git a/cmd/kubebuilder/update/update.go b/cmd/kubebuilder/update/update.go deleted file mode 100644 index 5025d808656..00000000000 --- a/cmd/kubebuilder/update/update.go +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package update - -import ( - "github.com/spf13/cobra" -) - -var updateCmd = &cobra.Command{ - Use: "update", - Short: "Command group for updating the kubebuilder version.", - Long: `Command group for updating the kubebuilder version.`, - Example: ` -# Update the vendored dependencies under vendor/ -kubebuilder update vendor -`, - Run: RunUpdate, -} - -func AddUpdate(cmd *cobra.Command) { - cmd.AddCommand(updateCmd) - AddUpdateVendorCmd(updateCmd) -} - -func RunUpdate(cmd *cobra.Command, args []string) { - cmd.Help() -} diff --git a/cmd/kubebuilder/update/vendor.go b/cmd/kubebuilder/update/vendor.go deleted file mode 100644 index c3a3c15ec79..00000000000 --- a/cmd/kubebuilder/update/vendor.go +++ /dev/null @@ -1,49 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package update - -import ( - "github.com/spf13/cobra" - - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/initproject" -) - -var overwriteDepManifest bool - -var vendorCmd = &cobra.Command{ - Use: "vendor", - Short: "Update the vendor packages managed by kubebuilder.", - Long: `Update the vendor packages managed by kubebuilder.`, - Example: `# Replace the vendor packages managed by kubebuilder with versions for the current install. -kubebuilder update vendor -`, - Run: RunUpdateVendor, -} - -func AddUpdateVendorCmd(cmd *cobra.Command) { - cmd.AddCommand(vendorCmd) - vendorCmd.Flags().BoolVar(&overwriteDepManifest, "overwrite-dep-manifest", false, "if true, overwrites the dep manifest file (Gopkg.toml)") -} - -func RunUpdateVendor(cmd *cobra.Command, args []string) { - initproject.Update = true - if overwriteDepManifest { - // suppress the update behavior - initproject.Update = false - } - initproject.RunVendorInstall(cmd, args) -} diff --git a/cmd/kubebuilder/v0/commands.go b/cmd/kubebuilder/v0/commands.go deleted file mode 100644 index 99fc2ea8405..00000000000 --- a/cmd/kubebuilder/v0/commands.go +++ /dev/null @@ -1,86 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v0 - -import ( - "github.com/spf13/cobra" - - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/build" - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/create" - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/docs" - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/generate" - "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/update" -) - -func AddCmds(cmd *cobra.Command) { - build.AddBuild(cmd) - create.AddCreate(cmd) - docs.AddDocs(cmd) - generate.AddGenerate(cmd) - update.AddUpdate(cmd) - cmd.Long = `Development kit for building Kubernetes extensions and tools. - -Provides libraries and tools to create new projects, APIs and controllers. -Includes tools for packaging artifacts into an installer container. - -Typical project lifecycle: - -- initialize a project: - - kubebuilder init --domain example.com - -- create one or more a new resource APIs and add your code to them: - - kubebuilder create resource --group --version --kind - -- run the controller as a local process (e.g. not in a container), installing APIs into the cluster if they are missing: - - GOBIN=${PWD}/bin go install ${PWD#$GOPATH/src/}/cmd/controller-manager - bin/controller-manager --kubeconfig ~/.kube/config - - # In another terminal create a new instance of your resource and watch the controller-manager output - kubectl apply -f hack/sample/.yaml - - -- build a docker container to install the API and controller into a namespace with RBAC configured: - - Note: You may need to give yourself admin privs in order to install the RBAC rules - kubectl create clusterrolebinding --clusterrole=cluster-admin --user= - - docker build -f Dockerfile.controller . -t - docker push - kubebuilder create config --controller-image --name - kubectl apply -f hack/install.yaml - -More options: - -- run tests - kubebuilder generate - go test ./pkg/... - -- build reference documentation to docs/reference/build/index.html - kubebuilder create example --group --version --kind - kubebuilder docs -` - - cmd.Example = `# Initialize your project -kubebuilder init --domain example.com - -# Initialize your project adding a go-header file to all generated files -touch hack/boilerplate.go.txt -kubebuilder init --domain example.com` -}