Repository: tektoncd/operator (go)

Issue:
Update argocd-task-sync-and-wait catalog community cluster tasks to 0.2
All is in the title 😝 

Pull request description:
Updates argocd-task-sync-and-wait tasks to v0.2
Closes #633 
Signed-off-by: Shivam Mukhade <smukhade@redhat.com>

# Changes

<!-- 🎉🎉🎉 Thank you for the PR!!! 🎉🎉🎉 -->

<!-- Describe your changes here- ideally you can get that description straight from
your descriptive commit message(s)! -->

# Submitter Checklist

These are the criteria that every PR should meet, please check them off as you
review them:

- [ ] Includes [tests](https://github.com/tektoncd/community/blob/master/standards.md#principles) (if functionality changed/added)
- [ ] Includes [docs](https://github.com/tektoncd/community/blob/master/standards.md#principles) (if user facing)
- [x] Commit messages follow [commit message best practices](https://github.com/tektoncd/community/blob/master/standards.md#commit-messages)

_See [the contribution guide](https://github.com/tektoncd/operator/blob/master/CONTRIBUTING.md) for more details._

# Release Notes

<!--
Describe any user facing changes here, or delete this block.

Examples of user facing changes:
- API changes
- Bug fixes
- Any changes in behavior
- Changes requiring upgrade notices or deprecation warnings

For pull requests with a release note:

```release-note
Your release note here
```

For pull requests that require additional action from users switching to the new release, include the string "action required" (case insensitive) in the release note:

```release-note
action required: your release note here
```

For pull requests that don't need to be mentioned at release time, use the `/release-note-none` Prow command to add the `release-note-none` label to the PR. You can also write the string "NONE" as a release note in your PR description:

```release-note
NONE
```
-->


Patch:
diff --git a/config/base/300-operator_v1alpha1_config_crd.yaml b/config/base/300-operator_v1alpha1_config_crd.yaml
index ab988ce4e..a9388e59a 100644
--- a/config/base/300-operator_v1alpha1_config_crd.yaml
+++ b/config/base/300-operator_v1alpha1_config_crd.yaml
@@ -35,6 +35,9 @@ spec:
     subresources:
       status: {}
     additionalPrinterColumns:
+    - jsonPath: .status.version
+      name: Version
+      type: string
     - jsonPath: .status.conditions[?(@.type=="Ready")].status
       name: Ready
       type: string
diff --git a/pkg/reconciler/openshift/tektonaddon/clustertTask.go b/pkg/reconciler/openshift/tektonaddon/clustertTask.go
index cecd8143f..11a8a9a86 100644
--- a/pkg/reconciler/openshift/tektonaddon/clustertTask.go
+++ b/pkg/reconciler/openshift/tektonaddon/clustertTask.go
@@ -51,7 +51,7 @@ var communityResourceURLs = []string{
 	"https://raw.githubusercontent.com/tektoncd/catalog/master/task/git-cli/0.3/git-cli.yaml",
 	"https://raw.githubusercontent.com/tektoncd/catalog/master/task/pull-request/0.1/pull-request.yaml",
 	"https://raw.githubusercontent.com/tektoncd/catalog/master/task/kubeconfig-creator/0.1/kubeconfig-creator.yaml",
-	"https://raw.githubusercontent.com/tektoncd/catalog/main/task/argocd-task-sync-and-wait/0.1/argocd-task-sync-and-wait.yaml",
+	"https://raw.githubusercontent.com/tektoncd/catalog/main/task/argocd-task-sync-and-wait/0.2/argocd-task-sync-and-wait.yaml",
 }
 
 func (r *Reconciler) EnsureClusterTask(ctx context.Context, enable string, ta *v1alpha1.TektonAddon) error {
diff --git a/pkg/reconciler/openshift/tektonaddon/extension.go b/pkg/reconciler/openshift/tektonaddon/extension.go
index 8dbefd2cc..23e7d21df 100644
--- a/pkg/reconciler/openshift/tektonaddon/extension.go
+++ b/pkg/reconciler/openshift/tektonaddon/extension.go
@@ -203,6 +203,10 @@ func (oe openshiftExtension) PostReconcile(ctx context.Context, comp v1alpha1.Te
 		if err := applyAddons(&tknservecliManifest, "05-tkncliserve"); err != nil {
 			return err
 		}
+		if err := addonTransform(ctx, &tknservecliManifest, addon); err != nil {
+			return err
+		}
+
 		routeHost, err := getRouteHost(&tknservecliManifest)
 		if err != nil {
 			return err
diff --git a/pkg/webhook/webhook_init.go b/pkg/webhook/webhook_init.go
index ba92efb63..8bf37e81e 100644
--- a/pkg/webhook/webhook_init.go
+++ b/pkg/webhook/webhook_init.go
@@ -12,7 +12,7 @@ import (
 	"github.com/tektoncd/operator/pkg/apis/operator/v1alpha1"
 	clientset "github.com/tektoncd/operator/pkg/client/clientset/versioned"
 	operatorclient "github.com/tektoncd/operator/pkg/client/injection/client"
-	"k8s.io/apimachinery/pkg/api/errors"
+	apierror "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	"github.com/tektoncd/operator/pkg/reconciler/common"
@@ -22,36 +22,62 @@ import (
 )
 
 const WEBHOOK_INSTALLERSET_LABEL = "validating-defaulting-webhooks.operator.tekton.dev"
+const POD_NAMESPACE_ENV_KEY = "SYSTEM_NAMESPACE"
+
+var (
+	ERR_NAMESPACE_ENV_NOT_SET = fmt.Errorf("Pod namespace env %q not set", POD_NAMESPACE_ENV_KEY)
+)
 
 func CreateWebhookResources(ctx context.Context) {
 	logger := logging.FromContext(ctx)
 
-	mfclient, err := mfc.NewClient(injection.GetConfig(ctx))
+	manifest, err := fetchManifests(ctx)
+	if err != nil {
+		logger.Fatalw("error creating initial manifest", zap.Error(err))
+	}
+
+	client := operatorclient.Get(ctx)
+	err = checkAndDeleteInstallerSet(ctx, client)
 	if err != nil {
 		logger.Fatalw("error creating client from injected config", zap.Error(err))
 	}
+
+	if err := createInstallerSet(ctx, client, *manifest); err != nil {
+		logger.Fatalw("error creating client from injected config", zap.Error(err))
+	}
+}
+
+func fetchManifests(ctx context.Context) (*mf.Manifest, error) {
+	logger := logging.FromContext(ctx)
+	mfclient, err := mfc.NewClient(injection.GetConfig(ctx))
+	if err != nil {
+		return nil, err
+	}
 	mflogger := zapr.NewLogger(logger.Named("manifestival").Desugar())
 	manifest, err := mf.ManifestFrom(mf.Slice{}, mf.UseClient(mfclient), mf.UseLogger(mflogger))
 	if err != nil {
-		logger.Fatalw("error creating initial manifest", zap.Error(err))
+		return nil, err
 	}
 
 	// Read manifests
 	koDataDir := os.Getenv(common.KoEnvKey)
 	validating_defaulting_webhooks := filepath.Join(koDataDir, "validating-defaulting-webhook")
 	if err := common.AppendManifest(&manifest, validating_defaulting_webhooks); err != nil {
-		logger.Fatalw("error creating initial manifest", zap.Error(err))
+		return nil, err
 	}
+	return manifestTransform(&manifest)
+}
 
-	client := operatorclient.Get(ctx)
-	err = checkAndDeleteInstallerSet(ctx, client)
-	if err != nil {
-		logger.Fatalw("error creating client from injected config", zap.Error(err))
+func manifestTransform(m *mf.Manifest) (*mf.Manifest, error) {
+	ns, ok := os.LookupEnv(POD_NAMESPACE_ENV_KEY)
+	if !ok || ns == "" {
+		return nil, ERR_NAMESPACE_ENV_NOT_SET
 	}
-
-	if err := createInstallerSet(ctx, client, manifest); err != nil {
-		logger.Fatalw("error creating client from injected config", zap.Error(err))
+	tfs := []mf.Transformer{
+		mf.InjectNamespace(ns),
 	}
+	result, err := m.Transform(tfs...)
+	return &result, err
 }
 
 func checkAndDeleteInstallerSet(ctx context.Context, oc clientset.Interface) error {
@@ -60,7 +86,7 @@ func checkAndDeleteInstallerSet(ctx context.Context, oc clientset.Interface) err
 			LabelSelector: WEBHOOK_INSTALLERSET_LABEL,
 		})
 	if err != nil {
-		if errors.IsNotFound(err) {
+		if apierror.IsNotFound(err) {
 			return nil
 		}
 		return err


Test patch:
diff --git a/pkg/webhook/testdata/validating-defaulting-webhook/500_webhooks.yaml b/pkg/webhook/testdata/validating-defaulting-webhook/500_webhooks.yaml
new file mode 100644
index 000000000..f3203b4e1
--- /dev/null
+++ b/pkg/webhook/testdata/validating-defaulting-webhook/500_webhooks.yaml
@@ -0,0 +1,61 @@
+---
+apiVersion: admissionregistration.k8s.io/v1
+kind: MutatingWebhookConfiguration
+metadata:
+  labels:
+    app: tekton-operator
+    name: tekton-operator-webhook
+  name: webhook.operator.tekton.dev
+webhooks:
+- admissionReviewVersions:
+  - v1beta1
+  - v1
+  clientConfig:
+    service:
+      name: tekton-operator-webhook
+      namespace: openshift-operators
+  failurePolicy: Fail
+  name: webhook.operator.tekton.dev
+  sideEffects: None
+---
+apiVersion: admissionregistration.k8s.io/v1
+kind: ValidatingWebhookConfiguration
+metadata:
+  labels:
+    app: tekton-operator
+    name: tekton-operator-webhook
+  name: config.webhook.operator.tekton.dev
+webhooks:
+- admissionReviewVersions:
+  - v1beta1
+  - v1
+  clientConfig:
+    service:
+      name: tekton-operator-webhook
+      namespace: openshift-operators
+  failurePolicy: Fail
+  name: config.webhook.operator.tekton.dev
+  namespaceSelector:
+    matchExpressions:
+    - key: operator.tekton.dev/release
+      operator: Exists
+  sideEffects: None
+---
+apiVersion: admissionregistration.k8s.io/v1
+kind: ValidatingWebhookConfiguration
+metadata:
+  labels:
+    app: tekton-operator
+    name: tekton-operator-webhook
+  name: validation.webhook.operator.tekton.dev
+webhooks:
+- admissionReviewVersions:
+  - v1beta1
+  - v1
+  clientConfig:
+    service:
+      name: tekton-operator-webhook
+      namespace: openshift-operators
+  failurePolicy: Fail
+  name: validation.webhook.operator.tekton.dev
+  sideEffects: None
diff --git a/pkg/webhook/webhook_init_test.go b/pkg/webhook/webhook_init_test.go
new file mode 100644
index 000000000..af9ad5808
--- /dev/null
+++ b/pkg/webhook/webhook_init_test.go
@@ -0,0 +1,59 @@
+package webhook
+
+import (
+	mf "github.com/manifestival/manifestival"
+	"gotest.tools/v3/assert"
+	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+	"os"
+	"path/filepath"
+	"testing"
+)
+
+const (
+	KoEnvKey = "KO_DATA_PATH"
+)
+
+func TestCreateWebhookResources(t *testing.T) {
+	t.Run("transform manifest when pod namespace env is set", func(t *testing.T) {
+		namespace_new := "not-the-default-value"
+		testdataPath := filepath.Join("testdata", "validating-defaulting-webhook")
+		m, err := mf.ManifestFrom(mf.Path(testdataPath))
+		assert.NilError(t, err)
+		os.Setenv(POD_NAMESPACE_ENV_KEY, namespace_new)
+		defer func() {
+			os.Unsetenv(POD_NAMESPACE_ENV_KEY)
+		}()
+		mOut, err := manifestTransform(&m)
+		assert.NilError(t, err)
+		for _, res := range mOut.Resources() {
+			assertServiceNamespace(t, &res, namespace_new)
+		}
+
+	})
+	t.Run("return err when pod namespace env is not set", func(t *testing.T) {
+		testdataPath := filepath.Join("testdata", "validating-defaulting-webhook")
+		m, err := mf.ManifestFrom(mf.Path(testdataPath))
+		assert.NilError(t, err)
+		_, err = manifestTransform(&m)
+		assert.Error(t, err, ERR_NAMESPACE_ENV_NOT_SET.Error())
+	})
+}
+
+func assertServiceNamespace(t *testing.T, u *unstructured.Unstructured, ns string) {
+	t.Helper()
+	hooks, _, _ := unstructured.NestedFieldNoCopy(u.Object, "webhooks")
+	for _, hook := range hooks.([]interface{}) {
+		srv, found, err := unstructured.NestedFieldNoCopy(hook.(map[string]interface{}), "clientConfig", "service")
+		if err != nil {
+			assert.NilError(t, err)
+		}
+		if found {
+			m := srv.(map[string]interface{})
+			got := m["namespace"]
+			if got != ns {
+				t.Errorf("expected namespace %q, got %q", ns, got)
+			}
+		}
+	}
+
+}