sigs.k8s.io/kubebuilder/v3@v3.14.0/test/e2e/v4/generate_test.go (about)

     1  /*
     2  Copyright 2020 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8     http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package v4
    18  
    19  import (
    20  	"fmt"
    21  	"path/filepath"
    22  	"strings"
    23  
    24  	. "github.com/onsi/ginkgo/v2"
    25  	. "github.com/onsi/gomega"
    26  
    27  	pluginutil "sigs.k8s.io/kubebuilder/v3/pkg/plugin/util"
    28  
    29  	//nolint:golint
    30  	//nolint:revive
    31  	//nolint:golint
    32  	//nolint:revive
    33  	"sigs.k8s.io/kubebuilder/v3/test/e2e/utils"
    34  )
    35  
    36  // GenerateV4 implements a go/v4 plugin project defined by a TestContext.
    37  func GenerateV4(kbc *utils.TestContext) {
    38  	initingTheProject(kbc)
    39  	creatingAPI(kbc)
    40  
    41  	By("scaffolding mutating and validating webhooks")
    42  	err := kbc.CreateWebhook(
    43  		"--group", kbc.Group,
    44  		"--version", kbc.Version,
    45  		"--kind", kbc.Kind,
    46  		"--defaulting",
    47  		"--programmatic-validation",
    48  	)
    49  	ExpectWithOffset(1, err).NotTo(HaveOccurred())
    50  
    51  	By("implementing the mutating and validating webhooks")
    52  	err = pluginutil.ImplementWebhooks(filepath.Join(
    53  		kbc.Dir, "api", kbc.Version,
    54  		fmt.Sprintf("%s_webhook.go", strings.ToLower(kbc.Kind))))
    55  	ExpectWithOffset(1, err).NotTo(HaveOccurred())
    56  
    57  	ExpectWithOffset(1, pluginutil.UncommentCode(
    58  		filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"),
    59  		"#- ../certmanager", "#")).To(Succeed())
    60  	ExpectWithOffset(1, pluginutil.UncommentCode(
    61  		filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"),
    62  		"#- ../prometheus", "#")).To(Succeed())
    63  	ExpectWithOffset(1, pluginutil.UncommentCode(
    64  		filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"),
    65  		"#- path: webhookcainjection_patch.yaml", "#")).To(Succeed())
    66  	ExpectWithOffset(1, pluginutil.UncommentCode(filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"),
    67  		certManagerTarget, "#")).To(Succeed())
    68  
    69  	if kbc.IsRestricted {
    70  		By("uncomment kustomize files to ensure that pods are restricted")
    71  		uncommentPodStandards(kbc)
    72  	}
    73  }
    74  
    75  // GenerateV4WithoutWebhooks implements a go/v4 plugin with APIs and enable Prometheus and CertManager
    76  func GenerateV4WithoutWebhooks(kbc *utils.TestContext) {
    77  	initingTheProject(kbc)
    78  	creatingAPI(kbc)
    79  
    80  	ExpectWithOffset(1, pluginutil.UncommentCode(
    81  		filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"),
    82  		"#- ../prometheus", "#")).To(Succeed())
    83  
    84  	if kbc.IsRestricted {
    85  		By("uncomment kustomize files to ensure that pods are restricted")
    86  		uncommentPodStandards(kbc)
    87  	}
    88  }
    89  
    90  func creatingAPI(kbc *utils.TestContext) {
    91  	By("creating API definition")
    92  	err := kbc.CreateAPI(
    93  		"--group", kbc.Group,
    94  		"--version", kbc.Version,
    95  		"--kind", kbc.Kind,
    96  		"--namespaced",
    97  		"--resource",
    98  		"--controller",
    99  		"--make=false",
   100  	)
   101  	ExpectWithOffset(1, err).NotTo(HaveOccurred())
   102  
   103  	By("implementing the API")
   104  	ExpectWithOffset(1, pluginutil.InsertCode(
   105  		filepath.Join(kbc.Dir, "api", kbc.Version, fmt.Sprintf("%s_types.go", strings.ToLower(kbc.Kind))),
   106  		fmt.Sprintf(`type %sSpec struct {
   107  `, kbc.Kind),
   108  		`	// +optional
   109  Count int `+"`"+`json:"count,omitempty"`+"`"+`
   110  `)).Should(Succeed())
   111  }
   112  
   113  func initingTheProject(kbc *utils.TestContext) {
   114  	By("initializing a project")
   115  	err := kbc.Init(
   116  		"--plugins", "go/v4",
   117  		"--project-version", "3",
   118  		"--domain", kbc.Domain,
   119  	)
   120  	ExpectWithOffset(1, err).NotTo(HaveOccurred())
   121  }
   122  
   123  //nolint:lll
   124  const certManagerTarget = `#replacements:
   125  #  - source: # Add cert-manager annotation to ValidatingWebhookConfiguration, MutatingWebhookConfiguration and CRDs
   126  #      kind: Certificate
   127  #      group: cert-manager.io
   128  #      version: v1
   129  #      name: serving-cert # this name should match the one in certificate.yaml
   130  #      fieldPath: .metadata.namespace # namespace of the certificate CR
   131  #    targets:
   132  #      - select:
   133  #          kind: ValidatingWebhookConfiguration
   134  #        fieldPaths:
   135  #          - .metadata.annotations.[cert-manager.io/inject-ca-from]
   136  #        options:
   137  #          delimiter: '/'
   138  #          index: 0
   139  #          create: true
   140  #      - select:
   141  #          kind: MutatingWebhookConfiguration
   142  #        fieldPaths:
   143  #          - .metadata.annotations.[cert-manager.io/inject-ca-from]
   144  #        options:
   145  #          delimiter: '/'
   146  #          index: 0
   147  #          create: true
   148  #      - select:
   149  #          kind: CustomResourceDefinition
   150  #        fieldPaths:
   151  #          - .metadata.annotations.[cert-manager.io/inject-ca-from]
   152  #        options:
   153  #          delimiter: '/'
   154  #          index: 0
   155  #          create: true
   156  #  - source:
   157  #      kind: Certificate
   158  #      group: cert-manager.io
   159  #      version: v1
   160  #      name: serving-cert # this name should match the one in certificate.yaml
   161  #      fieldPath: .metadata.name
   162  #    targets:
   163  #      - select:
   164  #          kind: ValidatingWebhookConfiguration
   165  #        fieldPaths:
   166  #          - .metadata.annotations.[cert-manager.io/inject-ca-from]
   167  #        options:
   168  #          delimiter: '/'
   169  #          index: 1
   170  #          create: true
   171  #      - select:
   172  #          kind: MutatingWebhookConfiguration
   173  #        fieldPaths:
   174  #          - .metadata.annotations.[cert-manager.io/inject-ca-from]
   175  #        options:
   176  #          delimiter: '/'
   177  #          index: 1
   178  #          create: true
   179  #      - select:
   180  #          kind: CustomResourceDefinition
   181  #        fieldPaths:
   182  #          - .metadata.annotations.[cert-manager.io/inject-ca-from]
   183  #        options:
   184  #          delimiter: '/'
   185  #          index: 1
   186  #          create: true
   187  #  - source: # Add cert-manager annotation to the webhook Service
   188  #      kind: Service
   189  #      version: v1
   190  #      name: webhook-service
   191  #      fieldPath: .metadata.name # namespace of the service
   192  #    targets:
   193  #      - select:
   194  #          kind: Certificate
   195  #          group: cert-manager.io
   196  #          version: v1
   197  #        fieldPaths:
   198  #          - .spec.dnsNames.0
   199  #          - .spec.dnsNames.1
   200  #        options:
   201  #          delimiter: '.'
   202  #          index: 0
   203  #          create: true
   204  #  - source:
   205  #      kind: Service
   206  #      version: v1
   207  #      name: webhook-service
   208  #      fieldPath: .metadata.namespace # namespace of the service
   209  #    targets:
   210  #      - select:
   211  #          kind: Certificate
   212  #          group: cert-manager.io
   213  #          version: v1
   214  #        fieldPaths:
   215  #          - .spec.dnsNames.0
   216  #          - .spec.dnsNames.1
   217  #        options:
   218  #          delimiter: '.'
   219  #          index: 1
   220  #          create: true`
   221  
   222  func uncommentPodStandards(kbc *utils.TestContext) {
   223  	configManager := filepath.Join(kbc.Dir, "config", "manager", "manager.yaml")
   224  
   225  	//nolint:lll
   226  	if err := pluginutil.ReplaceInFile(configManager, `# TODO(user): For common cases that do not require escalating privileges
   227          # it is recommended to ensure that all your Pods/Containers are restrictive.
   228          # More info: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted
   229          # Please uncomment the following code if your project does NOT have to work on old Kubernetes
   230          # versions < 1.19 or on vendors versions which do NOT support this field by default (i.e. Openshift < 4.11 ).
   231          # seccompProfile:
   232          #   type: RuntimeDefault`, `seccompProfile:
   233            type: RuntimeDefault`); err == nil {
   234  		ExpectWithOffset(1, err).NotTo(HaveOccurred())
   235  	}
   236  }