Repository: openshift/odo (go)

Issue:
service creation fails with wrong namespace
/kind bug


## What versions of software are you using?

**Operating System:** Win10Pro

**Output of `odo version`:**

```
odo v2.3.0 (089b8ea26)

Server: https://api.sandbox.x8i5.p1.openshiftapps.com:6443
Kubernetes: v1.20.0+558d959
```

## How did you run odo exactly?
```
odo service create rhoas-operator.0.7.8/KafkaConnection
odo push

```
## Actual behavior

```
Validation                                                                                                                                                                                     
 V  Validating the devfile [0ns]                                                                                                                                                               
                                                                                                                                                                                               
Creating Services for component ncomp                                                                                                                                                          
 X  Failed to start component with name "ncomp". Error: Failed to create the component: failed to create service(s) associated with the component: the namespace of the provided object does not match the namespace sent on the request                                                                                                                                                      
```
                                                                                                                                                                                               

## Expected behavior

Service should be created

## Any logs, error output, etc?

`odo service create rhoas-operator.0.7.8/KafkaConnection --dry-run` gives the following output:

```
apiVersion: rhoas.redhat.com/v1alpha1                       
kind: KafkaConnection                                       
metadata:                                                   
  labels:                                                   
    app.kubernetes.io/component: external-service           
    app.kubernetes.io/managed-by: rhoas                     
  name: example                                             
  namespace: example-namespace                              
spec:                                                       
  accessTokenSecretName: rh-managed-services-api-accesstoken
  credentials:                                              
    serviceAccountSecretName: service-account-secret        
  kafkaId: exampleId                                        
```




Pull request:
Remove metadata.namespace from ALM Examples
**What type of PR is this?**

/kind bug

**What does this PR do / why we need it**:

**Which issue(s) this PR fixes**:

Fixes #5019 

**PR acceptance criteria**:

- [x] Unit test 

- [ ] Integration test 

- [ ] Documentation 

- [x] I have read the [test guidelines](https://github.com/openshift/odo/blob/master/docs/dev/test-architecture.adoc)

**How to test changes / Special notes to the reviewer**:

```
odo service create rhoas-operator.0.9.0/ServiceRegistryConnection
odo push
```


Patch:
diff --git a/pkg/service/service.go b/pkg/service/service.go
index c8a7dfb13..2dd5fbb3e 100644
--- a/pkg/service/service.go
+++ b/pkg/service/service.go
@@ -193,6 +193,10 @@ func GetAlmExample(csv olm.ClusterServiceVersion, cr, serviceType string) (almEx
 func getAlmExample(almExamples []map[string]interface{}, crd, operator string) (map[string]interface{}, error) {
 	for _, example := range almExamples {
 		if example["kind"].(string) == crd {
+			// Remove metadata.namespace from example
+			if metadata, ok := example["metadata"].(map[string]interface{}); ok {
+				delete(metadata, "namespace")
+			}
 			return example, nil
 		}
 	}


Test patch:
diff --git a/pkg/service/service_test.go b/pkg/service/service_test.go
index 2e5343bd0..6de4cce3d 100644
--- a/pkg/service/service_test.go
+++ b/pkg/service/service_test.go
@@ -721,3 +721,155 @@ func Test_addKubernetesComponent(t *testing.T) {
 		})
 	}
 }
+
+func TestGetAlmExample(t *testing.T) {
+	tests := []struct {
+		name     string
+		examples []map[string]interface{}
+		crd      string
+		want     map[string]interface{}
+		wantErr  bool
+	}{
+		{
+			name: "rhoas-operator.0.9.0",
+			crd:  "CloudServiceAccountRequest",
+			examples: []map[string]interface{}{
+				{
+					"apiVersion": "rhoas.redhat.com/v1alpha1",
+					"kind":       "ServiceRegistryConnection",
+					"metadata": map[string]interface{}{
+						"name":      "example",
+						"namespace": "example-namespace",
+						"labels": map[string]interface{}{
+							"app.kubernetes.io/component":  "external-service",
+							"app.kubernetes.io/managed-by": "rhoas",
+						},
+					},
+					"spec": map[string]interface{}{
+						"accessTokenSecretName": "rh-managed-services-api-accesstoken",
+						"serviceRegistryId":     "exampleId",
+						"credentials": map[string]interface{}{
+							"serviceAccountSecretName": "service-account-secret",
+						},
+					},
+				},
+				{
+					"apiVersion": "rhoas.redhat.com/v1alpha1",
+					"kind":       "CloudServiceAccountRequest",
+					"metadata": map[string]interface{}{
+						"name":      "example",
+						"namespace": "example-namespace",
+					},
+					"spec": map[string]interface{}{
+						"serviceAccountName":        "rhoas-sa",
+						"serviceAccountDescription": "Operator created service account",
+						"serviceAccountSecretName":  "service-account-credentials",
+						"accessTokenSecretName":     "rh-managed-services-api-accesstoken",
+					},
+				},
+				{
+					"apiVersion": "rhoas.redhat.com/v1alpha1",
+					"kind":       "CloudServicesRequest",
+					"metadata": map[string]interface{}{
+						"name":      "example",
+						"namespace": "example-namespace",
+						"labels": map[string]interface{}{
+							"app.kubernetes.io/component":  "external-service",
+							"app.kubernetes.io/managed-by": "rhoas",
+						},
+					},
+					"spec": map[string]interface{}{
+						"accessTokenSecretName": "rh-cloud-services-api-accesstoken",
+					},
+				},
+			},
+			want: map[string]interface{}{
+				"apiVersion": "rhoas.redhat.com/v1alpha1",
+				"kind":       "CloudServiceAccountRequest",
+				"metadata": map[string]interface{}{
+					"name": "example",
+				},
+				"spec": map[string]interface{}{
+					"serviceAccountName":        "rhoas-sa",
+					"serviceAccountDescription": "Operator created service account",
+					"serviceAccountSecretName":  "service-account-credentials",
+					"accessTokenSecretName":     "rh-managed-services-api-accesstoken",
+				},
+			},
+		},
+		{
+			name: "postgresoperator.v5.0.3",
+			crd:  "PostgresCluster",
+			examples: []map[string]interface{}{
+				{
+					"apiVersion": "postgres-operator.crunchydata.com/v1beta1",
+					"kind":       "PostgresCluster",
+					"metadata": map[string]interface{}{
+						"name": "example",
+					},
+					"spec": map[string]interface{}{
+						"instances": []map[string]interface{}{
+							{
+								"dataVolumeClaimSpec": map[string]interface{}{
+									"accessModes": []string{
+										"ReadWriteOnce",
+									},
+									"resources": map[string]interface{}{
+										"requests": map[string]interface{}{
+											"storage": "1Gi",
+										},
+									},
+								},
+								"replicas": 1,
+							},
+						},
+						"postgresVersion": 13,
+					},
+				},
+			},
+			want: map[string]interface{}{
+				"apiVersion": "postgres-operator.crunchydata.com/v1beta1",
+				"kind":       "PostgresCluster",
+				"metadata": map[string]interface{}{
+					"name": "example",
+				},
+				"spec": map[string]interface{}{
+					"instances": []map[string]interface{}{
+						{
+							"dataVolumeClaimSpec": map[string]interface{}{
+								"accessModes": []string{
+									"ReadWriteOnce",
+								},
+								"resources": map[string]interface{}{
+									"requests": map[string]interface{}{
+										"storage": "1Gi",
+									},
+								},
+							},
+							"replicas": 1,
+						},
+					},
+					"postgresVersion": 13,
+				},
+			},
+		},
+		{
+			name:     "crd not found",
+			crd:      "unknown",
+			examples: []map[string]interface{}{},
+			want:     nil,
+			wantErr:  true,
+		}}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			result, err := getAlmExample(tt.examples, tt.crd, "an operator")
+			if err != nil != tt.wantErr {
+				t.Errorf("Expected error %v but got %q\n", tt.wantErr, err)
+			}
+			if !reflect.DeepEqual(result, tt.want) {
+				t.Errorf("\nExpected: %+v\n     Got: %+v\n", tt.want, result)
+			}
+		})
+	}
+}