diff --git a/bindata/configmaps/console-configmap.yaml b/bindata/configmaps/console-configmap.yaml new file mode 100644 index 0000000000..fd1beb1b88 --- /dev/null +++ b/bindata/configmaps/console-configmap.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: openshift-console + labels: + app: "console" + annotations: {} diff --git a/bindata/configmaps/console-managed-cluster-ingress-cert-configmap.yaml b/bindata/configmaps/console-managed-cluster-ingress-cert-configmap.yaml deleted file mode 100644 index f39c2d0e06..0000000000 --- a/bindata/configmaps/console-managed-cluster-ingress-cert-configmap.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: openshift-config-managed diff --git a/bindata/deployments/console-deployment.yaml b/bindata/deployments/console-deployment.yaml index 564bb98139..ed3701c32d 100644 --- a/bindata/deployments/console-deployment.yaml +++ b/bindata/deployments/console-deployment.yaml @@ -23,7 +23,7 @@ spec: target.workload.openshift.io/management: '{"effect": "PreferredDuringScheduling"}' spec: nodeSelector: - node-role.kubernetes.io/master: '' + node-role.kubernetes.io/master: "" restartPolicy: Always serviceAccountName: console schedulerName: default-scheduler @@ -49,13 +49,13 @@ spec: exec: command: - sleep - - '25' + - "25" name: console command: - /opt/bridge/bin/bridge - - '--public-dir=/opt/bridge/static' - - '--config=/var/console-config/console-config.yaml' - - '--service-ca-file=/var/service-ca/service-ca.crt' + - "--public-dir=/opt/bridge/static" + - "--config=/var/console-config/console-config.yaml" + - "--service-ca-file=/var/service-ca/service-ca.crt" livenessProbe: httpGet: path: /health diff --git a/bindata/managedclusteractions/console-managed-cluster-action-create-oauth-client.yaml b/bindata/managedclusteractions/console-create-oauth-client.yaml similarity index 59% rename from bindata/managedclusteractions/console-managed-cluster-action-create-oauth-client.yaml rename to bindata/managedclusteractions/console-create-oauth-client.yaml index 80a209a080..bd445b995a 100644 --- a/bindata/managedclusteractions/console-managed-cluster-action-create-oauth-client.yaml +++ b/bindata/managedclusteractions/console-create-oauth-client.yaml @@ -1,7 +1,5 @@ apiVersion: action.open-cluster-management.io/v1beta1 kind: ManagedClusterAction -metadata: - name: console-managed-cluster-action-oauth-create spec: actionType: Create kube: @@ -9,6 +7,4 @@ spec: template: apiVersion: oauth.openshift.io/v1 kind: OAuthClient - metadata: - name: console-managed-cluster-oauth-client - grantMethod: auto \ No newline at end of file + grantMethod: auto diff --git a/bindata/managedclusterviews/console-managed-cluster-view-oauth-client.yaml b/bindata/managedclusterviews/console-oauth-client.yaml similarity index 79% rename from bindata/managedclusterviews/console-managed-cluster-view-oauth-client.yaml rename to bindata/managedclusterviews/console-oauth-client.yaml index b4875bcc51..97b6476bc0 100644 --- a/bindata/managedclusterviews/console-managed-cluster-view-oauth-client.yaml +++ b/bindata/managedclusterviews/console-oauth-client.yaml @@ -1,7 +1,5 @@ apiVersion: view.open-cluster-management.io/v1beta1 kind: ManagedClusterView -metadata: - name: console-managed-cluster-view-oauth spec: scope: apiVersion: oauth.openshift.io/v1 diff --git a/bindata/managedclusterviews/console-managed-cluster-view-ingress-cert.yaml b/bindata/managedclusterviews/console-oauth-server-cert.yaml similarity index 76% rename from bindata/managedclusterviews/console-managed-cluster-view-ingress-cert.yaml rename to bindata/managedclusterviews/console-oauth-server-cert.yaml index c72a7e6117..91eda115c5 100644 --- a/bindata/managedclusterviews/console-managed-cluster-view-ingress-cert.yaml +++ b/bindata/managedclusterviews/console-oauth-server-cert.yaml @@ -1,7 +1,5 @@ apiVersion: view.open-cluster-management.io/v1beta1 kind: ManagedClusterView -metadata: - name: console-managed-cluster-view-ingress-cert spec: scope: kind: ConfigMap diff --git a/examples/cvo-unmanage-operator.yaml b/examples/cvo-unmanage-operator.yaml index bd6deb98ad..8e455fd6f4 100644 --- a/examples/cvo-unmanage-operator.yaml +++ b/examples/cvo-unmanage-operator.yaml @@ -9,4 +9,9 @@ spec: name: console-operator namespace: openshift-console-operator unmanaged: true - group: apps/v1 + group: apps + - kind: ClusterRole + name: console-operator + namespace: "" + unmanaged: true + group: rbac.authorization.k8s.io diff --git a/go.mod b/go.mod index 781dfb9ac1..2a282287e0 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/google/gofuzz v1.2.0 // indirect github.com/open-cluster-management/api v0.0.0-20210527013639-a6845f2ebcb1 github.com/openshift/api v0.0.0-20210729103544-e4a0474d1519 - github.com/openshift/build-machinery-go v0.0.0-20210712174854-1bb7fd1518d3 + github.com/openshift/build-machinery-go v0.0.0-20211213093930-7e33a7eb4ce3 github.com/openshift/client-go v0.0.0-20210112160336-8889f8b15bd6 github.com/openshift/library-go v0.0.0-20210330121117-68dd4a4c9d9e github.com/pkg/profile v1.4.0 // indirect diff --git a/go.sum b/go.sum index 6e12e09cdf..5cc0e6a5d4 100644 --- a/go.sum +++ b/go.sum @@ -421,8 +421,9 @@ github.com/openshift/api v0.0.0-20210729103544-e4a0474d1519 h1:g9hT0d7niFH2GD9NT github.com/openshift/api v0.0.0-20210729103544-e4a0474d1519/go.mod h1:wf/SnvIX5Aq1NkALk26b2extjOGm3Q781gEgvr0+CDY= github.com/openshift/build-machinery-go v0.0.0-20200917070002-f171684f77ab/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= github.com/openshift/build-machinery-go v0.0.0-20210115170933-e575b44a7a94/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= -github.com/openshift/build-machinery-go v0.0.0-20210712174854-1bb7fd1518d3 h1:hYMLjavR8LrcCva788SxDqYjRc1k2w0LNGi7eX9vY5Y= github.com/openshift/build-machinery-go v0.0.0-20210712174854-1bb7fd1518d3/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= +github.com/openshift/build-machinery-go v0.0.0-20211213093930-7e33a7eb4ce3 h1:65oBhJYHzYK5VL0gF1eiYY37lLzyLZ47b9y5Kib1nf8= +github.com/openshift/build-machinery-go v0.0.0-20211213093930-7e33a7eb4ce3/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= github.com/openshift/client-go v0.0.0-20201214125552-e615e336eb49/go.mod h1:9/jG4I6sh+5QublJpZZ4Zs/P4/QCXMsQQ/K/058bSB8= github.com/openshift/client-go v0.0.0-20210112160336-8889f8b15bd6 h1:nT3OoJhg9EO/sATO6oJFZkDmkNAq1ox4GJSp/rDcIqM= github.com/openshift/client-go v0.0.0-20210112160336-8889f8b15bd6/go.mod h1:u7NRAjtYVAKokiI9LouzTv4mhds8P4S1TwdVAfbjKSk= diff --git a/manifests/03-rbac-role-cluster.yaml b/manifests/03-rbac-role-cluster.yaml index c10bb6ba1e..c819abd4f0 100644 --- a/manifests/03-rbac-role-cluster.yaml +++ b/manifests/03-rbac-role-cluster.yaml @@ -21,23 +21,10 @@ rules: - apiGroups: - config.openshift.io resources: + - featuregates - oauths - verbs: - - get - - list - - watch - - apiGroups: - - config.openshift.io - resources: - infrastructures - ingresses - verbs: - - get - - list - - watch - - apiGroups: - - config.openshift.io - resources: - proxies verbs: - get @@ -88,28 +75,6 @@ rules: - get - list - watch - - apiGroups: - - action.open-cluster-management.io - resources: - - managedclusteractions - verbs: - - get - - list - - watch - - create - - update - - delete - - apiGroups: - - view.open-cluster-management.io - resources: - - managedclusterviews - verbs: - - get - - list - - watch - - create - - update - - delete --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 @@ -160,3 +125,34 @@ rules: verbs: - get - list +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: console-operator-tech-preview-only + annotations: + release.openshift.io/feature-gate: "TechPreviewNoUpgrade" + include.release.openshift.io/ibm-cloud-managed: "true" + include.release.openshift.io/self-managed-high-availability: "true" + include.release.openshift.io/single-node-developer: "true" +rules: + - apiGroups: + - action.open-cluster-management.io + resources: + - managedclusteractions + verbs: + - get + - list + - watch + - create + - delete + - apiGroups: + - view.open-cluster-management.io + resources: + - managedclusterviews + verbs: + - get + - list + - watch + - create + - delete diff --git a/manifests/04-rbac-rolebinding-cluster.yaml b/manifests/04-rbac-rolebinding-cluster.yaml index 8c326f2ed6..3263e8be59 100644 --- a/manifests/04-rbac-rolebinding-cluster.yaml +++ b/manifests/04-rbac-rolebinding-cluster.yaml @@ -28,9 +28,9 @@ roleRef: name: console-extensions-reader apiGroup: rbac.authorization.k8s.io subjects: -- kind: Group - name: system:authenticated - apiGroup: rbac.authorization.k8s.io + - kind: Group + name: system:authenticated + apiGroup: rbac.authorization.k8s.io --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding @@ -83,8 +83,26 @@ metadata: subjects: - kind: Group apiGroup: rbac.authorization.k8s.io - name: 'system:authenticated' + name: "system:authenticated" roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: helm-chartrepos-viewer +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: console-operator-tech-preview-only + annotations: + release.openshift.io/feature-gate: "TechPreviewNoUpgrade" + include.release.openshift.io/ibm-cloud-managed: "true" + include.release.openshift.io/self-managed-high-availability: "true" + include.release.openshift.io/single-node-developer: "true" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: console-operator-tech-preview-only +subjects: + - kind: ServiceAccount + name: console-operator + namespace: openshift-console-operator diff --git a/pkg/api/api.go b/pkg/api/api.go index ad934fc46f..89d6c5050e 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -1,5 +1,7 @@ package api +import "k8s.io/apimachinery/pkg/runtime/schema" + const ( TargetNamespace = "openshift-console" ConfigResourceName = "cluster" @@ -7,45 +9,57 @@ const ( // consts to maintain existing names of various sub-resources const ( - ClusterOperatorName = "console" - OpenShiftConsoleName = "console" - OpenShiftConsoleNamespace = TargetNamespace - OpenShiftConsoleOperatorNamespace = "openshift-console-operator" - OpenShiftConsoleOperator = "console-operator" - OpenShiftConsoleConfigMapName = "console-config" - OpenShiftConsolePublicConfigMapName = "console-public" - ServiceCAConfigMapName = "service-ca" - DefaultIngressCertConfigMapName = "default-ingress-cert" - OAuthServingCertConfigMapName = "oauth-serving-cert" - OAuthConfigMapName = "oauth-openshift" - OpenShiftConsoleDeploymentName = OpenShiftConsoleName - OpenShiftConsoleServiceName = OpenShiftConsoleName - OpenshiftConsoleRedirectServiceName = "console-redirect" - OpenShiftConsoleRouteName = OpenShiftConsoleName - OpenshiftConsoleCustomRouteName = "console-custom" - DownloadsResourceName = "downloads" - OpenShiftConsoleDownloadsRouteName = DownloadsResourceName - OpenShiftConsoleDownloadsDeploymentName = DownloadsResourceName - OAuthClientName = OpenShiftConsoleName - OpenShiftConfigManagedNamespace = "openshift-config-managed" - OpenShiftConfigNamespace = "openshift-config" - OpenShiftCustomLogoConfigMapName = "custom-logo" - TrustedCAConfigMapName = "trusted-ca-bundle" - TrustedCABundleKey = "ca-bundle.crt" - TrustedCABundleMountDir = "/etc/pki/ca-trust/extracted/pem" - TrustedCABundleMountFile = "tls-ca-bundle.pem" - OCCLIDownloadsCustomResourceName = "oc-cli-downloads" - ODOCLIDownloadsCustomResourceName = "odo-cli-downloads" - HubClusterName = "local-cluster" - ManagedClusterLabel = "managed-cluster" - ManagedClusterConfigMapName = "managed-clusters" - ManagedClusterConfigMountDir = "/var/managed-cluster-config" - ManagedClusterConfigKey = "managed-clusters.yaml" - ManagedClusterAPIServerCAMountDir = "/var/managed-cluster-certs" - ManagedClusterAPIServerCAName = "managed-cluster-api-server-ca" - ManagedClusterAPIServerCAKey = "ca-bundle.crt" - ManagedClusterIngressCertName = "managed-cluster-ingress-cert" - ManagedClusterIngressCertKey = "ca-bundle.crt" + ClusterOperatorName = "console" + OpenShiftConsoleName = "console" + OpenShiftConsoleNamespace = TargetNamespace + OpenShiftConsoleOperatorNamespace = "openshift-console-operator" + OpenShiftConsoleOperator = "console-operator" + OpenShiftConsoleConfigMapName = "console-config" + OpenShiftConsolePublicConfigMapName = "console-public" + ServiceCAConfigMapName = "service-ca" + DefaultIngressCertConfigMapName = "default-ingress-cert" + OAuthServingCertConfigMapName = "oauth-serving-cert" + OAuthConfigMapName = "oauth-openshift" + OpenShiftConsoleDeploymentName = OpenShiftConsoleName + OpenShiftConsoleServiceName = OpenShiftConsoleName + OpenshiftConsoleRedirectServiceName = "console-redirect" + OpenShiftConsoleRouteName = OpenShiftConsoleName + OpenshiftConsoleCustomRouteName = "console-custom" + DownloadsResourceName = "downloads" + OpenShiftConsoleDownloadsRouteName = DownloadsResourceName + OpenShiftConsoleDownloadsDeploymentName = DownloadsResourceName + OAuthClientName = OpenShiftConsoleName + OpenShiftConfigManagedNamespace = "openshift-config-managed" + OpenShiftConfigNamespace = "openshift-config" + OpenShiftCustomLogoConfigMapName = "custom-logo" + TrustedCAConfigMapName = "trusted-ca-bundle" + TrustedCABundleKey = "ca-bundle.crt" + TrustedCABundleMountDir = "/etc/pki/ca-trust/extracted/pem" + TrustedCABundleMountFile = "tls-ca-bundle.pem" + OCCLIDownloadsCustomResourceName = "oc-cli-downloads" + ODOCLIDownloadsCustomResourceName = "odo-cli-downloads" + HubClusterName = "local-cluster" + ManagedClusterLabel = "managed-cluster" + ManagedClusterConfigMapName = "managed-clusters" + ManagedClusterConfigMountDir = "/var/managed-cluster-config" + ManagedClusterConfigKey = "managed-clusters.yaml" + ManagedClusterAPIServerCertMountDir = "/var/managed-cluster-api-server-certs" + ManagedClusterAPIServerCertName = "managed-cluster-api-server-cert" + ManagedClusterAPIServerCertKey = "ca-bundle.crt" + ManagedClusterOAuthServerCertMountDir = "/var/managed-cluster-oauth-server-certs" + ManagedClusterOAuthServerCertName = "managed-cluster-oauth-server-cert" + ManagedClusterOAuthServerCertKey = "ca-bundle.crt" + ManagedClusterOAuthClientName = "console-managed-cluster-oauth-client" + OAuthClientManagedClusterViewName = "console-oauth-client" + CreateOAuthClientManagedClusterActionName = "console-create-oauth-client" + OAuthServerCertManagedClusterViewName = "console-oauth-server-cert" + + ManagedClusterViewAPIGroup = "view.open-cluster-management.io" + ManagedClusterViewAPIVersion = "v1beta1" + ManagedClusterViewResource = "managedclusterviews" + ManagedClusterActionAPIGroup = "action.open-cluster-management.io" + ManagedClusterActionAPIVersion = "v1beta1" + ManagedClusterActionResource = "managedclusteractions" ConsoleContainerPortName = "https" ConsoleContainerPort = 443 @@ -57,3 +71,16 @@ const ( DownloadsPortName = "http" DownloadsPort = 8080 ) + +var ( + ManagedClusterViewGroupVersionResource = schema.GroupVersionResource{ + Group: ManagedClusterViewAPIGroup, + Version: ManagedClusterViewAPIVersion, + Resource: ManagedClusterViewResource, + } + ManagedClusterActionGroupVersionResource = schema.GroupVersionResource{ + Group: ManagedClusterActionAPIGroup, + Version: ManagedClusterActionAPIVersion, + Resource: ManagedClusterActionResource, + } +) diff --git a/pkg/console/assets/bindata.go b/pkg/console/assets/bindata.go index afe47c5490..73c551da61 100644 --- a/pkg/console/assets/bindata.go +++ b/pkg/console/assets/bindata.go @@ -1,12 +1,12 @@ // Code generated for package assets by go-bindata DO NOT EDIT. (@generated) // sources: -// bindata/configmaps/console-managed-cluster-ingress-cert-configmap.yaml +// bindata/configmaps/console-configmap.yaml // bindata/configmaps/console-public-configmap.yaml // bindata/deployments/console-deployment.yaml // bindata/deployments/downloads-deployment.yaml -// bindata/managedclusteractions/console-managed-cluster-action-create-oauth-client.yaml -// bindata/managedclusterviews/console-managed-cluster-view-ingress-cert.yaml -// bindata/managedclusterviews/console-managed-cluster-view-oauth-client.yaml +// bindata/managedclusteractions/console-create-oauth-client.yaml +// bindata/managedclusterviews/console-oauth-client.yaml +// bindata/managedclusterviews/console-oauth-server-cert.yaml // bindata/routes/console-custom-route.yaml // bindata/routes/console-redirect-route.yaml // bindata/routes/console-route.yaml @@ -68,23 +68,26 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _configmapsConsoleManagedClusterIngressCertConfigmapYaml = []byte(`apiVersion: v1 +var _configmapsConsoleConfigmapYaml = []byte(`apiVersion: v1 kind: ConfigMap metadata: - namespace: openshift-config-managed + namespace: openshift-console + labels: + app: "console" + annotations: {} `) -func configmapsConsoleManagedClusterIngressCertConfigmapYamlBytes() ([]byte, error) { - return _configmapsConsoleManagedClusterIngressCertConfigmapYaml, nil +func configmapsConsoleConfigmapYamlBytes() ([]byte, error) { + return _configmapsConsoleConfigmapYaml, nil } -func configmapsConsoleManagedClusterIngressCertConfigmapYaml() (*asset, error) { - bytes, err := configmapsConsoleManagedClusterIngressCertConfigmapYamlBytes() +func configmapsConsoleConfigmapYaml() (*asset, error) { + bytes, err := configmapsConsoleConfigmapYamlBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "configmaps/console-managed-cluster-ingress-cert-configmap.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + info := bindataFileInfo{name: "configmaps/console-configmap.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -138,7 +141,7 @@ spec: target.workload.openshift.io/management: '{"effect": "PreferredDuringScheduling"}' spec: nodeSelector: - node-role.kubernetes.io/master: '' + node-role.kubernetes.io/master: "" restartPolicy: Always serviceAccountName: console schedulerName: default-scheduler @@ -164,13 +167,13 @@ spec: exec: command: - sleep - - '25' + - "25" name: console command: - /opt/bridge/bin/bridge - - '--public-dir=/opt/bridge/static' - - '--config=/var/console-config/console-config.yaml' - - '--service-ca-file=/var/service-ca/service-ca.crt' + - "--public-dir=/opt/bridge/static" + - "--config=/var/console-config/console-config.yaml" + - "--service-ca-file=/var/service-ca/service-ca.crt" livenessProbe: httpGet: path: /health @@ -427,10 +430,8 @@ func deploymentsDownloadsDeploymentYaml() (*asset, error) { return a, nil } -var _managedclusteractionsConsoleManagedClusterActionCreateOauthClientYaml = []byte(`apiVersion: action.open-cluster-management.io/v1beta1 +var _managedclusteractionsConsoleCreateOauthClientYaml = []byte(`apiVersion: action.open-cluster-management.io/v1beta1 kind: ManagedClusterAction -metadata: - name: console-managed-cluster-action-oauth-create spec: actionType: Create kube: @@ -438,74 +439,69 @@ spec: template: apiVersion: oauth.openshift.io/v1 kind: OAuthClient - metadata: - name: console-managed-cluster-oauth-client - grantMethod: auto`) + grantMethod: auto +`) -func managedclusteractionsConsoleManagedClusterActionCreateOauthClientYamlBytes() ([]byte, error) { - return _managedclusteractionsConsoleManagedClusterActionCreateOauthClientYaml, nil +func managedclusteractionsConsoleCreateOauthClientYamlBytes() ([]byte, error) { + return _managedclusteractionsConsoleCreateOauthClientYaml, nil } -func managedclusteractionsConsoleManagedClusterActionCreateOauthClientYaml() (*asset, error) { - bytes, err := managedclusteractionsConsoleManagedClusterActionCreateOauthClientYamlBytes() +func managedclusteractionsConsoleCreateOauthClientYaml() (*asset, error) { + bytes, err := managedclusteractionsConsoleCreateOauthClientYamlBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "managedclusteractions/console-managed-cluster-action-create-oauth-client.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + info := bindataFileInfo{name: "managedclusteractions/console-create-oauth-client.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _managedclusterviewsConsoleManagedClusterViewIngressCertYaml = []byte(`apiVersion: view.open-cluster-management.io/v1beta1 +var _managedclusterviewsConsoleOauthClientYaml = []byte(`apiVersion: view.open-cluster-management.io/v1beta1 kind: ManagedClusterView -metadata: - name: console-managed-cluster-view-ingress-cert spec: scope: - kind: ConfigMap - version: v1 - name: default-ingress-cert - namespace: openshift-config-managed + apiVersion: oauth.openshift.io/v1 + resource: OAuthClient + name: console-managed-cluster-oauth-client `) -func managedclusterviewsConsoleManagedClusterViewIngressCertYamlBytes() ([]byte, error) { - return _managedclusterviewsConsoleManagedClusterViewIngressCertYaml, nil +func managedclusterviewsConsoleOauthClientYamlBytes() ([]byte, error) { + return _managedclusterviewsConsoleOauthClientYaml, nil } -func managedclusterviewsConsoleManagedClusterViewIngressCertYaml() (*asset, error) { - bytes, err := managedclusterviewsConsoleManagedClusterViewIngressCertYamlBytes() +func managedclusterviewsConsoleOauthClientYaml() (*asset, error) { + bytes, err := managedclusterviewsConsoleOauthClientYamlBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "managedclusterviews/console-managed-cluster-view-ingress-cert.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + info := bindataFileInfo{name: "managedclusterviews/console-oauth-client.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _managedclusterviewsConsoleManagedClusterViewOauthClientYaml = []byte(`apiVersion: view.open-cluster-management.io/v1beta1 +var _managedclusterviewsConsoleOauthServerCertYaml = []byte(`apiVersion: view.open-cluster-management.io/v1beta1 kind: ManagedClusterView -metadata: - name: console-managed-cluster-view-oauth spec: scope: - apiVersion: oauth.openshift.io/v1 - resource: OAuthClient - name: console-managed-cluster-oauth-client + kind: ConfigMap + version: v1 + name: default-ingress-cert + namespace: openshift-config-managed `) -func managedclusterviewsConsoleManagedClusterViewOauthClientYamlBytes() ([]byte, error) { - return _managedclusterviewsConsoleManagedClusterViewOauthClientYaml, nil +func managedclusterviewsConsoleOauthServerCertYamlBytes() ([]byte, error) { + return _managedclusterviewsConsoleOauthServerCertYaml, nil } -func managedclusterviewsConsoleManagedClusterViewOauthClientYaml() (*asset, error) { - bytes, err := managedclusterviewsConsoleManagedClusterViewOauthClientYamlBytes() +func managedclusterviewsConsoleOauthServerCertYaml() (*asset, error) { + bytes, err := managedclusterviewsConsoleOauthServerCertYamlBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "managedclusterviews/console-managed-cluster-view-oauth-client.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + info := bindataFileInfo{name: "managedclusterviews/console-oauth-server-cert.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -865,21 +861,21 @@ func AssetNames() []string { // _bindata is a table, holding each asset generator, mapped to its name. var _bindata = map[string]func() (*asset, error){ - "configmaps/console-managed-cluster-ingress-cert-configmap.yaml": configmapsConsoleManagedClusterIngressCertConfigmapYaml, - "configmaps/console-public-configmap.yaml": configmapsConsolePublicConfigmapYaml, - "deployments/console-deployment.yaml": deploymentsConsoleDeploymentYaml, - "deployments/downloads-deployment.yaml": deploymentsDownloadsDeploymentYaml, - "managedclusteractions/console-managed-cluster-action-create-oauth-client.yaml": managedclusteractionsConsoleManagedClusterActionCreateOauthClientYaml, - "managedclusterviews/console-managed-cluster-view-ingress-cert.yaml": managedclusterviewsConsoleManagedClusterViewIngressCertYaml, - "managedclusterviews/console-managed-cluster-view-oauth-client.yaml": managedclusterviewsConsoleManagedClusterViewOauthClientYaml, - "routes/console-custom-route.yaml": routesConsoleCustomRouteYaml, - "routes/console-redirect-route.yaml": routesConsoleRedirectRouteYaml, - "routes/console-route.yaml": routesConsoleRouteYaml, - "routes/downloads-custom-route.yaml": routesDownloadsCustomRouteYaml, - "routes/downloads-route.yaml": routesDownloadsRouteYaml, - "services/console-redirect-service.yaml": servicesConsoleRedirectServiceYaml, - "services/console-service.yaml": servicesConsoleServiceYaml, - "services/downloads-service.yaml": servicesDownloadsServiceYaml, + "configmaps/console-configmap.yaml": configmapsConsoleConfigmapYaml, + "configmaps/console-public-configmap.yaml": configmapsConsolePublicConfigmapYaml, + "deployments/console-deployment.yaml": deploymentsConsoleDeploymentYaml, + "deployments/downloads-deployment.yaml": deploymentsDownloadsDeploymentYaml, + "managedclusteractions/console-create-oauth-client.yaml": managedclusteractionsConsoleCreateOauthClientYaml, + "managedclusterviews/console-oauth-client.yaml": managedclusterviewsConsoleOauthClientYaml, + "managedclusterviews/console-oauth-server-cert.yaml": managedclusterviewsConsoleOauthServerCertYaml, + "routes/console-custom-route.yaml": routesConsoleCustomRouteYaml, + "routes/console-redirect-route.yaml": routesConsoleRedirectRouteYaml, + "routes/console-route.yaml": routesConsoleRouteYaml, + "routes/downloads-custom-route.yaml": routesDownloadsCustomRouteYaml, + "routes/downloads-route.yaml": routesDownloadsRouteYaml, + "services/console-redirect-service.yaml": servicesConsoleRedirectServiceYaml, + "services/console-service.yaml": servicesConsoleServiceYaml, + "services/downloads-service.yaml": servicesDownloadsServiceYaml, } // AssetDir returns the file names below a certain @@ -924,19 +920,19 @@ type bintree struct { var _bintree = &bintree{nil, map[string]*bintree{ "configmaps": {nil, map[string]*bintree{ - "console-managed-cluster-ingress-cert-configmap.yaml": {configmapsConsoleManagedClusterIngressCertConfigmapYaml, map[string]*bintree{}}, - "console-public-configmap.yaml": {configmapsConsolePublicConfigmapYaml, map[string]*bintree{}}, + "console-configmap.yaml": {configmapsConsoleConfigmapYaml, map[string]*bintree{}}, + "console-public-configmap.yaml": {configmapsConsolePublicConfigmapYaml, map[string]*bintree{}}, }}, "deployments": {nil, map[string]*bintree{ "console-deployment.yaml": {deploymentsConsoleDeploymentYaml, map[string]*bintree{}}, "downloads-deployment.yaml": {deploymentsDownloadsDeploymentYaml, map[string]*bintree{}}, }}, "managedclusteractions": {nil, map[string]*bintree{ - "console-managed-cluster-action-create-oauth-client.yaml": {managedclusteractionsConsoleManagedClusterActionCreateOauthClientYaml, map[string]*bintree{}}, + "console-create-oauth-client.yaml": {managedclusteractionsConsoleCreateOauthClientYaml, map[string]*bintree{}}, }}, "managedclusterviews": {nil, map[string]*bintree{ - "console-managed-cluster-view-ingress-cert.yaml": {managedclusterviewsConsoleManagedClusterViewIngressCertYaml, map[string]*bintree{}}, - "console-managed-cluster-view-oauth-client.yaml": {managedclusterviewsConsoleManagedClusterViewOauthClientYaml, map[string]*bintree{}}, + "console-oauth-client.yaml": {managedclusterviewsConsoleOauthClientYaml, map[string]*bintree{}}, + "console-oauth-server-cert.yaml": {managedclusterviewsConsoleOauthServerCertYaml, map[string]*bintree{}}, }}, "routes": {nil, map[string]*bintree{ "console-custom-route.yaml": {routesConsoleCustomRouteYaml, map[string]*bintree{}}, diff --git a/pkg/console/controllers/managedclusters/controller.go b/pkg/console/controllers/managedclusters/controller.go index c94ee800fb..b79338ab4e 100644 --- a/pkg/console/controllers/managedclusters/controller.go +++ b/pkg/console/controllers/managedclusters/controller.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "strings" + "time" // k8s apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -19,6 +20,7 @@ import ( clusterclientv1 "github.com/open-cluster-management/api/client/cluster/clientset/versioned/typed/cluster/v1" clusterinformersv1 "github.com/open-cluster-management/api/client/cluster/informers/externalversions/cluster/v1" clusterv1 "github.com/open-cluster-management/api/cluster/v1" + oauthv1 "github.com/openshift/api/oauth/v1" operatorv1 "github.com/openshift/api/operator/v1" configclientv1 "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1" configinformer "github.com/openshift/client-go/config/informers/externalversions" @@ -35,7 +37,6 @@ import ( managedclusteractionsub "github.com/openshift/console-operator/pkg/console/subresource/managedclusteraction" managedclusterviewsub "github.com/openshift/console-operator/pkg/console/subresource/managedclusterview" oauthsub "github.com/openshift/console-operator/pkg/console/subresource/oauthclient" - secretsub "github.com/openshift/console-operator/pkg/console/subresource/secret" // console-operator "github.com/openshift/console-operator/pkg/api" @@ -47,6 +48,7 @@ import ( type ManagedClusterController struct { operatorClient v1helpers.OperatorClient operatorConfigClient operatorclientv1.ConsoleInterface + featureGateClient configclientv1.FeatureGateInterface configMapClient coreclientv1.ConfigMapsGetter managedClusterClient clusterclientv1.ManagedClustersGetter dynamicClient dynamic.Interface @@ -79,6 +81,7 @@ func NewManagedClusterController( ctrl := &ManagedClusterController{ operatorClient: operatorClient, operatorConfigClient: operatorConfigClient, + featureGateClient: configClient.FeatureGates(), configMapClient: configMapClient, managedClusterClient: managedClusterClient, dynamicClient: dynamicClient, @@ -93,18 +96,28 @@ func NewManagedClusterController( util.IncludeNamesFilter(api.ConfigResourceName), configV1Informers.Consoles().Informer(), operatorConfigInformer.Informer(), - ).WithFilteredEventsInformers( - util.ExcludeNamesFilter(api.HubClusterName), - managedClusterInformers.Informer(), - ).WithInformers( - dynamicInformers.ForResource(managedclusteractionsub.GetGroupVersionResource()).Informer(), - ).WithInformers( - dynamicInformers.ForResource(managedclusterviewsub.GetGroupVersionResource()).Informer(), - ).WithSync(ctrl.Sync). + configV1Informers.FeatureGates().Informer(), + ).ResyncEvery(1*time.Minute).WithSync(ctrl.Sync). ToController("ManagedClusterController", recorder.WithComponentSuffix("managed-cluster-controller")) } func (c *ManagedClusterController) Sync(ctx context.Context, controllerContext factory.SyncContext) error { + + // Get cluster FeatureGate config + featureGateConfig, err := c.featureGateClient.Get(ctx, api.ConfigResourceName, metav1.GetOptions{}) + if err != nil { + klog.Errorf("Error getting FeatureGate config: %v", err) + return nil + } + + // Check that the "TechPreviewNoUpgrade" feature set is configured, else exit the sync loop + featureSet := string(featureGateConfig.Spec.FeatureSet) + if featureSet == "" || !strings.Contains(featureSet, "TechPreviewNoUpgrade") { + return nil + } + + klog.V(4).Info("Tech preview is enabled. Running managed cluster sync") + operatorConfig, err := c.operatorConfigClient.Get(ctx, api.ConfigResourceName, metav1.GetOptions{}) if err != nil { return err @@ -125,56 +138,72 @@ func (c *ManagedClusterController) Sync(ctx context.Context, controllerContext f statusHandler := status.NewStatusHandler(c.operatorClient) - managedClusters, err := c.listManagedClusters(ctx) - // Not found means API is not on the cluster - if apierrors.IsNotFound(err) || err != nil { - return err - } - - // Get a list of ManagedCluster resources, degraded if error is returned - managedClusterClientConfigs, managedClusterClientConfigValidationErr, managedClusterClientConfigValidationErrReason := c.ValidateManagedClusterClientConfigs(ctx, operatorConfig, controllerContext.Recorder(), managedClusters) - statusHandler.AddConditions(status.HandleProgressingOrDegraded("ManagedClusterValidation", managedClusterClientConfigValidationErrReason, managedClusterClientConfigValidationErr)) - if managedClusterClientConfigValidationErr != nil { - return statusHandler.FlushAndReturn(managedClusterClientConfigValidationErr) - } - - // No managed clusters exist, quit sync - if len(managedClusterClientConfigs) == 0 { - return statusHandler.FlushAndReturn(nil) + // Get the local OAuthClient. If this fails, do not proceed. We can't create OAuth clients on + // managed clusters without the local client. + localOAuthClient, errReason, err := c.SyncLocalOAuthClient(ctx) + statusHandler.AddConditions(status.HandleProgressingOrDegraded("ManagedClusterSync", errReason, err)) + if err != nil { + return c.removeManagedClusters(ctx) } - // Create config maps for each managed cluster API server ca bundle - apiServerCASyncErr, apiServerCASyncErrReason := c.SyncAPIServerCAConfigMaps(managedClusterClientConfigs, ctx, operatorConfig, controllerContext.Recorder()) - statusHandler.AddConditions(status.HandleProgressingOrDegraded("ManagedClusterAPIServerCASync", apiServerCASyncErrReason, apiServerCASyncErr)) - if apiServerCASyncErr != nil { - return statusHandler.FlushAndReturn(apiServerCASyncErr) + // Get a list of validated ManagedCluster resources + managedClusters, errReason, err := c.SyncManagedClusterList(ctx) + statusHandler.AddConditions(status.HandleProgressingOrDegraded("ManagedClusterSync", errReason, err)) + if err != nil || len(managedClusters) == 0 { + return c.removeManagedClusters(ctx) } // Create managed cluster views for oauth clients - managedClusterViewOAuthClients, managedClusterViewOAuthClientErr, managedClusterViewOAuthClientErrReason := c.SyncManagedClusterViewOAuthClient(ctx, operatorConfig, managedClusters) - statusHandler.AddConditions(status.HandleProgressingOrDegraded("ManagedClusterViewOAuthClientSync", managedClusterViewOAuthClientErrReason, managedClusterViewOAuthClientErr)) + oAuthClientMCVs, errReason, err := c.SyncOAuthClientManagedClusterViews(ctx, operatorConfig, managedClusters) + statusHandler.AddConditions(status.HandleProgressingOrDegraded("ManagedClusterSync", errReason, err)) // Create managed cluster actions for oauth clients - _, managedClusterActionCreateOAuthClientErr, managedClusterActionCreateOAuthClientErrReason := c.SyncManagedClusterActionCreateOAuthClient(ctx, operatorConfig, managedClusterViewOAuthClients) - statusHandler.AddConditions(status.HandleProgressingOrDegraded("ManagedClusterActionCreateOAuthClientSync", managedClusterActionCreateOAuthClientErrReason, managedClusterActionCreateOAuthClientErr)) + errReason, err = c.SyncOAuthClientCreationManagedClusterActions(ctx, operatorConfig, localOAuthClient, oAuthClientMCVs) + statusHandler.AddConditions(status.HandleProgressingOrDegraded("ManagedClusterSync", errReason, err)) // Create managed cluster views for ingress cert - managedClusterViewsIngressCert, managedClusterViewIngressCertErr, managedClusterViewIngressCertErrReason := c.SyncManagedClusterViewIngressCert(ctx, operatorConfig, managedClusters) - statusHandler.AddConditions(status.HandleProgressingOrDegraded("ManagedClusterViewIngressCertSync", managedClusterViewIngressCertErrReason, managedClusterViewIngressCertErr)) + oAuthServerCertMCVs, errReason, err := c.SyncOAuthServerCertManagedClusterViews(ctx, operatorConfig, managedClusters) + statusHandler.AddConditions(status.HandleProgressingOrDegraded("ManagedClusterSync", errReason, err)) // Create config maps for each managed cluster ingress cert bundle - managedClusterIngressCertSyncErr, managedClusterIngressCertSyncErrReason := c.SyncManagedClusterIngressCertConfigMap(managedClusterViewsIngressCert, ctx, operatorConfig, controllerContext.Recorder()) - statusHandler.AddConditions(status.HandleProgressingOrDegraded("ManagedClusterIngressCertConfigMapSync", managedClusterIngressCertSyncErrReason, managedClusterIngressCertSyncErr)) + errReason, err = c.SyncOAuthServerCertConfigMaps(oAuthServerCertMCVs, ctx, operatorConfig, controllerContext.Recorder()) + statusHandler.AddConditions(status.HandleProgressingOrDegraded("ManagedClusterSync", errReason, err)) + + // Create config maps for each managed cluster API server ca bundle + errReason, err = c.SyncAPIServerCertConfigMaps(managedClusters, ctx, operatorConfig, controllerContext.Recorder()) + statusHandler.AddConditions(status.HandleProgressingOrDegraded("ManagedClusterSync", errReason, err)) + if err != nil { + return statusHandler.FlushAndReturn(err) + } // Create manged cluster config map - configSyncErr, configSyncErrReason := c.SyncManagedClusterConfigMap(managedClusterClientConfigs, ctx, operatorConfig, controllerContext.Recorder()) - statusHandler.AddConditions(status.HandleProgressingOrDegraded("ManagedClusterConfigSync", configSyncErrReason, configSyncErr)) - return statusHandler.FlushAndReturn(configSyncErr) + errReason, err = c.SyncManagedClusterConfigMap(managedClusters, ctx, operatorConfig, controllerContext.Recorder()) + statusHandler.AddConditions(status.HandleProgressingOrDegraded("ManagedClusterSync", errReason, err)) + return statusHandler.FlushAndReturn(err) +} + +func (c *ManagedClusterController) SyncLocalOAuthClient(ctx context.Context) (*oauthv1.OAuthClient, string, error) { + oAuthClient, oAuthErr := c.oauthClient.OAuthClients().Get(ctx, oauthsub.Stub().Name, metav1.GetOptions{}) + if oAuthErr != nil { + return nil, "LocalOAuthClientSyncError", fmt.Errorf("Failed to get oauth client: %v", oAuthErr) + } + + return oAuthClient, "", nil } -// Return slice of clusterv1.ClientConfigs that have been validated or error and reaons if unable to list ManagedClusters -func (c *ManagedClusterController) ValidateManagedClusterClientConfigs(ctx context.Context, operatorConfig *operatorv1.Console, recorder events.Recorder, managedClusters *clusterv1.ManagedClusterList) (map[string]*clusterv1.ClientConfig, error, string) { - validatedClientConfigs := map[string]*clusterv1.ClientConfig{} +func (c *ManagedClusterController) SyncManagedClusterList(ctx context.Context) ([]clusterv1.ManagedCluster, string, error) { + managedClusters, err := c.managedClusterClient.ManagedClusters().List(ctx, metav1.ListOptions{LabelSelector: fmt.Sprintf("local-cluster!=true")}) + + // Not degraded, API is not found which means ACM isn't installed + if apierrors.IsNotFound(err) { + return nil, "", nil + } + + if err != nil { + return nil, "ErrorListingManagedClusters", err + } + + valid := []clusterv1.ManagedCluster{} for _, managedCluster := range managedClusters.Items { clusterName := managedCluster.GetName() @@ -197,20 +226,149 @@ func (c *ManagedClusterController) ValidateManagedClusterClientConfigs(ctx conte continue } - validatedClientConfigs[clusterName] = &clientConfigs[0] + valid = append(valid, managedCluster) + } + + return valid, "", nil +} + +func (c *ManagedClusterController) SyncOAuthClientManagedClusterViews(ctx context.Context, operatorConfig *operatorv1.Console, managedClusters []clusterv1.ManagedCluster) ([]*unstructured.Unstructured, string, error) { + errs := []string{} + mcvs := []*unstructured.Unstructured{} + for _, managedCluster := range managedClusters { + mcv, err := c.dynamicClient.Resource(api.ManagedClusterViewGroupVersionResource).Namespace(managedCluster.Name).Get(ctx, api.OAuthClientManagedClusterViewName, metav1.GetOptions{}) + if apierrors.IsNotFound(err) { + required, err := managedclusterviewsub.DefaultOAuthClientView(managedCluster.Name) + if err != nil { + errs = append(errs, fmt.Sprintf("Error initializing oauth client ManagedClusterView for cluster %s: %v", managedCluster.Name, err)) + continue + } + mcv, err = c.dynamicClient.Resource(api.ManagedClusterViewGroupVersionResource).Namespace(managedCluster.Name).Create(ctx, required, metav1.CreateOptions{}) + } + + if err != nil || mcv == nil { + errs = append(errs, fmt.Sprintf("Error syncing managed cluster view for oauth client for cluster %s: %v", managedCluster.Name, err)) + } else { + mcvs = append(mcvs, mcv) + } + } + + if len(errs) > 0 { + return nil, "ManagedClusterViewOAuthClientSyncError", errors.New(strings.Join(errs, "\n")) + } + + return mcvs, "", nil +} + +func (c *ManagedClusterController) SyncOAuthClientCreationManagedClusterActions(ctx context.Context, operatorConfig *operatorv1.Console, localOAuthClient *oauthv1.OAuthClient, oAuthClientMCVs []*unstructured.Unstructured) (string, error) { + managedClusterList := []string{} + managedClusterListErrors := []string{} + for _, managedClusterOAuthView := range oAuthClientMCVs { + status, statusErr := managedclusterviewsub.GetStatus(managedClusterOAuthView) + if !status || statusErr != nil { + namespace, namespaceErr := managedclusterviewsub.GetNamespace(managedClusterOAuthView) + if namespaceErr != nil || namespace == "" { + managedClusterListErrors = append(managedClusterListErrors, fmt.Sprintf("Unable to create oauth client for cluster %v: managed cluster view status unknown", namespace)) + } else { + managedClusterList = append(managedClusterList, namespace) + } + } + } + + errs := []string{} + secretString := oauthsub.GetSecretString(localOAuthClient) + redirects := oauthsub.GetRedirectURIs(localOAuthClient) + for _, managedClusterName := range managedClusterList { + _, err := c.dynamicClient.Resource(api.ManagedClusterActionGroupVersionResource).Namespace(managedClusterName).Get(ctx, api.CreateOAuthClientManagedClusterActionName, metav1.GetOptions{}) + if apierrors.IsNotFound(err) { + required, err := managedclusteractionsub.DefaultCreateOAuthClientAction(managedClusterName, secretString, redirects) + if err != nil { + errs = append(errs, fmt.Sprintf("Error initializing oauth client ManagedClusterAction for cluster %s: %v", managedClusterName, err)) + continue + } + _, err = c.dynamicClient.Resource(api.ManagedClusterActionGroupVersionResource).Namespace(managedClusterName).Create(ctx, required, metav1.CreateOptions{}) + } + + if err != nil { + errs = append(errs, fmt.Sprintf("Error syncing managed cluster action for oauth client for cluster %s: %v", managedClusterName, err)) + } + } + + if len(errs) > 0 { + return "ManagedClusterActionCreateOAuthClientSyncError", errors.New(strings.Join(errs, "\n")) + } + + if len(managedClusterListErrors) > 0 { + return "ManagedClusterActionCreateOAuthClientSyncError", errors.New(strings.Join(managedClusterListErrors, "\n")) + } + + return "", nil +} + +func (c *ManagedClusterController) SyncOAuthServerCertManagedClusterViews(ctx context.Context, operatorConfig *operatorv1.Console, managedClusters []clusterv1.ManagedCluster) ([]*unstructured.Unstructured, string, error) { + errs := []string{} + mcvs := []*unstructured.Unstructured{} + for _, managedCluster := range managedClusters { + mcv, err := c.dynamicClient.Resource(api.ManagedClusterViewGroupVersionResource).Namespace(managedCluster.Name).Get(ctx, api.OAuthServerCertManagedClusterViewName, metav1.GetOptions{}) + if apierrors.IsNotFound(err) { + required, err := managedclusterviewsub.DefaultOAuthServerCertView(operatorConfig, managedCluster.Name) + if err != nil { + errs = append(errs, fmt.Sprintf("Error initializing oauth server cert ManagedClusterView for cluster %s: %v", managedCluster.Name, err)) + continue + } + mcv, err = c.dynamicClient.Resource(api.ManagedClusterViewGroupVersionResource).Namespace(managedCluster.Name).Create(ctx, required, metav1.CreateOptions{}) + } + + if err != nil || mcv == nil { + errs = append(errs, fmt.Sprintf("Error syncing oauth server cert ManagedClusterView for cluster %s: %v", managedCluster.Name, err)) + } else { + mcvs = append(mcvs, mcv) + } + } + + if len(errs) > 0 { + return nil, "OAuthServerCertManagedClusterViewSyncError", errors.New(strings.Join(errs, "\n")) + } + + return mcvs, "", nil +} + +func (c *ManagedClusterController) SyncOAuthServerCertConfigMaps(oAuthServerCertMCVs []*unstructured.Unstructured, ctx context.Context, operatorConfig *operatorv1.Console, recorder events.Recorder) (string, error) { + errs := []string{} + for _, oAuthServerCertMCV := range oAuthServerCertMCVs { + clusterName, _ := managedclusterviewsub.GetNamespace(oAuthServerCertMCV) + certBundle, _ := managedclusterviewsub.GetCertBundle(oAuthServerCertMCV) + if certBundle == "" { + klog.V(4).Infoln(fmt.Sprintf("Skipping OAuth server certificate ConfigMap sync for managed cluster %v, cert bundle is empty", clusterName)) + continue + } + + required := configmapsub.DefaultManagedClusterOAuthServerCertConfigMap(clusterName, certBundle, operatorConfig) + _, _, configMapApplyError := resourceapply.ApplyConfigMap(c.configMapClient, recorder, required) + if configMapApplyError != nil { + klog.V(4).Infoln(fmt.Sprintf("Skipping OAuth server certificate ConfigMap sync for managed cluster %v, Error applying ConfigMap", clusterName)) + errs = append(errs, configMapApplyError.Error()) + continue + } } - return validatedClientConfigs, nil, "" + if len(errs) > 0 { + return "ManagedClusterIngressCertConfigMapSyncError", errors.New(strings.Join(errs, "\n")) + } + + return "", nil } // Using ManagedCluster.spec.ManagedClusterClientConfigs, sync ConfigMaps containing the API server CA bundle for each managed cluster // If a managed cluster doesn't have complete client config yet, the information is logged, but no error is returned // If applying any ConfigMap fails, an error and reason are returned -func (c *ManagedClusterController) SyncAPIServerCAConfigMaps(clientConfigs map[string]*clusterv1.ClientConfig, ctx context.Context, operatorConfig *operatorv1.Console, recorder events.Recorder) (error, string) { +func (c *ManagedClusterController) SyncAPIServerCertConfigMaps(managedClusters []clusterv1.ManagedCluster, ctx context.Context, operatorConfig *operatorv1.Console, recorder events.Recorder) (string, error) { errs := []string{} - for clusterName, clientConfig := range clientConfigs { + for _, managedCluster := range managedClusters { // Apply the config map. If this fails for any managed cluster, operator is degraded - required := configmapsub.DefaultAPIServerCAConfigMap(clusterName, clientConfig.CABundle, operatorConfig) + clusterName := managedCluster.GetName() + caBundle := managedCluster.Spec.ManagedClusterClientConfigs[0].CABundle + required := configmapsub.DefaultAPIServerCAConfigMap(managedCluster.GetName(), caBundle, operatorConfig) _, _, configMapApplyError := resourceapply.ApplyConfigMap(c.configMapClient, recorder, required) if configMapApplyError != nil { klog.V(4).Infoln(fmt.Sprintf("Skipping API server CA ConfigMap sync for managed cluster %v, Error applying ConfigMap", clusterName)) @@ -221,39 +379,77 @@ func (c *ManagedClusterController) SyncAPIServerCAConfigMaps(clientConfigs map[s // Return any apply errors that occurred if len(errs) > 0 { - return errors.New(strings.Join(errs, "\n")), "APIServerCAConfigMapSyncError" + return "APIServerCAConfigMapSyncError", errors.New(strings.Join(errs, "\n")) } // Success - return nil, "" + return "", nil } // Using ManagedClusters.Spec.ManagedClusterClientConfigs and previously synced CA bundles, sync a ConfigMap containing serverconfig.ManagedClusterConfig YAML for each managed cluster // If a managed cluster doesn't have an API server CA bundle ConfigMap yet or the client config is incomplete, this is logged, but no error is returned // If applying the ConfigMap fails, an error and reason are returned -func (c *ManagedClusterController) SyncManagedClusterConfigMap(clientConfigs map[string]*clusterv1.ClientConfig, ctx context.Context, operatorConfig *operatorv1.Console, recorder events.Recorder) (error, string) { +func (c *ManagedClusterController) SyncManagedClusterConfigMap(managedClusters []clusterv1.ManagedCluster, ctx context.Context, operatorConfig *operatorv1.Console, recorder events.Recorder) (string, error) { managedClusterConfigs := []consoleserver.ManagedClusterConfig{} - for clusterName, clientConfig := range clientConfigs { + for _, managedCluster := range managedClusters { + clusterName := managedCluster.GetName() klog.V(4).Infoln(fmt.Sprintf("Building config for managed cluster: %v", clusterName)) - // Check that managed cluster CA ConfigMap has already been synced, skip if not found + // Check that managed cluster API server CA ConfigMap has already been synced, skip if not found _, err := c.configMapClient.ConfigMaps(api.OpenShiftConsoleNamespace).Get(ctx, configmapsub.APIServerCAConfigMapName(clusterName), metav1.GetOptions{}) if apierrors.IsNotFound(err) { - klog.V(4).Infof("CA file not found for managed cluster %v", clusterName) + klog.V(4).Infof("API server CA file not found for managed cluster %v", clusterName) continue } // Skip if unable to get managed cluster API server config map for any other reason if err != nil { - klog.V(4).Infof("Error getting CA file for managed cluster %v", clusterName) + klog.V(4).Infof("Error getting API server CA file for managed cluster %v", clusterName) + continue + } + + // Check that managed cluster OAuth server CA ConfigMap has already been synced, skip if not found + _, err = c.configMapClient.ConfigMaps(api.OpenShiftConsoleNamespace).Get(ctx, configmapsub.ManagedClusterOAuthServerCertConfigMapName(clusterName), metav1.GetOptions{}) + if apierrors.IsNotFound(err) { + klog.V(4).Infof("OAuth server CA file not found for managed cluster %v", clusterName) + continue + } + + // Skip if unable to get managed cluster OAuth server config map for any other reason + if err != nil { + klog.V(4).Infof("Error getting OAuth server CA file for managed cluster %v", clusterName) + continue + } + + // Check that managed cluster OAuth client MCV has already been synced, skip if not found + oAuthClientMCV, err := c.dynamicClient.Resource(api.ManagedClusterViewGroupVersionResource).Namespace(managedCluster.Name).Get(ctx, api.OAuthClientManagedClusterViewName, metav1.GetOptions{}) + if apierrors.IsNotFound(err) { + klog.V(4).Infof("OAuth client ManagedClusterView not found for managed cluster %v", clusterName) + continue + } + + // Skip if unable to get managed cluster OAuth client MCV for any other reason + if err != nil { + klog.V(4).Infof("Error getting OAuth client ManagedClusterView for managed cluster %v", clusterName) + continue + } + + oAuthClientSecret, err := managedclusterviewsub.GetOAuthClientSecret(oAuthClientMCV) + if err != nil || oAuthClientSecret == "" { + klog.V(4).Infof("Error getting OAuth client secret for managed cluster %v", clusterName) continue } managedClusterConfigs = append(managedClusterConfigs, consoleserver.ManagedClusterConfig{ Name: clusterName, APIServer: consoleserver.ManagedClusterAPIServerConfig{ - URL: clientConfig.URL, - CAFile: fmt.Sprintf("%s/%s/%s", api.ManagedClusterAPIServerCAMountDir, configmapsub.APIServerCAConfigMapName(clusterName), api.ManagedClusterAPIServerCAKey), + URL: managedCluster.Spec.ManagedClusterClientConfigs[0].URL, + CAFile: configmapsub.APIServerCAFileMountPath(clusterName), + }, + Oauth: consoleserver.ManagedClusterOAuthConfig{ + CAFile: configmapsub.ManagedClusterOAuthServerCAFileMountPath(clusterName), + ClientID: api.ManagedClusterOAuthClientName, + ClientSecret: oAuthClientSecret, }, }) } @@ -261,159 +457,110 @@ func (c *ManagedClusterController) SyncManagedClusterConfigMap(clientConfigs map if len(managedClusterConfigs) > 0 { required, err := configmapsub.DefaultManagedClustersConfigMap(operatorConfig, managedClusterConfigs) if err != nil { - return err, "FailedMarshallingYAML" + return "FailedMarshallingYAML", err } if _, _, applyErr := resourceapply.ApplyConfigMap(c.configMapClient, recorder, required); applyErr != nil { - return applyErr, "FailedApply" + return "FailedApply", applyErr } } - return nil, "" + return "", nil } -func (c *ManagedClusterController) SyncManagedClusterViewOAuthClient(ctx context.Context, operatorConfig *operatorv1.Console, managedClusters *clusterv1.ManagedClusterList) ([]*unstructured.Unstructured, error, string) { +func (c *ManagedClusterController) removeManagedClusters(ctx context.Context) error { + klog.V(4).Info("Removing managed cluster resources.") errs := []string{} - managedClusterOAuthClientViews := []*unstructured.Unstructured{} - for _, managedCluster := range managedClusters.Items { - mcvOAuth := managedclusterviewsub.DefaultViewOAuthClient(operatorConfig, managedCluster.Name) - gvr := managedclusterviewsub.GetGroupVersionResource() + err := c.removeManagedClusterConfigMaps(ctx) + if err != nil { + errs = append(errs, err.Error()) + } - oAuthResp, oAuthErr := c.dynamicClient.Resource(gvr).Namespace(managedCluster.Name).Create(ctx, mcvOAuth, metav1.CreateOptions{}) - if oAuthErr != nil && apierrors.IsAlreadyExists(oAuthErr) { - mcvOAuthName, _ := managedclusterviewsub.GetName(mcvOAuth) - oAuthResp, oAuthErr = c.dynamicClient.Resource(gvr).Namespace(managedCluster.Name).Get(ctx, mcvOAuthName, metav1.GetOptions{}) - } + err = c.removeManagedClusterActions(ctx) + if err != nil { + errs = append(errs, err.Error()) + } - if oAuthErr != nil || oAuthResp == nil { - errs = append(errs, fmt.Sprintf("Error syncing managed cluster view for oauth client for cluster %s: %v", managedCluster.Name, oAuthErr)) - } else { - managedClusterOAuthClientViews = append(managedClusterOAuthClientViews, oAuthResp) - } + err = c.removeManagedClusterViews(ctx) + if err != nil { + errs = append(errs, err.Error()) } if len(errs) > 0 { - return nil, errors.New(strings.Join(errs, "\n")), "ManagedClusterViewOAuthClientSyncError" + klog.Errorf("Errors were encountered while removing managed cluster resources: %v", errs) + return errors.New(strings.Join(errs, "\n")) } - return managedClusterOAuthClientViews, nil, "" + return nil } -func (c *ManagedClusterController) SyncManagedClusterActionCreateOAuthClient(ctx context.Context, operatorConfig *operatorv1.Console, managedClusterOAuthClientViews []*unstructured.Unstructured) ([]*unstructured.Unstructured, error, string) { - managedClusterList := []string{} - managedClusterListErrors := []string{} - for _, managedClusterOAuthView := range managedClusterOAuthClientViews { - status, statusErr := managedclusterviewsub.GetStatus(managedClusterOAuthView) - if !status || statusErr != nil { - namespace, namespaceErr := managedclusterviewsub.GetNamespace(managedClusterOAuthView) - if namespaceErr != nil || namespace == "" { - managedClusterListErrors = append(managedClusterListErrors, fmt.Sprintf("Unable to create oauth client for cluster %v: managed cluster view status unknown", namespace)) - } else { - managedClusterList = append(managedClusterList, namespace) - } - } - } +func (c *ManagedClusterController) removeManagedClusterActions(ctx context.Context) error { + errs := []string{} + mcas, err := c.dynamicClient.Resource(api.ManagedClusterViewGroupVersionResource).List(ctx, metav1.ListOptions{LabelSelector: api.ManagedClusterLabel}) - secret, secErr := c.secretsClient.Secrets(api.TargetNamespace).Get(ctx, secretsub.Stub().Name, metav1.GetOptions{}) - if secErr != nil { - return nil, fmt.Errorf("Failed to get secret: %v", secErr), "ManagedClusterActionCreateOAuthClientSyncError" + if apierrors.IsNotFound(err) { + return nil } - oauthClient, oAuthErr := c.oauthClient.OAuthClients().Get(ctx, oauthsub.Stub().Name, metav1.GetOptions{}) - if oAuthErr != nil { - return nil, fmt.Errorf("Failed to get oauth client: %v", oAuthErr), "ManagedClusterActionCreateOAuthClientSyncError" + if err != nil { + return err } - errs := []string{} - managedClusterActionCreateOAuthClients := []*unstructured.Unstructured{} - secretString := secretsub.GetSecretString(secret) - redirects := oauthsub.GetRedirectURIs(oauthClient) - for _, managedClusterName := range managedClusterList { - mca := managedclusteractionsub.DefaultCreateOAuthClient(operatorConfig, managedClusterName, secretString, redirects) - gvr := managedclusteractionsub.GetGroupVersionResource() - opt := metav1.CreateOptions{} - oAuthCreateResp, oAuthCreateErr := c.dynamicClient.Resource(gvr).Namespace(managedClusterName).Create(ctx, mca, opt) - if oAuthCreateErr != nil && apierrors.IsAlreadyExists(oAuthCreateErr) { - mcaOAuthName, _ := managedclusteractionsub.GetName(mca) - oAuthCreateResp, oAuthCreateErr = c.dynamicClient.Resource(gvr).Namespace(managedClusterName).Get(ctx, mcaOAuthName, metav1.GetOptions{}) - } + if len(mcas.Items) == 0 { + return nil + } - if oAuthCreateErr != nil { - errs = append(errs, fmt.Sprintf("Error syncing managed cluster action for oauth client for cluster %s: %v", managedClusterName, oAuthCreateErr)) - } else { - managedClusterActionCreateOAuthClients = append(managedClusterActionCreateOAuthClients, oAuthCreateResp) + for _, mca := range mcas.Items { + deletionErr := c.dynamicClient.Resource(api.ManagedClusterViewGroupVersionResource).Namespace(mca.GetNamespace()).Delete(ctx, mca.GetName(), metav1.DeleteOptions{}) + if deletionErr != nil && !apierrors.IsNotFound(deletionErr) { + errs = append(errs, deletionErr.Error()) } } if len(errs) > 0 { - return nil, errors.New(strings.Join(errs, "\n")), "ManagedClusterActionCreateOAuthClientSyncError" - } - - if len(managedClusterListErrors) > 0 { - return nil, errors.New(strings.Join(managedClusterListErrors, "\n")), "ManagedClusterActionCreateOAuthClientSyncError" + return errors.New(strings.Join(errs, "\n")) } - - return managedClusterActionCreateOAuthClients, nil, "" + return nil } -func (c *ManagedClusterController) SyncManagedClusterViewIngressCert(ctx context.Context, operatorConfig *operatorv1.Console, managedClusters *clusterv1.ManagedClusterList) ([]*unstructured.Unstructured, error, string) { +func (c *ManagedClusterController) removeManagedClusterViews(ctx context.Context) error { errs := []string{} - managedClusterIngressCertViews := []*unstructured.Unstructured{} - for _, managedCluster := range managedClusters.Items { - mcvIngress := managedclusterviewsub.DefaultViewIngressCert(operatorConfig, managedCluster.Name) - gvr := managedclusterviewsub.GetGroupVersionResource() - - ingressResp, ingressErr := c.dynamicClient.Resource(gvr).Namespace(managedCluster.Name).Create(ctx, mcvIngress, metav1.CreateOptions{}) - if ingressErr != nil && apierrors.IsAlreadyExists(ingressErr) { - mcvIngressName, _ := managedclusterviewsub.GetName(mcvIngress) - ingressResp, ingressErr = c.dynamicClient.Resource(gvr).Namespace(managedCluster.Name).Get(ctx, mcvIngressName, metav1.GetOptions{}) - } + mcvs, err := c.dynamicClient.Resource(api.ManagedClusterViewGroupVersionResource).List(ctx, metav1.ListOptions{LabelSelector: api.ManagedClusterLabel}) - if ingressErr != nil || ingressResp == nil { - errs = append(errs, fmt.Sprintf("Error syncing managed cluster view ingress cert for cluster %s: %v", managedCluster.Name, ingressErr)) - } else { - managedClusterIngressCertViews = append(managedClusterIngressCertViews, ingressResp) - } + if apierrors.IsNotFound(err) { + return nil } - if len(errs) > 0 { - return nil, errors.New(strings.Join(errs, "\n")), "ManagedClusterViewIngressCertSyncError" + if err != nil { + return err } - return managedClusterIngressCertViews, nil, "" -} + if len(mcvs.Items) == 0 { + return nil + } -func (c *ManagedClusterController) SyncManagedClusterIngressCertConfigMap(managedClusterIngressCertViews []*unstructured.Unstructured, ctx context.Context, operatorConfig *operatorv1.Console, recorder events.Recorder) (error, string) { - errs := []string{} - for _, mcvIngress := range managedClusterIngressCertViews { - clusterName, _ := managedclusterviewsub.GetNamespace(mcvIngress) - certBundle, _ := managedclusterviewsub.GetCertBundle(mcvIngress) - required := configmapsub.DefaultManagedClusterIngressCertConfigMap(clusterName, certBundle, operatorConfig) - _, _, configMapApplyError := resourceapply.ApplyConfigMap(c.configMapClient, recorder, required) - if configMapApplyError != nil { - klog.V(4).Infoln(fmt.Sprintf("Skipping Ingress certificate ConfigMap sync for managed cluster %v, Error applying ConfigMap", clusterName)) - errs = append(errs, configMapApplyError.Error()) - continue + for _, mcv := range mcvs.Items { + deletionErr := c.dynamicClient.Resource(api.ManagedClusterViewGroupVersionResource).Namespace(mcv.GetNamespace()).Delete(ctx, mcv.GetName(), metav1.DeleteOptions{}) + if deletionErr != nil && !apierrors.IsNotFound(deletionErr) { + errs = append(errs, deletionErr.Error()) } } if len(errs) > 0 { - return errors.New(strings.Join(errs, "\n")), "ManagedClusterIngressCertConfigMapSyncError" + return errors.New(strings.Join(errs, "\n")) } - - return nil, "" + return nil } -func (c *ManagedClusterController) removeManagedClusters(ctx context.Context) error { +func (c *ManagedClusterController) removeManagedClusterConfigMaps(ctx context.Context) error { errs := []string{} configMaps, err := c.configMapClient.ConfigMaps(api.OpenShiftConsoleNamespace).List(ctx, metav1.ListOptions{LabelSelector: api.ManagedClusterLabel}) + if err != nil { - klog.Errorf("Error listing managed cluster resources to remove: %v", err) return err } if len(configMaps.Items) == 0 { - klog.Info("No managed cluster resources to remove.") return nil } @@ -423,12 +570,9 @@ func (c *ManagedClusterController) removeManagedClusters(ctx context.Context) er errs = append(errs, deletionErr.Error()) } } + if len(errs) > 0 { return errors.New(strings.Join(errs, "\n")) } return nil } - -func (c *ManagedClusterController) listManagedClusters(ctx context.Context) (*clusterv1.ManagedClusterList, error) { - return c.managedClusterClient.ManagedClusters().List(ctx, metav1.ListOptions{LabelSelector: fmt.Sprintf("local-cluster!=true")}) -} diff --git a/pkg/console/operator/sync_v400.go b/pkg/console/operator/sync_v400.go index dd8bc6a3ab..72dd7a4490 100644 --- a/pkg/console/operator/sync_v400.go +++ b/pkg/console/operator/sync_v400.go @@ -71,17 +71,26 @@ func (co *consoleOperator) sync_v400(ctx context.Context, controllerContext fact return statusHandler.FlushAndReturn(routeErr) } - cm, cmChanged, cmErrReason, cmErr := co.SyncConfigMap(ctx, set.Operator, set.Console, set.Infrastructure, set.OAuth, route, controllerContext.Recorder()) + // managed-clusters ConfigMap is managed by another controller and is not required, we don't need to exit the sync loop if it's not present + managedClusterConfigMap, managedClusterConfigErrReason, managedClusterConfigErr := co.GetManagedClusterConfigMap(ctx) + statusHandler.AddConditions(status.HandleProgressingOrDegraded("ManagedClusterConfigSync", managedClusterConfigErrReason, managedClusterConfigErr)) + + cm, cmChanged, cmErrReason, cmErr := co.SyncConfigMap( + ctx, + set.Operator, + set.Console, + set.Infrastructure, + set.OAuth, + route, + managedClusterConfigMap, + controllerContext.Recorder(), + ) toUpdate = toUpdate || cmChanged statusHandler.AddConditions(status.HandleProgressingOrDegraded("ConfigMapSync", cmErrReason, cmErr)) if cmErr != nil { return statusHandler.FlushAndReturn(cmErr) } - // managed-clusters ConfigMap is managed by another controller and is not required, we don't need to exit the sync loop if it's not present - canMountManagedClusterConfig, managedClusterConfigErrReason, managedClusterConfigErr := co.SyncManagedClusterConfigMap(ctx) - statusHandler.AddConditions(status.HandleProgressingOrDegraded("ManagedClusterConfigSync", managedClusterConfigErrReason, managedClusterConfigErr)) - serviceCAConfigMap, serviceCAChanged, serviceCAErrReason, serviceCAErr := co.SyncServiceCAConfigMap(ctx, set.Operator) toUpdate = toUpdate || serviceCAChanged statusHandler.AddConditions(status.HandleProgressingOrDegraded("ServiceCASync", serviceCAErrReason, serviceCAErr)) @@ -125,7 +134,20 @@ func (co *consoleOperator) sync_v400(ctx context.Context, controllerContext fact return statusHandler.FlushAndReturn(oauthErr) } - actualDeployment, depChanged, depErrReason, depErr := co.SyncDeployment(ctx, set.Operator, cm, serviceCAConfigMap, oauthServingCertConfigMap, trustedCAConfigMap, sec, set.Proxy, set.Infrastructure, customLogoCanMount, canMountManagedClusterConfig, controllerContext.Recorder()) + actualDeployment, depChanged, depErrReason, depErr := co.SyncDeployment( + ctx, + set.Operator, + cm, + serviceCAConfigMap, + oauthServingCertConfigMap, + trustedCAConfigMap, + managedClusterConfigMap, + sec, + set.Proxy, + set.Infrastructure, + customLogoCanMount, + controllerContext.Recorder(), + ) toUpdate = toUpdate || depChanged statusHandler.AddConditions(status.HandleProgressingOrDegraded("DeploymentSync", depErrReason, depErr)) if depErr != nil { @@ -241,19 +263,37 @@ func (co *consoleOperator) SyncDeployment( serviceCAConfigMap *corev1.ConfigMap, oauthServingCertConfigMap *corev1.ConfigMap, trustedCAConfigMap *corev1.ConfigMap, + managedClusterConfigMap *corev1.ConfigMap, sec *corev1.Secret, proxyConfig *configv1.Proxy, infrastructureConfig *configv1.Infrastructure, canMountCustomLogo bool, - canMountManagedClusterConfig bool, - recorder events.Recorder) (consoleDeployment *appsv1.Deployment, changed bool, reason string, err error) { - + recorder events.Recorder, +) (consoleDeployment *appsv1.Deployment, changed bool, reason string, err error) { updatedOperatorConfig := operatorConfig.DeepCopy() - apiServerCAConfigMaps, clusterCAConfigMapsErr := co.configMapClient.ConfigMaps(api.OpenShiftConsoleNamespace).List(ctx, metav1.ListOptions{LabelSelector: api.ManagedClusterAPIServerCAName}) - if clusterCAConfigMapsErr != nil { - klog.Warningf("Unable to list managed cluster API server CA bundle ConfigMaps. Multicluster will not be enabled: %v", clusterCAConfigMapsErr) - } - requiredDeployment := deploymentsub.DefaultDeployment(operatorConfig, cm, apiServerCAConfigMaps, serviceCAConfigMap, oauthServingCertConfigMap, trustedCAConfigMap, sec, proxyConfig, infrastructureConfig, canMountCustomLogo, canMountManagedClusterConfig) + apiServerCertConfigMaps, apiServerCertConfigMapsErr := co.configMapClient.ConfigMaps(api.OpenShiftConsoleNamespace).List(ctx, metav1.ListOptions{LabelSelector: api.ManagedClusterAPIServerCertName}) + if apiServerCertConfigMapsErr != nil { + klog.Warningf("Unable to list managed cluster API server cert ConfigMaps. Multicluster will not be enabled: %v", apiServerCertConfigMapsErr) + } + + oAuthServerCertConfigMaps, oAuthServerCertConfigMapsErr := co.configMapClient.ConfigMaps(api.OpenShiftConsoleNamespace).List(ctx, metav1.ListOptions{LabelSelector: api.ManagedClusterOAuthServerCertName}) + if oAuthServerCertConfigMaps != nil { + klog.Warningf("Unable to list managed cluster OAuth server cert ConfigMaps. Multicluster will not be enabled: %v", oAuthServerCertConfigMapsErr) + } + requiredDeployment := deploymentsub.DefaultDeployment( + operatorConfig, + cm, + apiServerCertConfigMaps, + oAuthServerCertConfigMaps, + serviceCAConfigMap, + oauthServingCertConfigMap, + trustedCAConfigMap, + managedClusterConfigMap, + sec, + proxyConfig, + infrastructureConfig, + canMountCustomLogo, + ) genChanged := operatorConfig.ObjectMeta.Generation != operatorConfig.Status.ObservedGeneration if genChanged { @@ -317,6 +357,7 @@ func (co *consoleOperator) SyncConfigMap( infrastructureConfig *configv1.Infrastructure, oauthConfig *configv1.OAuth, activeConsoleRoute *routev1.Route, + managedClusterConfigMap *corev1.ConfigMap, recorder events.Recorder, ) (consoleConfigMap *corev1.ConfigMap, changed bool, reason string, err error) { @@ -349,7 +390,21 @@ func (co *consoleOperator) SyncConfigMap( } pluginsEndpointMap := co.GetPluginsEndpointMap(operatorConfig.Spec.Plugins) - defaultConfigmap, _, err := configmapsub.DefaultConfigMap(operatorConfig, consoleConfig, managedConfig, infrastructureConfig, activeConsoleRoute, useDefaultCAFile, inactivityTimeoutSeconds, pluginsEndpointMap) + managedClusterConfigFile := "" + if managedClusterConfigMap != nil { + managedClusterConfigFile = fmt.Sprintf("%v/%v", api.ManagedClusterConfigMountDir, api.ManagedClusterConfigKey) + } + defaultConfigmap, _, err := configmapsub.DefaultConfigMap( + operatorConfig, + consoleConfig, + managedConfig, + infrastructureConfig, + activeConsoleRoute, + useDefaultCAFile, + inactivityTimeoutSeconds, + pluginsEndpointMap, + managedClusterConfigFile, + ) if err != nil { return nil, false, "FailedConsoleConfigBuilder", err } @@ -364,27 +419,20 @@ func (co *consoleOperator) SyncConfigMap( return cm, cmChanged, "ConsoleConfigBuilder", cmErr } -func (co *consoleOperator) SyncManagedClusterConfigMap(ctx context.Context) (bool, string, error) { +func (co *consoleOperator) GetManagedClusterConfigMap(ctx context.Context) (*corev1.ConfigMap, string, error) { managedClusterConfigMap, err := co.configMapClient.ConfigMaps(api.OpenShiftConsoleNamespace).Get(ctx, api.ManagedClusterConfigMapName, metav1.GetOptions{}) // Not degraded if get fails because the config map isn't there if apierrors.IsNotFound(err) { - klog.V(4).Infof("%v config map not found, continuing...", api.ManagedClusterConfigMapName) - return false, "", nil + klog.V(4).Infof("%s ConfigMap not found, continuing...", api.ManagedClusterConfigMapName) + return nil, "", nil } // Degraded if get fails for any other reason if err != nil { - return false, "FailedGet", err - } - - // Degraded if managed cluster config map is present but doesn't have the correct data key - _, ok := managedClusterConfigMap.Data[api.ManagedClusterConfigKey] - if !ok { - return false, "MissingManagedClusterConfig", fmt.Errorf("%v ConfigMap is missing %v data key", api.ManagedClusterConfigMapName, api.ManagedClusterConfigKey) + return nil, "FailedGet", err } - // Managed cluster config map is present and can be mounted - return true, "", nil + return managedClusterConfigMap, "", nil } // apply service-ca configmap diff --git a/pkg/console/starter/starter.go b/pkg/console/starter/starter.go index b16eacb59b..f17ebc460a 100644 --- a/pkg/console/starter/starter.go +++ b/pkg/console/starter/starter.go @@ -49,7 +49,6 @@ import ( routesinformers "github.com/openshift/client-go/route/informers/externalversions" consolev1client "github.com/openshift/client-go/console/clientset/versioned" - // consolev1client "github.com/openshift/client-go/console/clientset/versioned/typed/console/v1" consoleinformers "github.com/openshift/client-go/console/informers/externalversions" clusterclient "github.com/open-cluster-management/api/client/cluster/clientset/versioned" diff --git a/pkg/console/subresource/configmap/api_server_ca.go b/pkg/console/subresource/configmap/api_server_ca.go index fc00c11f06..6163a0c109 100644 --- a/pkg/console/subresource/configmap/api_server_ca.go +++ b/pkg/console/subresource/configmap/api_server_ca.go @@ -18,7 +18,7 @@ func DefaultAPIServerCAConfigMap(clusterName string, caBundle []byte, cr *operat if caBundle != nil { configMap.Data = map[string]string{ - "ca.crt": string(caBundle), + api.ManagedClusterAPIServerCertKey: string(caBundle), } } @@ -27,19 +27,17 @@ func DefaultAPIServerCAConfigMap(clusterName string, caBundle []byte, cr *operat } func APIServerCAConfigMapStub(clusterName string) *corev1.ConfigMap { - meta := util.SharedMeta() - meta.Name = APIServerCAConfigMapName(clusterName) - meta.Labels = map[string]string{ - api.ManagedClusterAPIServerCAName: "", - api.ManagedClusterLabel: clusterName, - "app": "console", - } - configMap := &corev1.ConfigMap{ - ObjectMeta: meta, - } + configMap := ConsoleConfigMapStub() + configMap.Name = APIServerCAConfigMapName(clusterName) + configMap.Labels = util.LabelsForManagedClusterResources(clusterName) + configMap.Labels[api.ManagedClusterAPIServerCertName] = "" return configMap } func APIServerCAConfigMapName(clusterName string) string { - return fmt.Sprintf("%s-%s", clusterName, api.ManagedClusterAPIServerCAName) + return fmt.Sprintf("%s-%s", clusterName, api.ManagedClusterAPIServerCertName) +} + +func APIServerCAFileMountPath(clusterName string) string { + return fmt.Sprintf("%s/%s/%s", api.ManagedClusterAPIServerCertMountDir, APIServerCAConfigMapName(clusterName), api.ManagedClusterAPIServerCertKey) } diff --git a/pkg/console/subresource/configmap/api_server_ca_test.go b/pkg/console/subresource/configmap/api_server_ca_test.go index 19f71609e4..3324e0a508 100644 --- a/pkg/console/subresource/configmap/api_server_ca_test.go +++ b/pkg/console/subresource/configmap/api_server_ca_test.go @@ -36,6 +36,10 @@ func TestDefaultAPIServerCAConfigMap(t *testing.T) { }, }, want: &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: "v1", + }, ObjectMeta: metav1.ObjectMeta{ Name: APIServerCAConfigMapName("test-cluster"), Namespace: api.OpenShiftConsoleNamespace, @@ -43,13 +47,13 @@ func TestDefaultAPIServerCAConfigMap(t *testing.T) { CreationTimestamp: metav1.Time{}, DeletionTimestamp: nil, DeletionGracePeriodSeconds: nil, - Labels: map[string]string{api.ManagedClusterLabel: "test-cluster", api.ManagedClusterAPIServerCAName: "", "app": "console"}, + Labels: map[string]string{api.ManagedClusterLabel: "test-cluster", api.ManagedClusterAPIServerCertName: "", "app": "console"}, Annotations: map[string]string{}, OwnerReferences: nil, Finalizers: nil, }, Data: map[string]string{ - "ca.crt": "test-bundle", + "ca-bundle.crt": "test-bundle", }, BinaryData: nil, }, @@ -79,7 +83,10 @@ func TestAPIServerCAStub(t *testing.T) { clusterName: "test-cluster", }, want: &corev1.ConfigMap{ - TypeMeta: metav1.TypeMeta{}, + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: "v1", + }, ObjectMeta: metav1.ObjectMeta{ Name: APIServerCAConfigMapName("test-cluster"), Namespace: api.OpenShiftConsoleNamespace, @@ -87,7 +94,7 @@ func TestAPIServerCAStub(t *testing.T) { CreationTimestamp: metav1.Time{}, DeletionTimestamp: nil, DeletionGracePeriodSeconds: nil, - Labels: map[string]string{api.ManagedClusterLabel: "test-cluster", api.ManagedClusterAPIServerCAName: "", "app": "console"}, + Labels: map[string]string{api.ManagedClusterLabel: "test-cluster", api.ManagedClusterAPIServerCertName: "", "app": "console"}, Annotations: map[string]string{}, OwnerReferences: nil, Finalizers: nil, diff --git a/pkg/console/subresource/configmap/configmap.go b/pkg/console/subresource/configmap/configmap.go index da31d2799a..3413e8a70a 100644 --- a/pkg/console/subresource/configmap/configmap.go +++ b/pkg/console/subresource/configmap/configmap.go @@ -43,7 +43,9 @@ func DefaultConfigMap( activeConsoleRoute *routev1.Route, useDefaultCAFile bool, inactivityTimeoutSeconds int, - pluginsEndpoingMap map[string]string) (consoleConfigmap *corev1.ConfigMap, unsupportedOverridesHaveMerged bool, err error) { + pluginsEndpointMap map[string]string, + managedClusterConfigFile string, +) (consoleConfigmap *corev1.ConfigMap, unsupportedOverridesHaveMerged bool, err error) { defaultBuilder := &consoleserver.ConsoleServerCLIConfigBuilder{} defaultConfig, err := defaultBuilder.Host(activeConsoleRoute.Spec.Host). @@ -53,7 +55,6 @@ func DefaultConfigMap( OAuthServingCert(useDefaultCAFile). APIServerURL(getApiUrl(infrastructureConfig)). InactivityTimeout(inactivityTimeoutSeconds). - ManagedClusterConfigFile(fmt.Sprintf("%v/%v", api.ManagedClusterConfigMountDir, api.ManagedClusterConfigKey)). ConfigYAML() if err != nil { klog.Errorf("failed to generate default console-config config: %v", err) @@ -68,7 +69,7 @@ func DefaultConfigMap( DocURL(operatorConfig.Spec.Customization.DocumentationBaseURL). OAuthServingCert(useDefaultCAFile). APIServerURL(getApiUrl(infrastructureConfig)). - Plugins(pluginsEndpoingMap). + Plugins(pluginsEndpointMap). CustomLogoFile(operatorConfig.Spec.Customization.CustomLogoFile.Key). CustomProductName(operatorConfig.Spec.Customization.CustomProductName). CustomDeveloperCatalog(operatorConfig.Spec.Customization.DeveloperCatalog). @@ -78,6 +79,7 @@ func DefaultConfigMap( AddPage(operatorConfig.Spec.Customization.AddPage). StatusPageID(statusPageId(operatorConfig)). InactivityTimeout(inactivityTimeoutSeconds). + ManagedClusterConfigFile(managedClusterConfigFile). ConfigYAML() if err != nil { klog.Errorf("failed to generate user defined console-config config: %v", err) @@ -127,12 +129,13 @@ func EmptyPublicConfig() *corev1.ConfigMap { return config } +func ConsoleConfigMapStub() *corev1.ConfigMap { + return resourceread.ReadConfigMapV1OrDie(assets.MustAsset("configmaps/console-configmap.yaml")) +} + func Stub() *corev1.ConfigMap { - meta := util.SharedMeta() - meta.Name = api.OpenShiftConsoleConfigMapName - configMap := &corev1.ConfigMap{ - ObjectMeta: meta, - } + configMap := ConsoleConfigMapStub() + configMap.Name = api.OpenShiftConsoleConfigMapName return configMap } diff --git a/pkg/console/subresource/configmap/configmap_test.go b/pkg/console/subresource/configmap/configmap_test.go index 18fe9dad3f..96ef05ac00 100644 --- a/pkg/console/subresource/configmap/configmap_test.go +++ b/pkg/console/subresource/configmap/configmap_test.go @@ -38,6 +38,7 @@ func TestDefaultConfigMap(t *testing.T) { useDefaultCAFile bool inactivityTimeoutSeconds int enabledPlugins map[string]string + managedClusterConfigFile string } tests := []struct { name string @@ -65,8 +66,13 @@ func TestDefaultConfigMap(t *testing.T) { }, useDefaultCAFile: true, inactivityTimeoutSeconds: 0, + managedClusterConfigFile: "", }, want: &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: "v1", + }, ObjectMeta: metav1.ObjectMeta{ Name: api.OpenShiftConsoleConfigMapName, Namespace: api.OpenShiftConsoleNamespace, @@ -82,7 +88,6 @@ auth: clusterInfo: consoleBaseAddress: https://` + host + ` masterPublicURL: ` + mockAPIServer + ` -managedClusterConfigFile: /var/managed-cluster-config/managed-clusters.yaml customization: branding: ` + DEFAULT_BRAND + ` documentationBaseURL: ` + DEFAULT_DOC_URL + ` @@ -116,8 +121,13 @@ providers: {} }, useDefaultCAFile: false, inactivityTimeoutSeconds: 0, + managedClusterConfigFile: "", }, want: &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: "v1", + }, ObjectMeta: metav1.ObjectMeta{ Name: api.OpenShiftConsoleConfigMapName, Namespace: api.OpenShiftConsoleNamespace, @@ -133,7 +143,6 @@ auth: clusterInfo: consoleBaseAddress: https://` + host + ` masterPublicURL: ` + mockAPIServer + ` -managedClusterConfigFile: /var/managed-cluster-config/managed-clusters.yaml customization: branding: ` + DEFAULT_BRAND + ` documentationBaseURL: ` + DEFAULT_DOC_URL + ` @@ -154,7 +163,6 @@ providers: {} managedConfig: &corev1.ConfigMap{ Data: map[string]string{configKey: `kind: ConsoleConfig apiVersion: console.openshift.io/v1 -managedClusterConfigFile: /var/managed-cluster-config/managed-clusters.yaml customization: branding: online documentationBaseURL: https://docs.okd.io/4.4/ @@ -176,8 +184,13 @@ customization: }, useDefaultCAFile: true, inactivityTimeoutSeconds: 0, + managedClusterConfigFile: "", }, want: &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: "v1", + }, ObjectMeta: metav1.ObjectMeta{ Name: api.OpenShiftConsoleConfigMapName, Namespace: api.OpenShiftConsoleNamespace, @@ -193,7 +206,6 @@ auth: clusterInfo: consoleBaseAddress: https://` + host + ` masterPublicURL: ` + mockAPIServer + ` -managedClusterConfigFile: /var/managed-cluster-config/managed-clusters.yaml customization: branding: online documentationBaseURL: https://docs.okd.io/4.4/ @@ -223,7 +235,6 @@ providers: {} managedConfig: &corev1.ConfigMap{ Data: map[string]string{configKey: `kind: ConsoleConfig apiVersion: console.openshift.io/v1 -managedClusterConfigFile: /var/managed-cluster-config/managed-clusters.yaml customization: branding: online documentationBaseURL: https://docs.okd.io/4.4/ @@ -245,8 +256,13 @@ customization: }, useDefaultCAFile: true, inactivityTimeoutSeconds: 0, + managedClusterConfigFile: "", }, want: &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: "v1", + }, ObjectMeta: metav1.ObjectMeta{ Name: api.OpenShiftConsoleConfigMapName, Namespace: api.OpenShiftConsoleNamespace, @@ -262,7 +278,6 @@ auth: clusterInfo: consoleBaseAddress: https://` + host + ` masterPublicURL: ` + mockAPIServer + ` -managedClusterConfigFile: /var/managed-cluster-config/managed-clusters.yaml customization: branding: ` + string(operatorv1.BrandDedicated) + ` documentationBaseURL: ` + mockOperatorDocURL + ` @@ -297,7 +312,6 @@ providers: {} managedConfig: &corev1.ConfigMap{ Data: map[string]string{configKey: `kind: ConsoleConfig apiVersion: console.openshift.io/v1 -managedClusterConfigFile: /var/managed-cluster-config/managed-clusters.yaml customization: branding: online documentationBaseURL: https://docs.okd.io/4.4/ @@ -319,8 +333,13 @@ customization: }, useDefaultCAFile: true, inactivityTimeoutSeconds: 0, + managedClusterConfigFile: "", }, want: &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: "v1", + }, ObjectMeta: metav1.ObjectMeta{ Name: api.OpenShiftConsoleConfigMapName, Namespace: api.OpenShiftConsoleNamespace, @@ -336,7 +355,6 @@ auth: clusterInfo: consoleBaseAddress: https://` + host + ` masterPublicURL: ` + mockAPIServer + ` -managedClusterConfigFile: /var/managed-cluster-config/managed-clusters.yaml customization: branding: ` + string(operatorv1.BrandDedicated) + ` documentationBaseURL: ` + mockOperatorDocURL + ` @@ -373,7 +391,6 @@ providers: {} managedConfig: &corev1.ConfigMap{ Data: map[string]string{configKey: `kind: ConsoleConfig apiVersion: console.openshift.io/v1 -managedClusterConfigFile: /var/managed-cluster-config/managed-clusters.yaml customization: branding: online documentationBaseURL: https://docs.okd.io/4.4/ @@ -395,8 +412,13 @@ customization: }, useDefaultCAFile: true, inactivityTimeoutSeconds: 0, + managedClusterConfigFile: "", }, want: &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: "v1", + }, ObjectMeta: metav1.ObjectMeta{ Name: api.OpenShiftConsoleConfigMapName, Namespace: api.OpenShiftConsoleNamespace, @@ -412,7 +434,6 @@ auth: clusterInfo: consoleBaseAddress: https://` + host + ` masterPublicURL: ` + mockAPIServer + ` -managedClusterConfigFile: /var/managed-cluster-config/managed-clusters.yaml customization: branding: ` + string(operatorv1.BrandDedicated) + ` documentationBaseURL: ` + mockOperatorDocURL + ` @@ -453,8 +474,13 @@ providers: }, useDefaultCAFile: false, inactivityTimeoutSeconds: 0, + managedClusterConfigFile: "", }, want: &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: "v1", + }, ObjectMeta: metav1.ObjectMeta{ Name: api.OpenShiftConsoleConfigMapName, Namespace: api.OpenShiftConsoleNamespace, @@ -470,7 +496,6 @@ auth: clusterInfo: consoleBaseAddress: https://` + customHostname + ` masterPublicURL: ` + mockAPIServer + ` -managedClusterConfigFile: /var/managed-cluster-config/managed-clusters.yaml customization: branding: ` + DEFAULT_BRAND + ` documentationBaseURL: ` + DEFAULT_DOC_URL + ` @@ -505,8 +530,13 @@ providers: {} }, useDefaultCAFile: true, inactivityTimeoutSeconds: 60, + managedClusterConfigFile: "", }, want: &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: "v1", + }, ObjectMeta: metav1.ObjectMeta{ Name: api.OpenShiftConsoleConfigMapName, Namespace: api.OpenShiftConsoleNamespace, @@ -523,7 +553,6 @@ auth: clusterInfo: consoleBaseAddress: https://` + host + ` masterPublicURL: ` + mockAPIServer + ` -managedClusterConfigFile: /var/managed-cluster-config/managed-clusters.yaml customization: branding: ` + DEFAULT_BRAND + ` documentationBaseURL: ` + DEFAULT_DOC_URL + ` @@ -532,6 +561,62 @@ servingInfo: certFile: /var/serving-cert/tls.crt keyFile: /var/serving-cert/tls.key providers: {} +`, + }, + }, + }, + { + name: "Test operator config, with managedClusterConfigFile set", + args: args{ + operatorConfig: &operatorv1.Console{}, + consoleConfig: &configv1.Console{}, + managedConfig: &corev1.ConfigMap{}, + infrastructureConfig: &configv1.Infrastructure{ + Status: configv1.InfrastructureStatus{ + APIServerURL: mockAPIServer, + }, + }, + rt: &routev1.Route{ + ObjectMeta: metav1.ObjectMeta{ + Name: api.OpenShiftConsoleName, + }, + Spec: routev1.RouteSpec{ + Host: host, + }, + }, + useDefaultCAFile: true, + inactivityTimeoutSeconds: 0, + managedClusterConfigFile: "test", + }, + want: &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: api.OpenShiftConsoleConfigMapName, + Namespace: api.OpenShiftConsoleNamespace, + Labels: map[string]string{"app": api.OpenShiftConsoleName}, + Annotations: map[string]string{}, + }, + Data: map[string]string{configKey: `kind: ConsoleConfig +apiVersion: console.openshift.io/v1 +auth: + clientID: console + clientSecretFile: /var/oauth-config/clientSecret + oauthEndpointCAFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt +clusterInfo: + consoleBaseAddress: https://` + host + ` + masterPublicURL: ` + mockAPIServer + ` +customization: + branding: ` + DEFAULT_BRAND + ` + documentationBaseURL: ` + DEFAULT_DOC_URL + ` +servingInfo: + bindAddress: https://[::]:8443 + certFile: /var/serving-cert/tls.crt + keyFile: /var/serving-cert/tls.key +providers: {} +managedClusterConfigFile: 'test' `, }, }, @@ -561,8 +646,13 @@ providers: {} "plugin1": "plugin1_url", "plugin2": "plugin2_url", }, + managedClusterConfigFile: "", }, want: &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: "v1", + }, ObjectMeta: metav1.ObjectMeta{ Name: api.OpenShiftConsoleConfigMapName, Namespace: api.OpenShiftConsoleNamespace, @@ -578,7 +668,6 @@ auth: clusterInfo: consoleBaseAddress: https://` + host + ` masterPublicURL: ` + mockAPIServer + ` -managedClusterConfigFile: /var/managed-cluster-config/managed-clusters.yaml customization: branding: ` + DEFAULT_BRAND + ` documentationBaseURL: ` + DEFAULT_DOC_URL + ` @@ -606,6 +695,7 @@ plugins: tt.args.useDefaultCAFile, tt.args.inactivityTimeoutSeconds, tt.args.enabledPlugins, + tt.args.managedClusterConfigFile, ) // marshall the exampleYaml to map[string]interface{} so we can use it in diff below @@ -656,6 +746,10 @@ func TestStub(t *testing.T) { { name: "Testing Stub function configmap", want: &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: "v1", + }, ObjectMeta: metav1.ObjectMeta{ Name: api.OpenShiftConsoleConfigMapName, Namespace: api.OpenShiftConsoleNamespace, @@ -752,7 +846,6 @@ func Test_extractYAML(t *testing.T) { }, Data: map[string]string{configKey: `kind: ConsoleConfig apiVersion: console.openshift.io/v1 -managedClusterConfigFile: /var/managed-cluster-config/managed-clusters.yaml customization: branding: online documentationBaseURL: https://docs.okd.io/4.4/ @@ -763,7 +856,6 @@ customization: }, want: `kind: ConsoleConfig apiVersion: console.openshift.io/v1 -managedClusterConfigFile: /var/managed-cluster-config/managed-clusters.yaml customization: branding: online documentationBaseURL: https://docs.okd.io/4.4/ diff --git a/pkg/console/subresource/configmap/managed_cluster_ingress_cert.go b/pkg/console/subresource/configmap/managed_cluster_ingress_cert.go deleted file mode 100644 index 102f4144b7..0000000000 --- a/pkg/console/subresource/configmap/managed_cluster_ingress_cert.go +++ /dev/null @@ -1,37 +0,0 @@ -package configmap - -import ( - "fmt" - - corev1 "k8s.io/api/core/v1" - - operatorv1 "github.com/openshift/api/operator/v1" - "github.com/openshift/library-go/pkg/operator/resource/resourceread" - - "github.com/openshift/console-operator/pkg/api" - "github.com/openshift/console-operator/pkg/console/assets" - "github.com/openshift/console-operator/pkg/console/subresource/util" -) - -func DefaultManagedClusterIngressCertConfigMap(clusterName string, caBundle string, cr *operatorv1.Console) *corev1.ConfigMap { - configMap := ManagedClusterIngressCertConfigMapStub(clusterName) - - if caBundle != "" { - configMap.Data = map[string]string{ - "ca.crt": caBundle, - } - } - - util.AddOwnerRef(configMap, util.OwnerRefFrom(cr)) - return configMap -} - -func ManagedClusterIngressCertConfigMapStub(clusterName string) *corev1.ConfigMap { - configMap := resourceread.ReadConfigMapV1OrDie(assets.MustAsset("configmaps/console-managed-cluster-ingress-cert-configmap.yaml")) - configMap.Name = ManagedClusterIngressCertConfigMapName(clusterName) - return configMap -} - -func ManagedClusterIngressCertConfigMapName(clusterName string) string { - return fmt.Sprintf("%s-%s", clusterName, api.ManagedClusterIngressCertName) -} diff --git a/pkg/console/subresource/configmap/managed_cluster_oauth_server_cert.go b/pkg/console/subresource/configmap/managed_cluster_oauth_server_cert.go new file mode 100644 index 0000000000..ce3a03fdff --- /dev/null +++ b/pkg/console/subresource/configmap/managed_cluster_oauth_server_cert.go @@ -0,0 +1,38 @@ +package configmap + +import ( + "fmt" + + corev1 "k8s.io/api/core/v1" + + operatorv1 "github.com/openshift/api/operator/v1" + + "github.com/openshift/console-operator/pkg/api" + "github.com/openshift/console-operator/pkg/console/subresource/util" +) + +func DefaultManagedClusterOAuthServerCertConfigMap(clusterName string, caBundle string, cr *operatorv1.Console) *corev1.ConfigMap { + configMap := ManagedClusterOAuthServerCertConfigMapStub(clusterName) + configMap.Data = map[string]string{ + api.ManagedClusterOAuthServerCertKey: caBundle, + } + + util.AddOwnerRef(configMap, util.OwnerRefFrom(cr)) + return configMap +} + +func ManagedClusterOAuthServerCertConfigMapStub(clusterName string) *corev1.ConfigMap { + configMap := ConsoleConfigMapStub() + configMap.Name = ManagedClusterOAuthServerCertConfigMapName(clusterName) + configMap.Labels = util.LabelsForManagedClusterResources(clusterName) + configMap.Labels[api.ManagedClusterOAuthServerCertName] = "" + return configMap +} + +func ManagedClusterOAuthServerCertConfigMapName(clusterName string) string { + return fmt.Sprintf("%s-%s", clusterName, api.ManagedClusterOAuthServerCertName) +} + +func ManagedClusterOAuthServerCAFileMountPath(clusterName string) string { + return fmt.Sprintf("%s/%s/%s", api.ManagedClusterOAuthServerCertMountDir, ManagedClusterOAuthServerCertConfigMapName(clusterName), api.ManagedClusterAPIServerCertKey) +} diff --git a/pkg/console/subresource/configmap/managed_clusters.go b/pkg/console/subresource/configmap/managed_clusters.go index 04491e8e6b..bf435aaf52 100644 --- a/pkg/console/subresource/configmap/managed_clusters.go +++ b/pkg/console/subresource/configmap/managed_clusters.go @@ -28,14 +28,8 @@ func DefaultManagedClustersConfigMap(operatorConfig *operatorv1.Console, managed } func ManagedClustersConfigMapStub() *corev1.ConfigMap { - meta := util.SharedMeta() - meta.Name = api.ManagedClusterConfigMapName - meta.Labels = map[string]string{ - "app": "console", - api.ManagedClusterLabel: "", - } - configMap := &corev1.ConfigMap{ - ObjectMeta: meta, - } + configMap := ConsoleConfigMapStub() + configMap.Name = api.ManagedClusterConfigMapName + configMap.Labels[api.ManagedClusterLabel] = "" return configMap } diff --git a/pkg/console/subresource/configmap/managed_clusters_test.go b/pkg/console/subresource/configmap/managed_clusters_test.go index 9562f92f09..7c47c57b98 100644 --- a/pkg/console/subresource/configmap/managed_clusters_test.go +++ b/pkg/console/subresource/configmap/managed_clusters_test.go @@ -59,6 +59,10 @@ func TestDefaultManagedClustersConfigMap(t *testing.T) { }, }, want: &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: "v1", + }, ObjectMeta: metav1.ObjectMeta{ Name: api.ManagedClusterConfigMapName, Namespace: api.OpenShiftConsoleNamespace, @@ -96,7 +100,10 @@ func TestManagedClusterStub(t *testing.T) { { name: "Test stubbing managed clusters config map", want: &corev1.ConfigMap{ - TypeMeta: metav1.TypeMeta{}, + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: "v1", + }, ObjectMeta: metav1.ObjectMeta{ Name: api.ManagedClusterConfigMapName, Namespace: api.OpenShiftConsoleNamespace, diff --git a/pkg/console/subresource/deployment/deployment.go b/pkg/console/subresource/deployment/deployment.go index 6c7002d858..5b10828dca 100644 --- a/pkg/console/subresource/deployment/deployment.go +++ b/pkg/console/subresource/deployment/deployment.go @@ -61,13 +61,26 @@ type volumeConfig struct { mappedKeys map[string]string } -func DefaultDeployment(operatorConfig *operatorv1.Console, cm *corev1.ConfigMap, apiServerCAConfigMaps *corev1.ConfigMapList, serviceCAConfigMap *corev1.ConfigMap, oauthServingCertConfigMap *corev1.ConfigMap, trustedCAConfigMap *corev1.ConfigMap, sec *corev1.Secret, proxyConfig *configv1.Proxy, infrastructureConfig *configv1.Infrastructure, canMountCustomLogo bool, canMountManagedClusterConfigMap bool) *appsv1.Deployment { +func DefaultDeployment( + operatorConfig *operatorv1.Console, + cm *corev1.ConfigMap, + apiServerCertConfigMaps *corev1.ConfigMapList, + managedClusterOAuthServerCertConfigMaps *corev1.ConfigMapList, + serviceCAConfigMap *corev1.ConfigMap, + localOAuthServingCertConfigMap *corev1.ConfigMap, + trustedCAConfigMap *corev1.ConfigMap, + managedClusterConfigMap *corev1.ConfigMap, + sec *corev1.Secret, + proxyConfig *configv1.Proxy, + infrastructureConfig *configv1.Infrastructure, + canMountCustomLogo bool, +) *appsv1.Deployment { deployment := resourceread.ReadDeploymentV1OrDie(assets.MustAsset("deployments/console-deployment.yaml")) withReplicas(deployment, infrastructureConfig) withAffinity(deployment, infrastructureConfig, "ui") withStrategy(deployment, infrastructureConfig) - withConsoleAnnotations(deployment, cm, serviceCAConfigMap, oauthServingCertConfigMap, trustedCAConfigMap, sec, proxyConfig, infrastructureConfig) - withConsoleVolumes(deployment, trustedCAConfigMap, apiServerCAConfigMaps, canMountCustomLogo, canMountManagedClusterConfigMap) + withConsoleAnnotations(deployment, cm, serviceCAConfigMap, localOAuthServingCertConfigMap, trustedCAConfigMap, sec, proxyConfig, infrastructureConfig) + withConsoleVolumes(deployment, apiServerCertConfigMaps, managedClusterOAuthServerCertConfigMaps, trustedCAConfigMap, managedClusterConfigMap, canMountCustomLogo) withConsoleContainerImage(deployment, operatorConfig, proxyConfig) withConsoleNodeSelector(deployment, infrastructureConfig) util.AddOwnerRef(deployment, util.OwnerRefFrom(operatorConfig)) @@ -148,22 +161,33 @@ func withConsoleAnnotations(deployment *appsv1.Deployment, cm *corev1.ConfigMap, deployment.Spec.Template.ObjectMeta.Annotations = podAnnotations } -func withConsoleVolumes(deployment *appsv1.Deployment, trustedCAConfigMap *corev1.ConfigMap, apiServerCAConfigMaps *corev1.ConfigMapList, canMountCustomLogo bool, canMountManagedClusterConfigMap bool) { +func withConsoleVolumes( + deployment *appsv1.Deployment, + apiServerCertConfigMaps *corev1.ConfigMapList, + oAuthServerCertConfigMaps *corev1.ConfigMapList, + trustedCAConfigMap *corev1.ConfigMap, + managedClusterConfigMap *corev1.ConfigMap, + canMountCustomLogo bool) { volumeConfig := defaultVolumeConfig() caBundle, caBundleExists := trustedCAConfigMap.Data["ca-bundle.crt"] if caBundleExists && caBundle != "" { volumeConfig = append(volumeConfig, trustedCAVolume()) } + if managedClusterConfigMap != nil { + volumeConfig = append(volumeConfig, managedClusterVolumeConfig()) + } if canMountCustomLogo { volumeConfig = append(volumeConfig, customLogoVolume()) } - if canMountManagedClusterConfigMap { - volumeConfig = append(volumeConfig, managedClusterVolumeConfig()) + if len(apiServerCertConfigMaps.Items) > 0 { + for _, apiServerCertConfigMap := range apiServerCertConfigMaps.Items { + volumeConfig = append(volumeConfig, apiServerCertVolumeConfig(apiServerCertConfigMap)) + } } - if len(apiServerCAConfigMaps.Items) > 0 { - for _, apiServerCAConfigMap := range apiServerCAConfigMaps.Items { - volumeConfig = append(volumeConfig, apiServerCAVolumeConfig(apiServerCAConfigMap)) + if len(oAuthServerCertConfigMaps.Items) > 0 { + for _, oAuthServerCertConfigMap := range oAuthServerCertConfigMaps.Items { + volumeConfig = append(volumeConfig, oAuthServerCertVolumeConfig(oAuthServerCertConfigMap)) } } @@ -404,11 +428,21 @@ func managedClusterVolumeConfig() volumeConfig { } } -func apiServerCAVolumeConfig(configMap corev1.ConfigMap) volumeConfig { +func apiServerCertVolumeConfig(configMap corev1.ConfigMap) volumeConfig { + name := configMap.GetName() + return volumeConfig{ + name: name, + path: fmt.Sprintf("%s/%s", api.ManagedClusterAPIServerCertMountDir, name), + readOnly: true, + isConfigMap: true, + } +} + +func oAuthServerCertVolumeConfig(configMap corev1.ConfigMap) volumeConfig { name := configMap.GetName() return volumeConfig{ name: name, - path: fmt.Sprintf("%s/%s", api.ManagedClusterAPIServerCAMountDir, name), + path: fmt.Sprintf("%s/%s", api.ManagedClusterOAuthServerCertMountDir, name), readOnly: true, isConfigMap: true, } diff --git a/pkg/console/subresource/deployment/deployment_test.go b/pkg/console/subresource/deployment/deployment_test.go index 90b1d4231a..f4fc014b28 100644 --- a/pkg/console/subresource/deployment/deployment_test.go +++ b/pkg/console/subresource/deployment/deployment_test.go @@ -34,17 +34,18 @@ func TestDefaultDeployment(t *testing.T) { tolerationSeconds int64 = 120 ) type args struct { - config *operatorsv1.Console - cm *corev1.ConfigMap - ccas *corev1.ConfigMapList - ca *corev1.ConfigMap - dica *corev1.ConfigMap - tca *corev1.ConfigMap - sec *corev1.Secret - proxy *configv1.Proxy - infrastructure *configv1.Infrastructure - canMountCustomLogo bool - canMountManagedClusterConfigMap bool + config *operatorsv1.Console + cm *corev1.ConfigMap + ccas *corev1.ConfigMapList + ocas *corev1.ConfigMapList + ca *corev1.ConfigMap + dica *corev1.ConfigMap + tca *corev1.ConfigMap + mccm *corev1.ConfigMap + sec *corev1.Secret + proxy *configv1.Proxy + infrastructure *configv1.Infrastructure + canMountCustomLogo bool } consoleOperatorConfig := &operatorsv1.Console{ @@ -178,10 +179,10 @@ func TestDefaultDeployment(t *testing.T) { consoleDeploymentTemplate := resourceread.ReadDeploymentV1OrDie(assets.MustAsset("deployments/console-deployment.yaml")) withConsoleContainerImage(consoleDeploymentTemplate, consoleOperatorConfig, proxyConfig) - withConsoleVolumes(consoleDeploymentTemplate, trustedCAConfigMapEmpty, &corev1.ConfigMapList{}, false, false) + withConsoleVolumes(consoleDeploymentTemplate, &corev1.ConfigMapList{}, &corev1.ConfigMapList{}, trustedCAConfigMapEmpty, nil, false) consoleDeploymentContainer := consoleDeploymentTemplate.Spec.Template.Spec.Containers[0] consoleDeploymentVolumes := consoleDeploymentTemplate.Spec.Template.Spec.Volumes - withConsoleVolumes(consoleDeploymentTemplate, trustedCAConfigMapSet, &corev1.ConfigMapList{}, false, false) + withConsoleVolumes(consoleDeploymentTemplate, &corev1.ConfigMapList{}, &corev1.ConfigMapList{}, trustedCAConfigMapSet, nil, false) consoleDeploymentContainerTrusted := consoleDeploymentTemplate.Spec.Template.Spec.Containers[0] consoleDeploymentVolumesTrusted := consoleDeploymentTemplate.Spec.Template.Spec.Volumes @@ -196,6 +197,7 @@ func TestDefaultDeployment(t *testing.T) { config: consoleOperatorConfig, cm: consoleConfig, ccas: &corev1.ConfigMapList{}, + ocas: &corev1.ConfigMapList{}, ca: &corev1.ConfigMap{}, dica: &corev1.ConfigMap{ Data: map[string]string{"ca-bundle.crt": "test"}, @@ -274,6 +276,7 @@ func TestDefaultDeployment(t *testing.T) { config: consoleOperatorConfig, cm: consoleConfig, ccas: &corev1.ConfigMapList{}, + ocas: &corev1.ConfigMapList{}, ca: &corev1.ConfigMap{}, dica: &corev1.ConfigMap{ Data: map[string]string{"ca-bundle.crt": "test"}, @@ -351,6 +354,7 @@ func TestDefaultDeployment(t *testing.T) { config: consoleOperatorConfig, cm: consoleConfig, ccas: &corev1.ConfigMapList{}, + ocas: &corev1.ConfigMapList{}, ca: &corev1.ConfigMap{}, dica: &corev1.ConfigMap{ Data: map[string]string{"ca-bundle.crt": "test"}, @@ -421,6 +425,7 @@ func TestDefaultDeployment(t *testing.T) { config: consoleOperatorConfig, cm: consoleConfig, ccas: &corev1.ConfigMapList{}, + ocas: &corev1.ConfigMapList{}, ca: &corev1.ConfigMap{}, dica: &corev1.ConfigMap{ Data: map[string]string{"ca-bundle.crt": "test"}, @@ -492,7 +497,20 @@ func TestDefaultDeployment(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if diff := deep.Equal(DefaultDeployment(tt.args.config, tt.args.cm, tt.args.ccas, tt.args.dica, tt.args.cm, tt.args.tca, tt.args.sec, tt.args.proxy, tt.args.infrastructure, tt.args.canMountCustomLogo, tt.args.canMountManagedClusterConfigMap), tt.want); diff != nil { + if diff := deep.Equal(DefaultDeployment( + tt.args.config, + tt.args.cm, + tt.args.ccas, + tt.args.ocas, + tt.args.dica, + tt.args.cm, + tt.args.tca, + tt.args.mccm, + tt.args.sec, + tt.args.proxy, + tt.args.infrastructure, + tt.args.canMountCustomLogo, + ), tt.want); diff != nil { t.Error(diff) } }) @@ -770,9 +788,10 @@ func TestWithAffinity(t *testing.T) { func TestWithConsoleVolumes(t *testing.T) { type args struct { - deployment *appsv1.Deployment - trustedCAConfigMap *corev1.ConfigMap - canMountCustomLogo bool + deployment *appsv1.Deployment + trustedCAConfigMap *corev1.ConfigMap + managedClusterConfigMap *corev1.ConfigMap + canMountCustomLogo bool } trustedCAConfigMap := &corev1.ConfigMap{ @@ -1036,9 +1055,10 @@ func TestWithConsoleVolumes(t *testing.T) { { name: "Test Volumes With CA bundle And Custom Logo True", args: args{ - deployment: consoleDeployment, - trustedCAConfigMap: trustedCAConfigMap, - canMountCustomLogo: true, + deployment: consoleDeployment, + trustedCAConfigMap: trustedCAConfigMap, + managedClusterConfigMap: nil, + canMountCustomLogo: true, }, want: &appsv1.Deployment{ Spec: appsv1.DeploymentSpec{ @@ -1059,7 +1079,14 @@ func TestWithConsoleVolumes(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - withConsoleVolumes(tt.args.deployment, tt.args.trustedCAConfigMap, &corev1.ConfigMapList{}, tt.args.canMountCustomLogo, false) + withConsoleVolumes( + tt.args.deployment, + &corev1.ConfigMapList{}, + &corev1.ConfigMapList{}, + tt.args.trustedCAConfigMap, + tt.args.managedClusterConfigMap, + tt.args.canMountCustomLogo, + ) if diff := deep.Equal(tt.args.deployment, tt.want); diff != nil { t.Error(diff) } diff --git a/pkg/console/subresource/managedclusteraction/create_oauth_client.go b/pkg/console/subresource/managedclusteraction/create_oauth_client.go new file mode 100644 index 0000000000..567beec90e --- /dev/null +++ b/pkg/console/subresource/managedclusteraction/create_oauth_client.go @@ -0,0 +1,41 @@ +package managedclusteraction + +import ( + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + utilerrors "k8s.io/apimachinery/pkg/util/errors" + + // openshift + "github.com/openshift/console-operator/pkg/api" + "github.com/openshift/console-operator/pkg/console/assets" + "github.com/openshift/console-operator/pkg/console/subresource/util" + // acm - TODO conflicts adding package to go.mod with several dependencies + // managedclusterviewv1beta1 "github.com/open-cluster-management/multicloud-operators-foundation/pkg/apis/action/v1beta1" +) + +func DefaultCreateOAuthClientAction(cn string, sec string, redirects []string) (*unstructured.Unstructured, error) { + mca := CreateOAuthClientStub(cn) + var errors []error + errors = append(errors, unstructured.SetNestedField(mca.Object, api.CreateOAuthClientManagedClusterActionName, "metadata", "name")) + errors = append(errors, unstructured.SetNestedField(mca.Object, cn, "metadata", "namespace")) + errors = append(errors, unstructured.SetNestedStringMap(mca.Object, util.LabelsForManagedClusterResources(cn), "metadata", "labels")) + errors = append(errors, unstructured.SetNestedField(mca.Object, sec, "spec", "kube", "template", "secret")) + errors = append(errors, unstructured.SetNestedField(mca.Object, api.ManagedClusterOAuthClientName, "spec", "kube", "template", "metadata", "name")) + errors = append(errors, unstructured.SetNestedStringSlice(mca.Object, redirects, "spec", "kube", "template", "redirectURIs")) + aggregateError := utilerrors.NewAggregate(errors) + if aggregateError != nil { + return nil, aggregateError + } + return mca, nil +} + +func CreateOAuthClientStub(cn string) *unstructured.Unstructured { + return util.ReadUnstructuredOrDie(assets.MustAsset("managedclusteractions/console-create-oauth-client.yaml")) +} + +func GetName(mca *unstructured.Unstructured) (string, error) { + name, found, err := unstructured.NestedString(mca.Object, "metadata", "name") + if err != nil || !found || name == "" { + return "", err + } + return name, nil +} diff --git a/pkg/console/subresource/managedclusteraction/oauth-client.go b/pkg/console/subresource/managedclusteraction/oauth-client.go deleted file mode 100644 index cdad03b843..0000000000 --- a/pkg/console/subresource/managedclusteraction/oauth-client.go +++ /dev/null @@ -1,45 +0,0 @@ -package managedclusteraction - -import ( - operatorv1 "github.com/openshift/api/operator/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime/schema" - - // openshift - "github.com/openshift/console-operator/pkg/console/assets" - "github.com/openshift/console-operator/pkg/console/subresource/util" - // acm - TODO conflicts adding package to go.mod with several dependencies - // managedclusterviewv1beta1 "github.com/open-cluster-management/multicloud-operators-foundation/pkg/apis/action/v1beta1" -) - -func DefaultCreateOAuthClient(cr *operatorv1.Console, cn string, sec string, redirects []string) *unstructured.Unstructured { - managedClusterAction := CreateOAuthClientStub(cn) - withDefaultCreateOAuthClientInfo(managedClusterAction, cn, sec, redirects) - return managedClusterAction -} - -func withDefaultCreateOAuthClientInfo(mca *unstructured.Unstructured, cn string, sec string, redirects []string) { - unstructured.SetNestedField(mca.Object, cn, "metadata", "namespace") - unstructured.SetNestedField(mca.Object, sec, "spec", "kube", "template", "secret") - unstructured.SetNestedStringSlice(mca.Object, redirects, "spec", "kube", "template", "redirectURIs") -} - -func CreateOAuthClientStub(cn string) *unstructured.Unstructured { - return util.ReadUnstructuredOrDie(assets.MustAsset("managedclusteractions/console-managed-cluster-action-create-oauth-client.yaml")) -} - -func GetName(mca *unstructured.Unstructured) (string, error) { - name, found, err := unstructured.NestedString(mca.Object, "metadata", "name") - if err != nil || !found || name == "" { - return "", err - } - return name, nil -} - -func GetGroupVersionResource() schema.GroupVersionResource { - return schema.GroupVersionResource{ - Group: "action.open-cluster-management.io", - Version: "v1beta1", - Resource: "managedclusteractions", - } -} diff --git a/pkg/console/subresource/managedclusterview/default-ingress-cert.go b/pkg/console/subresource/managedclusterview/default-ingress-cert.go deleted file mode 100644 index 9ee904c4da..0000000000 --- a/pkg/console/subresource/managedclusterview/default-ingress-cert.go +++ /dev/null @@ -1,35 +0,0 @@ -package managedclusterview - -import ( - operatorv1 "github.com/openshift/api/operator/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - - // openshift - "github.com/openshift/console-operator/pkg/api" - "github.com/openshift/console-operator/pkg/console/assets" - "github.com/openshift/console-operator/pkg/console/subresource/util" - // acm - TODO conflicts adding package to go.mod with several dependencies - // managedclusterviewv1beta1 "github.com/open-cluster-management/multicloud-operators-foundation/pkg/apis/action/v1beta1" -) - -func DefaultViewIngressCert(cr *operatorv1.Console, cn string) *unstructured.Unstructured { - managedClusterView := ViewIngressCertStub(cn) - withDefaultViewIngressCertInfo(managedClusterView, cn) - return managedClusterView -} - -func withDefaultViewIngressCertInfo(mcv *unstructured.Unstructured, cn string) { - unstructured.SetNestedField(mcv.Object, cn, "metadata", "namespace") -} - -func ViewIngressCertStub(cn string) *unstructured.Unstructured { - return util.ReadUnstructuredOrDie(assets.MustAsset("managedclusterviews/console-managed-cluster-view-ingress-cert.yaml")) -} - -func GetCertBundle(mcv *unstructured.Unstructured) (string, error) { - cert, found, err := unstructured.NestedString(mcv.Object, "status", "result", "data", api.ManagedClusterIngressCertKey) - if err != nil || !found || cert == "" { - return "", err - } - return cert, nil -} diff --git a/pkg/console/subresource/managedclusterview/oauth-client.go b/pkg/console/subresource/managedclusterview/oauth-client.go deleted file mode 100644 index 879e0c31f8..0000000000 --- a/pkg/console/subresource/managedclusterview/oauth-client.go +++ /dev/null @@ -1,67 +0,0 @@ -package managedclusterview - -import ( - operatorv1 "github.com/openshift/api/operator/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime/schema" - - // openshift - - "github.com/openshift/console-operator/pkg/console/assets" - "github.com/openshift/console-operator/pkg/console/subresource/util" - // acm - TODO conflicts adding package to go.mod with several dependencies - // managedclusterviewv1beta1 "github.com/open-cluster-management/multicloud-operators-foundation/pkg/apis/action/v1beta1" -) - -func DefaultViewOAuthClient(cr *operatorv1.Console, cn string) *unstructured.Unstructured { - managedClusterView := ViewOAuthClientStub(cn) - withDefaultViewOAuthClientInfo(managedClusterView, cn) - return managedClusterView -} - -func withDefaultViewOAuthClientInfo(mcv *unstructured.Unstructured, cn string) { - unstructured.SetNestedField(mcv.Object, cn, "metadata", "namespace") -} - -func ViewOAuthClientStub(cn string) *unstructured.Unstructured { - return util.ReadUnstructuredOrDie(assets.MustAsset("managedclusterviews/console-managed-cluster-view-oauth-client.yaml")) -} - -func GetStatus(mcv *unstructured.Unstructured) (bool, error) { - conditions, found, err := unstructured.NestedSlice(mcv.Object, "status", "conditions") - if err != nil || !found || len(conditions) == 0 { - return false, err - } - - condition := conditions[0].(map[string]interface{}) - status := condition["status"].(string) - if status != "True" { - return false, err - } - - return true, nil -} - -func GetName(mcv *unstructured.Unstructured) (string, error) { - name, found, err := unstructured.NestedString(mcv.Object, "metadata", "name") - if err != nil || !found || name == "" { - return "", err - } - return name, nil -} - -func GetNamespace(mcv *unstructured.Unstructured) (string, error) { - namespace, found, err := unstructured.NestedString(mcv.Object, "metadata", "namespace") - if err != nil || !found || namespace == "" { - return "", err - } - return namespace, nil -} - -func GetGroupVersionResource() schema.GroupVersionResource { - return schema.GroupVersionResource{ - Group: "view.open-cluster-management.io", - Version: "v1beta1", - Resource: "managedclusterviews", - } -} diff --git a/pkg/console/subresource/managedclusterview/oauth_client.go b/pkg/console/subresource/managedclusterview/oauth_client.go new file mode 100644 index 0000000000..138346cfff --- /dev/null +++ b/pkg/console/subresource/managedclusterview/oauth_client.go @@ -0,0 +1,61 @@ +package managedclusterview + +import ( + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + utilerrors "k8s.io/apimachinery/pkg/util/errors" + + // openshift + + "github.com/openshift/console-operator/pkg/api" + "github.com/openshift/console-operator/pkg/console/assets" + "github.com/openshift/console-operator/pkg/console/subresource/util" + // acm - TODO conflicts adding package to go.mod with several dependencies + // managedclusterviewv1beta1 "github.com/open-cluster-management/multicloud-operators-foundation/pkg/apis/action/v1beta1" +) + +func DefaultOAuthClientView(cn string) (*unstructured.Unstructured, error) { + mcv := OAuthClientViewStub() + var errors []error + errors = append(errors, unstructured.SetNestedField(mcv.Object, api.OAuthClientManagedClusterViewName, "metadata", "name")) + errors = append(errors, unstructured.SetNestedField(mcv.Object, cn, "metadata", "namespace")) + errors = append(errors, unstructured.SetNestedStringMap(mcv.Object, util.LabelsForManagedClusterResources(cn), "metadata", "labels")) + aggregateErrors := utilerrors.NewAggregate(errors) + if aggregateErrors != nil { + return nil, aggregateErrors + } + return mcv, nil +} + +func OAuthClientViewStub() *unstructured.Unstructured { + return util.ReadUnstructuredOrDie(assets.MustAsset("managedclusterviews/console-oauth-client.yaml")) +} + +func GetStatus(mcv *unstructured.Unstructured) (bool, error) { + conditions, found, err := unstructured.NestedSlice(mcv.Object, "status", "conditions") + if err != nil || !found || len(conditions) == 0 { + return false, err + } + + condition := conditions[0].(map[string]interface{}) + status := condition["status"].(string) + if status != "True" { + return false, err + } + + return true, nil +} + +func GetName(mcv *unstructured.Unstructured) (string, error) { + name, _, err := unstructured.NestedString(mcv.Object, "metadata", "name") + return name, err +} + +func GetNamespace(mcv *unstructured.Unstructured) (string, error) { + namespace, _, err := unstructured.NestedString(mcv.Object, "metadata", "namespace") + return namespace, err +} + +func GetOAuthClientSecret(mcv *unstructured.Unstructured) (string, error) { + secret, _, err := unstructured.NestedString(mcv.Object, "status", "result", "secret") + return secret, err +} diff --git a/pkg/console/subresource/managedclusterview/oauth_server_cert.go b/pkg/console/subresource/managedclusterview/oauth_server_cert.go new file mode 100644 index 0000000000..153ec9170b --- /dev/null +++ b/pkg/console/subresource/managedclusterview/oauth_server_cert.go @@ -0,0 +1,39 @@ +package managedclusterview + +import ( + operatorv1 "github.com/openshift/api/operator/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + utilerrors "k8s.io/apimachinery/pkg/util/errors" + + // openshift + "github.com/openshift/console-operator/pkg/api" + "github.com/openshift/console-operator/pkg/console/assets" + "github.com/openshift/console-operator/pkg/console/subresource/util" + // acm - TODO conflicts adding package to go.mod with several dependencies + // managedclusterviewv1beta1 "github.com/open-cluster-management/multicloud-operators-foundation/pkg/apis/action/v1beta1" +) + +func DefaultOAuthServerCertView(cr *operatorv1.Console, cn string) (*unstructured.Unstructured, error) { + mcv := OAuthServerCertViewStub(cn) + var errors []error + errors = append(errors, unstructured.SetNestedField(mcv.Object, api.OAuthServerCertManagedClusterViewName, "metadata", "name")) + errors = append(errors, unstructured.SetNestedField(mcv.Object, cn, "metadata", "namespace")) + errors = append(errors, unstructured.SetNestedStringMap(mcv.Object, util.LabelsForManagedClusterResources(cn), "metadata", "labels")) + aggregateError := utilerrors.NewAggregate(errors) + if aggregateError != nil { + return nil, aggregateError + } + return mcv, nil +} + +func OAuthServerCertViewStub(cn string) *unstructured.Unstructured { + return util.ReadUnstructuredOrDie(assets.MustAsset("managedclusterviews/console-oauth-server-cert.yaml")) +} + +func GetCertBundle(mcv *unstructured.Unstructured) (string, error) { + cert, found, err := unstructured.NestedString(mcv.Object, "status", "result", "data", "ca-bundle.crt") + if err != nil || !found || cert == "" { + return "", err + } + return cert, nil +} diff --git a/pkg/console/subresource/util/util.go b/pkg/console/subresource/util/util.go index 529c2d9b8b..368a14dc1a 100644 --- a/pkg/console/subresource/util/util.go +++ b/pkg/console/subresource/util/util.go @@ -48,6 +48,12 @@ func LabelsForDownloads() map[string]string { } } +func LabelsForManagedClusterResources(managedClusterName string) map[string]string { + labels := SharedLabels() + labels[api.ManagedClusterLabel] = managedClusterName + return labels +} + func SharedMeta() metav1.ObjectMeta { return metav1.ObjectMeta{ Name: api.OpenShiftConsoleName, diff --git a/vendor/github.com/openshift/build-machinery-go/make/lib/golang.mk b/vendor/github.com/openshift/build-machinery-go/make/lib/golang.mk index 66f9a0029c..a6ebe6cd45 100644 --- a/vendor/github.com/openshift/build-machinery-go/make/lib/golang.mk +++ b/vendor/github.com/openshift/build-machinery-go/make/lib/golang.mk @@ -16,7 +16,7 @@ GOFMT ?=gofmt GOFMT_FLAGS ?=-s -l GOLINT ?=golint -go_version :=$(shell $(GO) version | sed -E -e 's/.*go([0-9]+.[0-9]+.[0-9]+).*/\1/') +go_version :=$(shell $(GO) version | sed -E -e 's/.*go([0-9]+.[0-9]+(.[0-9]+)?).*/\1/') GO_REQUIRED_MIN_VERSION ?=1.15.2 ifneq "$(GO_REQUIRED_MIN_VERSION)" "" $(call require_minimal_version,$(GO),GO_REQUIRED_MIN_VERSION,$(go_version)) diff --git a/vendor/github.com/openshift/build-machinery-go/make/targets/openshift/images.mk b/vendor/github.com/openshift/build-machinery-go/make/targets/openshift/images.mk index 47cc227948..c53c3f1b9a 100644 --- a/vendor/github.com/openshift/build-machinery-go/make/targets/openshift/images.mk +++ b/vendor/github.com/openshift/build-machinery-go/make/targets/openshift/images.mk @@ -1,3 +1,7 @@ +include $(addprefix $(dir $(lastword $(MAKEFILE_LIST))), \ + imagebuilder.mk \ +) + # IMAGE_BUILD_EXTRA_FLAGS lets you add extra flags for imagebuilder # e.g. to mount secrets and repo information into base image like: # make images IMAGE_BUILD_EXTRA_FLAGS='-mount ~/projects/origin-repos/4.2/:/etc/yum.repos.d/' diff --git a/vendor/github.com/openshift/build-machinery-go/make/targets/openshift/kustomize.mk b/vendor/github.com/openshift/build-machinery-go/make/targets/openshift/kustomize.mk index 7ff64334c2..79c26f9151 100644 --- a/vendor/github.com/openshift/build-machinery-go/make/targets/openshift/kustomize.mk +++ b/vendor/github.com/openshift/build-machinery-go/make/targets/openshift/kustomize.mk @@ -12,8 +12,13 @@ ensure-kustomize: ifeq "" "$(wildcard $(KUSTOMIZE))" $(info Installing kustomize into '$(KUSTOMIZE)') mkdir -p '$(kustomize_dir)' + @# install_kustomize.sh lays down the binary as `kustomize`, and will + @# also fail if a file of that name already exists. Remove it for + @# backward compatibility (older b-m-gs used the raw file name). + rm -f $(kustomize_dir)/kustomize @# NOTE: Pinning script to a tag rather than `master` for security reasons curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/kustomize/v$(KUSTOMIZE_VERSION)/hack/install_kustomize.sh" | bash -s $(KUSTOMIZE_VERSION) $(kustomize_dir) + mv $(kustomize_dir)/kustomize $(KUSTOMIZE) else $(info Using existing kustomize from "$(KUSTOMIZE)") endif diff --git a/vendor/github.com/openshift/build-machinery-go/make/targets/openshift/yaml-patch.mk b/vendor/github.com/openshift/build-machinery-go/make/targets/openshift/yaml-patch.mk index 1e62348a14..4a65f7b904 100644 --- a/vendor/github.com/openshift/build-machinery-go/make/targets/openshift/yaml-patch.mk +++ b/vendor/github.com/openshift/build-machinery-go/make/targets/openshift/yaml-patch.mk @@ -6,7 +6,7 @@ include $(addprefix $(dir $(lastword $(MAKEFILE_LIST))), \ ../../lib/tmp.mk \ ) -YAML_PATCH_VERSION ?=v0.0.10 +YAML_PATCH_VERSION ?=v0.0.11 YAML_PATCH ?=$(PERMANENT_TMP_GOPATH)/bin/yaml-patch-$(YAML_PATCH_VERSION) yaml_patch_dir :=$(dir $(YAML_PATCH)) @@ -15,7 +15,7 @@ ensure-yaml-patch: ifeq "" "$(wildcard $(YAML_PATCH))" $(info Installing yaml-patch into '$(YAML_PATCH)') mkdir -p '$(yaml_patch_dir)' - curl -s -f -L https://github.com/krishicks/yaml-patch/releases/download/$(YAML_PATCH_VERSION)/yaml_patch_$(GOHOSTOS) -o '$(YAML_PATCH)' + curl -s -f -L https://github.com/pivotal-cf/yaml-patch/releases/download/$(YAML_PATCH_VERSION)/yaml_patch_$(GOHOSTOS) -o '$(YAML_PATCH)' chmod +x '$(YAML_PATCH)'; else $(info Using existing yaml-patch from "$(YAML_PATCH)") diff --git a/vendor/modules.txt b/vendor/modules.txt index 59b91d9748..ab51c7e2b7 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -173,7 +173,7 @@ github.com/openshift/api/template github.com/openshift/api/template/v1 github.com/openshift/api/user github.com/openshift/api/user/v1 -# github.com/openshift/build-machinery-go v0.0.0-20210712174854-1bb7fd1518d3 +# github.com/openshift/build-machinery-go v0.0.0-20211213093930-7e33a7eb4ce3 ## explicit github.com/openshift/build-machinery-go github.com/openshift/build-machinery-go/make