Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce webhook to prevent more than 1 KIP resource in a single namespace #115

Merged
merged 19 commits into from
Dec 18, 2023

Conversation

dkwon17
Copy link
Collaborator

@dkwon17 dkwon17 commented Nov 28, 2023

Related issue: https://issues.redhat.com/browse/CRW-4980

This PR creates a validation webhook ensures that only one KIP CR can be created in a given namespace:

https://github.com/che-incubator/kubernetes-image-puller-operator/assets/83611742/09e20dad-6ec0-4a07-b326-ce2e40f26a39.

This PR also generates deployment manifests under deploy/deployment:

└── deploy/deployment/
    ├── kubernetes/
    │   ├── objects/
    │   └── combined.yaml
    └── openshift/
        ├── objects/
        └── combined.yaml

where manifests under kubernetes is meant for installation on a kubernetes cluster (requires cert-manager), and manifests under openshift is meant for openshift cluster (requires service-ca)

This is generated automatically when running make deploy.

How to test this PR

  1. Build the operator images (optional)
    I've already built it here:
  • quay.io/dkwon17/kubernetes-image-puller-operator:validation

The image can be built by running this command:

make docker-build IMG=quay.io/<username>/kubernetes-image-puller-operator:<tag>
  1. In a new cluster, deploy the operator:
make deploy IMG=quay.io/dkwon17/kubernetes-image-puller-operator:validation
  1. In the default namespace, try to create two KubernetesImagePuller resources in the same namespace. The webhook should prevent that from happening with an error message:
Screenshot

image

Testing the bundle build

With this PR, building a bundle image and deploying with operator-sdk run bundle works as expected:

  1. Set env vars.

Note: you must have your own kubernetes-image-puller-operator and kubernetes-image-puller-operator-bundle repositories available under your quay account.

$ export IMAGE_TAG_BASE=quay.io/<username>/kubernetes-image-puller-operator
$ export VERSION=1.1.0
  1. Build and push the operator image:
$ make docker-build docker-push 
  1. Build and push the bundle image:
$ rm -rf bundle/manifests
$ make bundle bundle-build bundle-push
  1. Install the bundle on a cluster with OLM:
$ ./bin/operator-sdk run bundle $BUNDLE_IMG

The Kubernetes Image Puller operator should install successfully, and the webhook functionality described in the How to test this PR should work as well.

  1. Uninstall the operator
./bin/operator-sdk cleanup kubernetes-imagepuller-operator

operator-sdk create webhook --group che --version v1alpha1 --kind KubernetesImagePuller  --defaulting --programmatic-validation --force
Writing kustomize manifests for you to edit...
Writing scaffold for you to edit...
api/v1alpha1/kubernetesimagepuller_webhook.go
$ operator-sdk version
operator-sdk version: "v1.9.2", commit: "319e77f2fff57c6c862bddd64ecf9c562f2d2161", kubernetes version: "1.20.2", go version: "go1.16.6", GOOS: "linux", GOARCH: "amd64"

Signed-off-by: David Kwon <[email protected]>
Signed-off-by: David Kwon <[email protected]>
Copy link

Click here to review and test in web IDE: Contribute

1 similar comment
Copy link

Click here to review and test in web IDE: Contribute

@dkwon17 dkwon17 requested a review from ibuziuk November 29, 2023 02:20
@dkwon17 dkwon17 marked this pull request as ready for review November 29, 2023 02:20
@dkwon17 dkwon17 requested a review from tolusha November 29, 2023 02:20
@dkwon17 dkwon17 force-pushed the validation-webhook-restrict-cr branch from 4c49489 to 4c4d59a Compare November 29, 2023 02:24
Copy link

Click here to review and test in web IDE: Contribute

@@ -169,7 +169,8 @@ bundle: generate manifests download-kustomize download-operator-sdk ## Generate

CSV_PATH=$$($(MAKE) csv-path)
yq -riY '.metadata.annotations.containerImage = "'$(IMG)'"' $${CSV_PATH}
yq -riY '.spec.install.spec.deployments[0].spec.template.spec.containers[1].image = "'$(IMG)'"' $${CSV_PATH}
# Update container image for container 'kuebrnetes-image-puller-operator' in the list of deployments
yq -riY '.spec.install.spec.deployments[0].spec.template.spec.containers[] |= (select(.name == "kubernetes-image-puller-operator") .image |= "'$(IMG)'")' $${CSV_PATH}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When running make bundle on the dogfooding cluster, the order of the containers are different. This change makes it so that we don't assume that the kubernetes-image-puller-operator container is defined at index 1

Copy link

Click here to review and test in web IDE: Contribute

Copy link

@amisevsk amisevsk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally LGTM, though I haven't been able to test yet.

api/v1alpha1/kubernetesimagepuller_webhook.go Show resolved Hide resolved
metadata:
name: validating-webhook-configuration
annotations:
cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't had a chance to test this, but speaking from (distant) experience in setting up similar for DWO -- have we verified this works on both Kubernetes and OpenShift? I recall some differences in how certs for webhooks are managed on OpenShift vs. Kubernetes. On Kubernetes we can use cert-manager but on OpenShift we need (IIRC) the service-ca.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dkwon17
We have different configuration for Kubernetes and OpenShift.
Please have a look at [1]. As far as I remember I was inspired from DWO configuration.

[1] https://github.com/eclipse-che/che-operator/tree/a4e19ead9d324dce09f5ca400a5cb7eff3abd253/config/openshift/patches

.github/workflows/pr-check.yml Outdated Show resolved Hide resolved
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: selfsigned-issuer
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All resources names must be unique, like kubernetes-image-puller-selfsigned-issuer

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it should be prefixed by kustomize on generation

Copy link

Click here to review and test in web IDE: Contribute

- Create gen-deployment makefile goal. Generates deploy folder for kubernetes and openshift.
- Use name-prefix to prefix resources
- Move operator service account from rbac directory to manager directory

Signed-off-by: David Kwon <[email protected]>
- Create deploy.mk to avoid checking for kubectl or oc when make test is ran within to dockerfile
- Create prefix overlay to prevent prefixing csv for bundle build

Signed-off-by: dkwon17 <[email protected]>
Copy link

github-actions bot commented Dec 5, 2023

Click here to review and test in web IDE: Contribute

for file in temp??; do
name_kind=$$(yq -r '"\(.metadata.name).\(.kind)"' "$${file}")
mv "$${file}" "$${OBJECTS_DIR}/$${name_kind}.yaml"
done
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

# Red Hat, Inc. - initial API and implementation
#

namePrefix: k8s-image-puller-operator-
Copy link
Collaborator Author

@dkwon17 dkwon17 Dec 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've set the prefix to k8s-image-puller-operator- instead of kubernetes-image-puller-operator- because the longer prefix led to resource names that were too long (IIRC, it was one of the rolebindings)

I stuck with kubernetes-image-puller-operator- to be consistent with the kubernetes-image-puller pod names

@@ -13,7 +13,7 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: kubernetes-image-puller-operator
name: manager
Copy link
Collaborator Author

@dkwon17 dkwon17 Dec 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of the new kustomize namePrefix (example) and resource renames, I plan to indicate in the KIP operator release notes what resource names have been changed

Signed-off-by: dkwon17 <[email protected]>
Copy link

github-actions bot commented Dec 5, 2023

Click here to review and test in web IDE: Contribute

Signed-off-by: David Kwon <[email protected]>
Copy link

github-actions bot commented Dec 6, 2023

Click here to review and test in web IDE: Contribute

@dkwon17
Copy link
Collaborator Author

dkwon17 commented Dec 6, 2023

Thanks for the reviews @amisevsk @tolusha, I've updated this PR.

The main update is that there is a new goal in the makefile gen-deployment that generates manifests for the kubernetes and openshift installation, similar to how che-operator and devworkspace-operator functions.

The make deploy command will generate the manifests and apply them based on the platform:

deploy: manifests download-kustomize kustomize-operator-image gen-deployment ## Deploy controller to the K8s cluster specified in ~/.kube/config.
$(K8S_CLI) apply -f $(DEPLOYMENT_DIR)/$(PLATFORM)/combined.yaml

Copy link

github-actions bot commented Dec 6, 2023

Click here to review and test in web IDE: Contribute


manifests: download-controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
$(CONTROLLER_GEN) crd:crdVersions=v1 rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases
$(CONTROLLER_GEN) crd:crdVersions=v1 rbac:roleName=manager-role paths="./..." output:crd:artifacts:config=config/crd/bases
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you remove webhook parameter, then you don't need annotation anymore // +kubebuilder:webhook:path ...

@tolusha
Copy link
Collaborator

tolusha commented Dec 7, 2023

@dkwon17
How is OLM bundle is generated?
Could we check operator update?

@dkwon17
Copy link
Collaborator Author

dkwon17 commented Dec 7, 2023

@tolusha I've generated the bundle image and tried it out with Testing the bundle build steps I've added to the PR description: #115 (comment)

Basically to build and deploy on a cluster, I've done:

export IMG=quay.io/dkwon17/kubernetes-image-puller-operator:1.1.0
export BUNDLE_IMG=quay.io/dkwon17/kubernetes-image-puller-operator-bundle:1.1.0
make docker-build docker-push 
make bundle bundle-build bundle-push
./bin/operator-sdk run bundle $BUNDLE_IMG

Could we check operator update?

What is the best way I can check that?

Copy link

github-actions bot commented Dec 7, 2023

Click here to review and test in web IDE: Contribute

@dkwon17 dkwon17 marked this pull request as draft December 7, 2023 21:52
@tolusha
Copy link
Collaborator

tolusha commented Dec 8, 2023

It is hard to review all resources and spot possible issues. So, in order to be sure everything works correctly, we have to:

  1. Ensure that README.md is up to date, it is possible to deploy KIP on both Kubernetes and OpenShift clusters
  2. Release works
  3. Try to update KIP on OpenShift cluster to a newer version.

@dkwon17
Copy link
Collaborator Author

dkwon17 commented Dec 12, 2023

I have tested this PR with Kubernetes and OpenShift, as well as the operator upgrade

First, I created the operator image:

export IMAGE_TAG_BASE=quay.io/dkwon17/kubernetes-image-puller-operator
export VERSION=1.1.0
make docker-build docker-push
Test make deploy on minikube

Run:

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.3/cert-manager.yaml
make deploy IMG=quay.io/dkwon17/kubernetes-image-puller-operator:1.1.0

(screenshots have a different image tag, it is the same image as dkwon17/kubernetes-image-puller-operator:1.1.0)

image

After creating 1 KIP CR in `kubernetes-image-puller-operator` namespace

image

After trying to create a second KIP CR in `kubernetes-image-puller-operator` namespace:

image

Test make deploy on openshift

Run:

make deploy IMG=quay.io/dkwon17/kubernetes-image-puller-operator:1.1.0

image

After creating 1 KIP CR in `kubernetes-image-puller-operator` namespace

image

After trying to create a second KIP CR in `kubernetes-image-puller-operator` namespace:

image

@dkwon17
Copy link
Collaborator Author

dkwon17 commented Dec 12, 2023

Test and deploy using OLM

Run:

rm -rf bundle/manifests
make bundle
bundle/test-bundle.sh

image

KIP operator on the operators tab:

image

KIP pods after creating a KIP CR in a namespace:

image

Webhook when trying to create a second KIP CR in the same namespace:

image

The message appears twice, but this happens only once. Subsequent attempts only result in 1 message. I don't get this problem when trying to create the KIP CR using kubectl, maybe it's an issue with the OpenShift console?

@dkwon17
Copy link
Collaborator Author

dkwon17 commented Dec 12, 2023

Test with release-olm-bundle

Run

./make-release.sh $VERSION --release-olm-bundle

The catalog image is pushed: quay.io/dkwon17/kubernetes-image-puller-operator-catalog:stable

@dkwon17
Copy link
Collaborator Author

dkwon17 commented Dec 12, 2023

Test upgrading KIP operator v1.0.6 to KIP operator v1.1.0

  1. Install KIP operator v1.0.6 from OpeartorHub
  2. Create catalog source:
apiVersion: operators.coreos.com/v1alpha1
kind: CatalogSource
metadata:
  name: kubernetes-imagepuller-operator
  namespace: openshift-marketplace
spec:
  image: quay.io/dkwon17/kubernetes-image-puller-operator-catalog:stable
  sourceType: grpc
  updateStrategy:
    registryPoll:
      interval: 15m
  1. Update the KIP operator subscription to reference the new catalog source
  2. Wait until upgrade completes:
Screenshots

image

image

Deployment updated:

image

The following old components are updated as well

Old components image

with the exception of the metrics-reader cluster role. This role remains in the cluster, despite not being defined in bundle/manifests anymore.

New components

image

@dkwon17 dkwon17 marked this pull request as ready for review December 12, 2023 21:32
@dkwon17
Copy link
Collaborator Author

dkwon17 commented Dec 12, 2023

Is there something else I should check @tolusha ?

I will add a new commit updating the readme for:

  • resource name changes
  • cert-manager / service-ca requirement for webhook

@tolusha
Copy link
Collaborator

tolusha commented Dec 13, 2023

I run make bundle to generate a new bundle to see the differences.

  1. There are two files with identical content, must be only one:
  • kubernetes-image-puller-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml
  • metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml
  1. There are two files with identical content, must be only one:
  • controller-manager-metrics-service_v1_service.yaml
  • kubernetes-image-puller-operator-manager-metrics-service_v1_service.yaml

The changes below are not critical if old resources are removed after upgrade:
3. SA name changed kubernetes-image-puller-operator -> kubernetes-image-puller-operator-sa
4. Deployment name changes kubernetes-image-puller-operator -> kubernetes-image-puller-operator-manager

…m for webhook, update test-bundle.sh

Signed-off-by: dkwon17 <[email protected]>
Copy link

Click here to review and test in web IDE: Contribute

@dkwon17
Copy link
Collaborator Author

dkwon17 commented Dec 13, 2023

Yes, I should mention, before make bundle, I run rm -rf ./bundle/manifests to remove the old manifests

@dkwon17
Copy link
Collaborator Author

dkwon17 commented Dec 13, 2023

@ibuziuk and I discussed releaesing KIP operator version 1.1.0 which contains the webhook introduced by this PR.

@tolusha does it make more sense to update the readme and bundle/ folder in a separate PR?

@tolusha
Copy link
Collaborator

tolusha commented Dec 14, 2023

bundle folder is supposed to be updated on release, so yes, it has to be a different PR

@dkwon17
Copy link
Collaborator Author

dkwon17 commented Dec 18, 2023

Thank you @tolusha @amisevsk merging soon

@dkwon17 dkwon17 merged commit 6cc03a0 into che-incubator:main Dec 18, 2023
5 checks passed
@dkwon17 dkwon17 added the made-with-che Changes were made using Che label Dec 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
made-with-che Changes were made using Che
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants