diff --git a/deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml b/deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml index e5fef5e047..a78d2be671 100644 --- a/deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml +++ b/deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml @@ -91,6 +91,71 @@ spec: DeployOption contains the options of deploying a cluster-manager Default mode is used if DeployOption is not set. properties: + default: + description: Default includes configurations for clustermanager + in the Default mode + properties: + registrationWebhookConfiguration: + description: RegistrationWebhookConfiguration represents the + customized webhook-server configuration of registration. + properties: + healthProbeBindAddress: + default: :8000 + description: |- + HealthProbeBindAddress represents the healthcheck address of a webhook-server. The default value is ":8000". + Healthchecks may be disabled by setting a value of "0" or "". + type: string + hostNetwork: + description: |- + HostNetwork enables running webhook pods with hostNetwork: true + This may be required in some installations, such as EKS with Calico CNI, + to allow the API Server to communicate with the webhook pods. + type: boolean + metricsBindAddress: + default: :8080 + description: |- + MetricsBindAddress represents the metrics address of a webhook-server. The default value is ":8080" + Metrics may be disabled by setting a value of "0" or "". + type: string + port: + default: 9443 + description: Port represents the port of a webhook-server. + The default value of Port is 9443. + format: int32 + maximum: 65535 + type: integer + type: object + workWebhookConfiguration: + description: WorkWebhookConfiguration represents the customized + webhook-server configuration of work. + properties: + healthProbeBindAddress: + default: :8000 + description: |- + HealthProbeBindAddress represents the healthcheck address of a webhook-server. The default value is ":8000". + Healthchecks may be disabled by setting a value of "0" or "". + type: string + hostNetwork: + description: |- + HostNetwork enables running webhook pods with hostNetwork: true + This may be required in some installations, such as EKS with Calico CNI, + to allow the API Server to communicate with the webhook pods. + type: boolean + metricsBindAddress: + default: :8080 + description: |- + MetricsBindAddress represents the metrics address of a webhook-server. The default value is ":8080" + Metrics may be disabled by setting a value of "0" or "". + type: string + port: + default: 9443 + description: Port represents the port of a webhook-server. + The default value of Port is 9443. + format: int32 + maximum: 65535 + type: integer + type: object + type: object hosted: description: Hosted includes configurations we need for clustermanager in the Hosted mode. @@ -106,6 +171,24 @@ spec: The Address must be reachable by apiserver of the hub cluster. pattern: ^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$ type: string + healthProbeBindAddress: + default: :8000 + description: |- + HealthProbeBindAddress represents the healthcheck address of a webhook-server. The default value is ":8000". + Healthchecks may be disabled by setting a value of "0" or "". + type: string + hostNetwork: + description: |- + HostNetwork enables running webhook pods with hostNetwork: true + This may be required in some installations, such as EKS with Calico CNI, + to allow the API Server to communicate with the webhook pods. + type: boolean + metricsBindAddress: + default: :8080 + description: |- + MetricsBindAddress represents the metrics address of a webhook-server. The default value is ":8080" + Metrics may be disabled by setting a value of "0" or "". + type: string port: default: 443 description: Port represents the port of a webhook-server. @@ -127,6 +210,24 @@ spec: The Address must be reachable by apiserver of the hub cluster. pattern: ^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$ type: string + healthProbeBindAddress: + default: :8000 + description: |- + HealthProbeBindAddress represents the healthcheck address of a webhook-server. The default value is ":8000". + Healthchecks may be disabled by setting a value of "0" or "". + type: string + hostNetwork: + description: |- + HostNetwork enables running webhook pods with hostNetwork: true + This may be required in some installations, such as EKS with Calico CNI, + to allow the API Server to communicate with the webhook pods. + type: boolean + metricsBindAddress: + default: :8080 + description: |- + MetricsBindAddress represents the metrics address of a webhook-server. The default value is ":8080" + Metrics may be disabled by setting a value of "0" or "". + type: string port: default: 443 description: Port represents the port of a webhook-server. @@ -279,6 +380,12 @@ spec: items: type: string type: array + disableManagedIam: + description: |- + DisableManagedIam disables creation and management of IAM roles and policies on the hub. + If true, all AWS permissions for awsirsa registration must be managed manually by the administrator. + Used in cases where IAM permissions cannot be granted to OCM, or to run an EKS hub with non-aws spoke clusters. + type: boolean hubClusterArn: description: |- This represents the hub cluster ARN diff --git a/deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml b/deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml index e5fef5e047..a78d2be671 100644 --- a/deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml +++ b/deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml @@ -91,6 +91,71 @@ spec: DeployOption contains the options of deploying a cluster-manager Default mode is used if DeployOption is not set. properties: + default: + description: Default includes configurations for clustermanager + in the Default mode + properties: + registrationWebhookConfiguration: + description: RegistrationWebhookConfiguration represents the + customized webhook-server configuration of registration. + properties: + healthProbeBindAddress: + default: :8000 + description: |- + HealthProbeBindAddress represents the healthcheck address of a webhook-server. The default value is ":8000". + Healthchecks may be disabled by setting a value of "0" or "". + type: string + hostNetwork: + description: |- + HostNetwork enables running webhook pods with hostNetwork: true + This may be required in some installations, such as EKS with Calico CNI, + to allow the API Server to communicate with the webhook pods. + type: boolean + metricsBindAddress: + default: :8080 + description: |- + MetricsBindAddress represents the metrics address of a webhook-server. The default value is ":8080" + Metrics may be disabled by setting a value of "0" or "". + type: string + port: + default: 9443 + description: Port represents the port of a webhook-server. + The default value of Port is 9443. + format: int32 + maximum: 65535 + type: integer + type: object + workWebhookConfiguration: + description: WorkWebhookConfiguration represents the customized + webhook-server configuration of work. + properties: + healthProbeBindAddress: + default: :8000 + description: |- + HealthProbeBindAddress represents the healthcheck address of a webhook-server. The default value is ":8000". + Healthchecks may be disabled by setting a value of "0" or "". + type: string + hostNetwork: + description: |- + HostNetwork enables running webhook pods with hostNetwork: true + This may be required in some installations, such as EKS with Calico CNI, + to allow the API Server to communicate with the webhook pods. + type: boolean + metricsBindAddress: + default: :8080 + description: |- + MetricsBindAddress represents the metrics address of a webhook-server. The default value is ":8080" + Metrics may be disabled by setting a value of "0" or "". + type: string + port: + default: 9443 + description: Port represents the port of a webhook-server. + The default value of Port is 9443. + format: int32 + maximum: 65535 + type: integer + type: object + type: object hosted: description: Hosted includes configurations we need for clustermanager in the Hosted mode. @@ -106,6 +171,24 @@ spec: The Address must be reachable by apiserver of the hub cluster. pattern: ^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$ type: string + healthProbeBindAddress: + default: :8000 + description: |- + HealthProbeBindAddress represents the healthcheck address of a webhook-server. The default value is ":8000". + Healthchecks may be disabled by setting a value of "0" or "". + type: string + hostNetwork: + description: |- + HostNetwork enables running webhook pods with hostNetwork: true + This may be required in some installations, such as EKS with Calico CNI, + to allow the API Server to communicate with the webhook pods. + type: boolean + metricsBindAddress: + default: :8080 + description: |- + MetricsBindAddress represents the metrics address of a webhook-server. The default value is ":8080" + Metrics may be disabled by setting a value of "0" or "". + type: string port: default: 443 description: Port represents the port of a webhook-server. @@ -127,6 +210,24 @@ spec: The Address must be reachable by apiserver of the hub cluster. pattern: ^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$ type: string + healthProbeBindAddress: + default: :8000 + description: |- + HealthProbeBindAddress represents the healthcheck address of a webhook-server. The default value is ":8000". + Healthchecks may be disabled by setting a value of "0" or "". + type: string + hostNetwork: + description: |- + HostNetwork enables running webhook pods with hostNetwork: true + This may be required in some installations, such as EKS with Calico CNI, + to allow the API Server to communicate with the webhook pods. + type: boolean + metricsBindAddress: + default: :8080 + description: |- + MetricsBindAddress represents the metrics address of a webhook-server. The default value is ":8080" + Metrics may be disabled by setting a value of "0" or "". + type: string port: default: 443 description: Port represents the port of a webhook-server. @@ -279,6 +380,12 @@ spec: items: type: string type: array + disableManagedIam: + description: |- + DisableManagedIam disables creation and management of IAM roles and policies on the hub. + If true, all AWS permissions for awsirsa registration must be managed manually by the administrator. + Used in cases where IAM permissions cannot be granted to OCM, or to run an EKS hub with non-aws spoke clusters. + type: boolean hubClusterArn: description: |- This represents the hub cluster ARN diff --git a/deploy/cluster-manager/olm-catalog/latest/manifests/cluster-manager.clusterserviceversion.yaml b/deploy/cluster-manager/olm-catalog/latest/manifests/cluster-manager.clusterserviceversion.yaml index cdecced1ad..5c22f40bfc 100644 --- a/deploy/cluster-manager/olm-catalog/latest/manifests/cluster-manager.clusterserviceversion.yaml +++ b/deploy/cluster-manager/olm-catalog/latest/manifests/cluster-manager.clusterserviceversion.yaml @@ -59,7 +59,7 @@ metadata: categories: Integration & Delivery,OpenShift Optional certified: "false" containerImage: quay.io/open-cluster-management/registration-operator:latest - createdAt: "2025-05-29T02:56:45Z" + createdAt: "2025-06-12T23:20:27Z" description: Manages the installation and upgrade of the ClusterManager. operators.operatorframework.io/builder: operator-sdk-v1.32.0 operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 diff --git a/deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml b/deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml index 989586e683..0609f6d486 100644 --- a/deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml +++ b/deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml @@ -91,6 +91,71 @@ spec: DeployOption contains the options of deploying a cluster-manager Default mode is used if DeployOption is not set. properties: + default: + description: Default includes configurations for clustermanager + in the Default mode + properties: + registrationWebhookConfiguration: + description: RegistrationWebhookConfiguration represents the + customized webhook-server configuration of registration. + properties: + healthProbeBindAddress: + default: :8000 + description: |- + HealthProbeBindAddress represents the healthcheck address of a webhook-server. The default value is ":8000". + Healthchecks may be disabled by setting a value of "0" or "". + type: string + hostNetwork: + description: |- + HostNetwork enables running webhook pods with hostNetwork: true + This may be required in some installations, such as EKS with Calico CNI, + to allow the API Server to communicate with the webhook pods. + type: boolean + metricsBindAddress: + default: :8080 + description: |- + MetricsBindAddress represents the metrics address of a webhook-server. The default value is ":8080" + Metrics may be disabled by setting a value of "0" or "". + type: string + port: + default: 9443 + description: Port represents the port of a webhook-server. + The default value of Port is 9443. + format: int32 + maximum: 65535 + type: integer + type: object + workWebhookConfiguration: + description: WorkWebhookConfiguration represents the customized + webhook-server configuration of work. + properties: + healthProbeBindAddress: + default: :8000 + description: |- + HealthProbeBindAddress represents the healthcheck address of a webhook-server. The default value is ":8000". + Healthchecks may be disabled by setting a value of "0" or "". + type: string + hostNetwork: + description: |- + HostNetwork enables running webhook pods with hostNetwork: true + This may be required in some installations, such as EKS with Calico CNI, + to allow the API Server to communicate with the webhook pods. + type: boolean + metricsBindAddress: + default: :8080 + description: |- + MetricsBindAddress represents the metrics address of a webhook-server. The default value is ":8080" + Metrics may be disabled by setting a value of "0" or "". + type: string + port: + default: 9443 + description: Port represents the port of a webhook-server. + The default value of Port is 9443. + format: int32 + maximum: 65535 + type: integer + type: object + type: object hosted: description: Hosted includes configurations we need for clustermanager in the Hosted mode. @@ -279,6 +344,11 @@ spec: items: type: string type: array + disableManagedIam: + description: |- + DisableManagedIAM disables IAM role management in the hub. All required IAM roles + must be created by the administrator. + type: boolean hubClusterArn: description: |- This represents the hub cluster ARN diff --git a/deploy/klusterlet/chart/klusterlet/crds/0000_00_operator.open-cluster-management.io_klusterlets.crd.yaml b/deploy/klusterlet/chart/klusterlet/crds/0000_00_operator.open-cluster-management.io_klusterlets.crd.yaml index d515ca1163..4c71c41d0e 100644 --- a/deploy/klusterlet/chart/klusterlet/crds/0000_00_operator.open-cluster-management.io_klusterlets.crd.yaml +++ b/deploy/klusterlet/chart/klusterlet/crds/0000_00_operator.open-cluster-management.io_klusterlets.crd.yaml @@ -341,17 +341,20 @@ spec: minLength: 1 pattern: ^arn:aws:eks:([a-zA-Z0-9-]+):(\d{12}):cluster/([a-zA-Z0-9-]+)$ type: string + iamConfigSecret: + description: |- + IamConfigSecret is the name of a secret containing "config" and/or "credentials" files mounted to /.aws/config and /.aws/credentials respectively. + More Info: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html + type: string managedClusterArn: description: |- - The arn of the managed cluster (ie: an EKS cluster). This will be required to generate the md5hash which will be used as a suffix to create IAM role on hub + The arn of the managed cluster (ie: an EKS cluster). This will be used when managed IAM is enabled to generate the md5hash as a suffix to create IAM role on hub as well as used by kluslerlet-agent, to assume role suffixed with the md5hash, on startup. Example - arn:eks:us-west-2:12345678910:cluster/managed-cluster1. - minLength: 1 pattern: ^arn:aws:eks:([a-zA-Z0-9-]+):(\d{12}):cluster/([a-zA-Z0-9-]+)$ type: string required: - hubClusterArn - - managedClusterArn type: object required: - authType diff --git a/deploy/klusterlet/config/crds/0000_00_operator.open-cluster-management.io_klusterlets.crd.yaml b/deploy/klusterlet/config/crds/0000_00_operator.open-cluster-management.io_klusterlets.crd.yaml index d515ca1163..4c71c41d0e 100644 --- a/deploy/klusterlet/config/crds/0000_00_operator.open-cluster-management.io_klusterlets.crd.yaml +++ b/deploy/klusterlet/config/crds/0000_00_operator.open-cluster-management.io_klusterlets.crd.yaml @@ -341,17 +341,20 @@ spec: minLength: 1 pattern: ^arn:aws:eks:([a-zA-Z0-9-]+):(\d{12}):cluster/([a-zA-Z0-9-]+)$ type: string + iamConfigSecret: + description: |- + IamConfigSecret is the name of a secret containing "config" and/or "credentials" files mounted to /.aws/config and /.aws/credentials respectively. + More Info: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html + type: string managedClusterArn: description: |- - The arn of the managed cluster (ie: an EKS cluster). This will be required to generate the md5hash which will be used as a suffix to create IAM role on hub + The arn of the managed cluster (ie: an EKS cluster). This will be used when managed IAM is enabled to generate the md5hash as a suffix to create IAM role on hub as well as used by kluslerlet-agent, to assume role suffixed with the md5hash, on startup. Example - arn:eks:us-west-2:12345678910:cluster/managed-cluster1. - minLength: 1 pattern: ^arn:aws:eks:([a-zA-Z0-9-]+):(\d{12}):cluster/([a-zA-Z0-9-]+)$ type: string required: - hubClusterArn - - managedClusterArn type: object required: - authType diff --git a/deploy/klusterlet/olm-catalog/latest/manifests/klusterlet.clusterserviceversion.yaml b/deploy/klusterlet/olm-catalog/latest/manifests/klusterlet.clusterserviceversion.yaml index b68854d01d..99c6a20fa0 100644 --- a/deploy/klusterlet/olm-catalog/latest/manifests/klusterlet.clusterserviceversion.yaml +++ b/deploy/klusterlet/olm-catalog/latest/manifests/klusterlet.clusterserviceversion.yaml @@ -31,7 +31,7 @@ metadata: categories: Integration & Delivery,OpenShift Optional certified: "false" containerImage: quay.io/open-cluster-management/registration-operator:latest - createdAt: "2025-05-29T02:56:45Z" + createdAt: "2025-06-12T23:20:27Z" description: Manages the installation and upgrade of the Klusterlet. operators.operatorframework.io/builder: operator-sdk-v1.32.0 operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 diff --git a/go.mod b/go.mod index f94115bd5e..82e4f55225 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,9 @@ module open-cluster-management.io/ocm go 1.23.6 +// TODO: Remove before merge +replace open-cluster-management.io/api => github.com/bhperry/ocm-api v0.0.0-20250709173341-f336f4574c03 + require ( github.com/aws/aws-sdk-go-v2 v1.36.3 github.com/aws/aws-sdk-go-v2/config v1.29.14 diff --git a/go.sum b/go.sum index 1abd2cd671..2aee3a2034 100644 --- a/go.sum +++ b/go.sum @@ -58,6 +58,8 @@ github.com/aws/smithy-go v1.22.2 h1:6D9hW43xKFrRx/tXXfAlIZc4JI+yQe6snnWcQyxSyLQ= github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bhperry/ocm-api v0.0.0-20250709173341-f336f4574c03 h1:6fRvZreOtZAmxUAQopCsdhWlLk4lorhZEhB1E+839Zo= +github.com/bhperry/ocm-api v0.0.0-20250709173341-f336f4574c03/go.mod h1:/OeqXycNBZQoe3WG6ghuWsMgsKGuMZrK8ZpsU6gWL0Y= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0= @@ -491,8 +493,6 @@ k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6J k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= open-cluster-management.io/addon-framework v1.0.0 h1:ejTk4hPAJnwCSxQhY/tVDPg3SeH91lVfWqSaJcYiKwg= open-cluster-management.io/addon-framework v1.0.0/go.mod h1:Gw9zRGvuNJJ3XhTYanIuA7FFFw0EjtoE74l5OBZCZf8= -open-cluster-management.io/api v1.0.0 h1:54QllH9DTudCk6VrGt0q8CDsE3MghqJeTaTN4RHZpE0= -open-cluster-management.io/api v1.0.0/go.mod h1:/OeqXycNBZQoe3WG6ghuWsMgsKGuMZrK8ZpsU6gWL0Y= open-cluster-management.io/sdk-go v1.0.1-0.20250708024404-422b23814b5d h1:sYgNfYyQ6O7sfiVOUaMuoK/CTeWnTNTfVKY8dWORBgw= open-cluster-management.io/sdk-go v1.0.1-0.20250708024404-422b23814b5d/go.mod h1:LYX48E3h96XGnm6o+GomV0DSf15w1i9crtggj2HeDvI= sigs.k8s.io/about-api v0.0.0-20250131010323-518069c31c03 h1:1ShFiMjGQOR/8jTBkmZrk1gORxnvMwm1nOy2/DbHg4U= diff --git a/manifests/cluster-manager/hub/cluster-manager-registration-webhook-service.yaml b/manifests/cluster-manager/hub/cluster-manager-registration-webhook-service.yaml index 07781ea4b0..c7fc3423a3 100644 --- a/manifests/cluster-manager/hub/cluster-manager-registration-webhook-service.yaml +++ b/manifests/cluster-manager/hub/cluster-manager-registration-webhook-service.yaml @@ -14,5 +14,5 @@ spec: app: {{ .ClusterManagerName }}-registration-webhook ports: - name: webhook - port: 9443 - targetPort: 9443 + port: {{ .RegistrationWebhook.Port }} + targetPort: {{ .RegistrationWebhook.Port }} diff --git a/manifests/cluster-manager/hub/cluster-manager-work-webhook-service.yaml b/manifests/cluster-manager/hub/cluster-manager-work-webhook-service.yaml index c6ebdd4e95..52c1751210 100644 --- a/manifests/cluster-manager/hub/cluster-manager-work-webhook-service.yaml +++ b/manifests/cluster-manager/hub/cluster-manager-work-webhook-service.yaml @@ -14,5 +14,5 @@ spec: app: {{ .ClusterManagerName }}-work-webhook ports: - name: webhook - port: 9443 - targetPort: 9443 + port: {{ .WorkWebhook.Port }} + targetPort: {{ .WorkWebhook.Port }} diff --git a/manifests/cluster-manager/hub/cluster-manager-work-webhook-validatingconfiguration.yaml b/manifests/cluster-manager/hub/cluster-manager-work-webhook-validatingconfiguration.yaml index 695bbfea3c..fbce1e809b 100644 --- a/manifests/cluster-manager/hub/cluster-manager-work-webhook-validatingconfiguration.yaml +++ b/manifests/cluster-manager/hub/cluster-manager-work-webhook-validatingconfiguration.yaml @@ -17,8 +17,8 @@ webhooks: namespace: {{ .ClusterManagerNamespace }} name: cluster-manager-work-webhook path: /validate-work-open-cluster-management-io-v1-manifestwork - port: {{.RegistrationWebhook.Port}} - caBundle: {{ .RegistrationAPIServiceCABundle }} + port: {{.WorkWebhook.Port}} + caBundle: {{ .WorkAPIServiceCABundle }} rules: - operations: - CREATE diff --git a/manifests/cluster-manager/management/cluster-manager-registration-deployment.yaml b/manifests/cluster-manager/management/cluster-manager-registration-deployment.yaml index ffe0568a9b..b70d47ce98 100644 --- a/manifests/cluster-manager/management/cluster-manager-registration-deployment.yaml +++ b/manifests/cluster-manager/management/cluster-manager-registration-deployment.yaml @@ -92,6 +92,9 @@ spec: {{if .AwsResourceTags}} - "--aws-resource-tags={{ .AwsResourceTags }}" {{end}} + {{ if .DisableManagedIam }} + - "--disable-managed-iam" + {{ end }} env: - name: POD_NAME valueFrom: diff --git a/manifests/cluster-manager/management/cluster-manager-registration-webhook-deployment.yaml b/manifests/cluster-manager/management/cluster-manager-registration-webhook-deployment.yaml index 9ac61efe44..30429f9d82 100644 --- a/manifests/cluster-manager/management/cluster-manager-registration-webhook-deployment.yaml +++ b/manifests/cluster-manager/management/cluster-manager-registration-webhook-deployment.yaml @@ -12,6 +12,16 @@ metadata: {{ end }} spec: replicas: {{ .Replica }} + {{- if .RegistrationWebhook.HostNetwork }} + strategy: + rollingUpdate: + {{- if lt .Replica 4 }} + maxUnavailable: 1 + {{- else }} + maxUnavailable: 25% + {{- end }} + type: RollingUpdate + {{- end }} selector: matchLabels: app: {{ .ClusterManagerName }}-registration-webhook @@ -59,7 +69,9 @@ spec: args: - /registration - "webhook-server" - - "port=9443" + - "--port={{ .RegistrationWebhook.Port }}" + - "--health-probe-bind-address={{ .RegistrationWebhook.HealthProbeBindAddress }}" + - "--metrics-bind-address={{ .RegistrationWebhook.MetricsBindAddress }}" {{ if gt (len .RegistrationFeatureGates) 0 }} {{range .RegistrationFeatureGates}} - {{ . }} @@ -91,21 +103,23 @@ spec: privileged: false runAsNonRoot: true readOnlyRootFilesystem: true + {{- if gt .RegistrationWebhook.HealthProbePort 0 }} livenessProbe: httpGet: path: /healthz scheme: HTTP - port: 8000 + port: {{ .RegistrationWebhook.HealthProbePort }} initialDelaySeconds: 2 periodSeconds: 10 readinessProbe: httpGet: path: /readyz scheme: HTTP - port: 8000 + port: {{ .RegistrationWebhook.HealthProbePort }} initialDelaySeconds: 2 + {{- end }} ports: - - containerPort: 9443 + - containerPort: {{ .RegistrationWebhook.Port }} protocol: TCP volumeMounts: - mountPath: /tmp/k8s-webhook-server/serving-certs @@ -116,6 +130,10 @@ spec: name: kubeconfig readOnly: true {{ end }} + {{- if .RegistrationWebhook.HostNetwork }} + dnsPolicy: ClusterFirstWithHostNet + hostNetwork: true + {{- end }} volumes: - name: webhook-secret secret: diff --git a/manifests/cluster-manager/management/cluster-manager-work-webhook-deployment.yaml b/manifests/cluster-manager/management/cluster-manager-work-webhook-deployment.yaml index a0dee0975b..b680ae57fe 100644 --- a/manifests/cluster-manager/management/cluster-manager-work-webhook-deployment.yaml +++ b/manifests/cluster-manager/management/cluster-manager-work-webhook-deployment.yaml @@ -12,6 +12,16 @@ metadata: {{ end }} spec: replicas: {{ .Replica }} + {{- if .WorkWebhook.HostNetwork }} + strategy: + rollingUpdate: + {{- if lt .Replica 4 }} + maxUnavailable: 1 + {{- else }} + maxUnavailable: 25% + {{- end }} + type: RollingUpdate + {{- end }} selector: matchLabels: app: {{ .ClusterManagerName }}-work-webhook @@ -59,7 +69,9 @@ spec: args: - /work - "webhook-server" - - "port=9443" + - "--port={{ .WorkWebhook.Port }}" + - "--health-probe-bind-address={{ .WorkWebhook.HealthProbeBindAddress }}" + - "--metrics-bind-address={{ .WorkWebhook.MetricsBindAddress }}" {{ if gt (len .WorkFeatureGates) 0 }} {{range .WorkFeatureGates}} - {{ . }} @@ -76,19 +88,21 @@ spec: privileged: false runAsNonRoot: true readOnlyRootFilesystem: true + {{- if gt .WorkWebhook.HealthProbePort 0 }} livenessProbe: httpGet: path: /healthz scheme: HTTP - port: 8000 + port: {{ .WorkWebhook.HealthProbePort }} initialDelaySeconds: 2 periodSeconds: 10 readinessProbe: httpGet: path: /healthz scheme: HTTP - port: 8000 + port: {{ .WorkWebhook.HealthProbePort }} initialDelaySeconds: 2 + {{- end }} {{- if or (eq .ResourceRequirementResourceType "Default") (eq .ResourceRequirementResourceType "") }} resources: requests: @@ -103,7 +117,7 @@ spec: {{ .ResourceRequirements | indent 10 }} {{- end }} ports: - - containerPort: 9443 + - containerPort: {{ .WorkWebhook.Port }} protocol: TCP volumeMounts: - mountPath: /tmp/k8s-webhook-server/serving-certs @@ -114,6 +128,10 @@ spec: name: kubeconfig readOnly: true {{ end }} + {{- if .WorkWebhook.HostNetwork }} + dnsPolicy: ClusterFirstWithHostNet + hostNetwork: true + {{- end }} volumes: - name: webhook-secret secret: diff --git a/manifests/config.go b/manifests/config.go index 17d4400721..aa2f9c4066 100644 --- a/manifests/config.go +++ b/manifests/config.go @@ -1,6 +1,11 @@ package manifests -import operatorapiv1 "open-cluster-management.io/api/operator/v1" +import ( + "net" + "strconv" + + operatorapiv1 "open-cluster-management.io/api/operator/v1" +) type HubConfig struct { ClusterManagerName string @@ -34,6 +39,7 @@ type HubConfig struct { ResourceRequirements []byte ManagedClusterIdentityCreatorRole string HubClusterArn string + DisableManagedIam bool EnabledRegistrationDrivers string AutoApprovedCSRUsers string AutoApprovedARNPatterns string @@ -43,7 +49,38 @@ type HubConfig struct { } type Webhook struct { - IsIPFormat bool - Port int32 - Address string + IsIPFormat bool + HostNetwork bool + Port int32 + HealthProbeBindAddress string + MetricsBindAddress string + Address string +} + +func (w Webhook) HealthProbePort() int32 { + _, port, err := parseHostPort(w.HealthProbeBindAddress) + if err != nil { + return 0 + } + return port +} + +func (w Webhook) MetricsPort() int32 { + _, port, err := parseHostPort(w.MetricsBindAddress) + if err != nil { + return 0 + } + return port +} + +func parseHostPort(address string) (host string, port int32, err error) { + host, portStr, err := net.SplitHostPort(address) + if err != nil { + return host, port, err + } + port64, err := strconv.ParseInt(portStr, 10, 32) + if err != nil { + return host, port, err + } + return host, int32(port64), nil } diff --git a/manifests/klusterlet/management/klusterlet-agent-deployment.yaml b/manifests/klusterlet/management/klusterlet-agent-deployment.yaml index 759caae56f..dd7d427254 100644 --- a/manifests/klusterlet/management/klusterlet-agent-deployment.yaml +++ b/manifests/klusterlet/management/klusterlet-agent-deployment.yaml @@ -230,8 +230,14 @@ spec: - name: tmpdir emptyDir: { } {{if eq .RegistrationDriver.AuthType "awsirsa"}} + {{if and .RegistrationDriver.AwsIrsa .RegistrationDriver.AwsIrsa.IamConfigSecret }} + - name: dot-aws + secret: + secretName: {{ .RegistrationDriver.AwsIrsa.IamConfigSecret }} + {{else}} - name: dot-aws emptyDir: { } + {{end}} - name: awscli emptyDir: { } {{end}} diff --git a/manifests/klusterlet/management/klusterlet-registration-deployment.yaml b/manifests/klusterlet/management/klusterlet-registration-deployment.yaml index c3f1cb6467..7e239c1a7a 100644 --- a/manifests/klusterlet/management/klusterlet-registration-deployment.yaml +++ b/manifests/klusterlet/management/klusterlet-registration-deployment.yaml @@ -208,8 +208,14 @@ spec: - name: tmpdir emptyDir: { } {{if eq .RegistrationDriver.AuthType "awsirsa"}} + {{if and .RegistrationDriver.AwsIrsa .RegistrationDriver.AwsIrsa.IamConfigSecret }} + - name: dot-aws + secret: + secretName: {{ .RegistrationDriver.AwsIrsa.IamConfigSecret }} + {{else}} - name: dot-aws emptyDir: { } + {{end}} - name: awscli emptyDir: { } {{end}} diff --git a/manifests/klusterlet/management/klusterlet-work-deployment.yaml b/manifests/klusterlet/management/klusterlet-work-deployment.yaml index 4302158ffa..1f66d4831f 100644 --- a/manifests/klusterlet/management/klusterlet-work-deployment.yaml +++ b/manifests/klusterlet/management/klusterlet-work-deployment.yaml @@ -174,8 +174,14 @@ spec: - name: tmpdir emptyDir: { } {{if eq .RegistrationDriver.AuthType "awsirsa"}} + {{if and .RegistrationDriver.AwsIrsa .RegistrationDriver.AwsIrsa.IamConfigSecret }} + - name: dot-aws + secret: + secretName: {{ .RegistrationDriver.AwsIrsa.IamConfigSecret }} + {{else}} - name: dot-aws emptyDir: { } + {{end}} - name: awscli emptyDir: { } {{end}} diff --git a/pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go b/pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go index b0e8ffa529..ac472f2b64 100644 --- a/pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go +++ b/pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go @@ -41,8 +41,10 @@ import ( const ( clusterManagerFinalizer = "operator.open-cluster-management.io/cluster-manager-cleanup" - defaultWebhookPort = int32(9443) - clusterManagerReSyncTime = 5 * time.Second + defaultWebhookPort = int32(9443) + defaultHealthProbeBindAddr = ":8000" + defaultMetricsBindAddr = ":8080" + clusterManagerReSyncTime = 5 * time.Second ) type clusterManagerController struct { @@ -157,22 +159,19 @@ func (n *clusterManagerController) sync(ctx context.Context, controllerContext f } // This config is used to render template of manifests. + registrationWebhook, workWebhook := webhookConfigurations(clusterManager.Spec.DeployOption) config := manifests.HubConfig{ - ClusterManagerName: clusterManager.Name, - ClusterManagerNamespace: clusterManagerNamespace, - OperatorNamespace: n.operatorNamespace, - RegistrationImage: clusterManager.Spec.RegistrationImagePullSpec, - WorkImage: clusterManager.Spec.WorkImagePullSpec, - PlacementImage: clusterManager.Spec.PlacementImagePullSpec, - AddOnManagerImage: clusterManager.Spec.AddOnManagerImagePullSpec, - Replica: replica, - HostedMode: clusterManager.Spec.DeployOption.Mode == operatorapiv1.InstallModeHosted, - RegistrationWebhook: manifests.Webhook{ - Port: defaultWebhookPort, - }, - WorkWebhook: manifests.Webhook{ - Port: defaultWebhookPort, - }, + ClusterManagerName: clusterManager.Name, + ClusterManagerNamespace: clusterManagerNamespace, + OperatorNamespace: n.operatorNamespace, + RegistrationImage: clusterManager.Spec.RegistrationImagePullSpec, + WorkImage: clusterManager.Spec.WorkImagePullSpec, + PlacementImage: clusterManager.Spec.PlacementImagePullSpec, + AddOnManagerImage: clusterManager.Spec.AddOnManagerImagePullSpec, + Replica: replica, + HostedMode: clusterManager.Spec.DeployOption.Mode == operatorapiv1.InstallModeHosted, + RegistrationWebhook: registrationWebhook, + WorkWebhook: workWebhook, ResourceRequirementResourceType: helpers.ResourceType(clusterManager), ResourceRequirements: resourceRequirements, WorkDriver: string(workDriver), @@ -217,14 +216,6 @@ func (n *clusterManagerController) sync(ctx context.Context, controllerContext f // Compute and populate the value of managed cluster identity creator role to be used in cluster manager registration service account config.ManagedClusterIdentityCreatorRole = getIdentityCreatorRoleAndTags(*clusterManager) - // If we are deploying in the hosted mode, it requires us to create webhook in a different way with the default mode. - // In the hosted mode, the webhook servers is running in the management cluster but the users are accessing the hub cluster. - // So we need to add configuration to make the apiserver of the hub cluster could access the webhook servers on the management cluster. - if clusterManager.Spec.DeployOption.Hosted != nil { - config.RegistrationWebhook = convertWebhookConfiguration(clusterManager.Spec.DeployOption.Hosted.RegistrationWebhookConfiguration) - config.WorkWebhook = convertWebhookConfiguration(clusterManager.Spec.DeployOption.Hosted.WorkWebhookConfiguration) - } - config.Labels = helpers.GetClusterManagerHubLabels(clusterManager, n.enableSyncLabels) config.LabelsString = helpers.GetRegistrationLabelString(config.Labels) @@ -376,6 +367,10 @@ func ensureSAKubeconfigs(ctx context.Context, clusterManagerName, clusterManager // TODO: support IPV6 address func isIPFormat(address string) bool { + if address == "" { + return false + } + runes := []rune(address) for i := 0; i < len(runes); i++ { if (runes[i] < '0' || runes[i] > '9') && runes[i] != '.' { @@ -385,11 +380,52 @@ func isIPFormat(address string) bool { return true } -func convertWebhookConfiguration(webhookConfiguration operatorapiv1.WebhookConfiguration) manifests.Webhook { +func webhookConfigurations(deployOption operatorapiv1.ClusterManagerDeployOption) (registration, work manifests.Webhook) { + switch deployOption.Mode { + case operatorapiv1.InstallModeDefault: + if deployOption.Default != nil { + registration = convertDefaultWebhookConfiguration(deployOption.Default.RegistrationWebhookConfiguration) + work = convertDefaultWebhookConfiguration(deployOption.Default.WorkWebhookConfiguration) + return + } + case operatorapiv1.InstallModeHosted: + if deployOption.Hosted != nil { + registration = convertHostedWebhookConfiguration(deployOption.Hosted.RegistrationWebhookConfiguration) + work = convertHostedWebhookConfiguration(deployOption.Hosted.WorkWebhookConfiguration) + return + } + } + + registration = manifests.Webhook{ + Port: defaultWebhookPort, + HealthProbeBindAddress: defaultHealthProbeBindAddr, + MetricsBindAddress: defaultMetricsBindAddr, + } + work = manifests.Webhook{ + Port: defaultWebhookPort, + HealthProbeBindAddress: defaultHealthProbeBindAddr, + MetricsBindAddress: defaultMetricsBindAddr, + } + return +} + +func convertDefaultWebhookConfiguration(webhookConfiguration operatorapiv1.DefaultWebhookConfiguration) manifests.Webhook { + return manifests.Webhook{ + Port: webhookConfiguration.Port, + HealthProbeBindAddress: webhookConfiguration.HealthProbeBindAddress, + MetricsBindAddress: webhookConfiguration.MetricsBindAddress, + HostNetwork: webhookConfiguration.HostNetwork, + } +} + +func convertHostedWebhookConfiguration(webhookConfiguration operatorapiv1.HostedWebhookConfiguration) manifests.Webhook { return manifests.Webhook{ - Address: webhookConfiguration.Address, - Port: webhookConfiguration.Port, - IsIPFormat: isIPFormat(webhookConfiguration.Address), + Address: webhookConfiguration.Address, + IsIPFormat: isIPFormat(webhookConfiguration.Address), + Port: webhookConfiguration.Port, + HealthProbeBindAddress: webhookConfiguration.HealthProbeBindAddress, + MetricsBindAddress: webhookConfiguration.MetricsBindAddress, + HostNetwork: webhookConfiguration.HostNetwork, } } @@ -434,6 +470,9 @@ func getIdentityCreatorRoleAndTags(cm operatorapiv1.ClusterManager) string { if cm.Spec.RegistrationConfiguration != nil { for _, registrationDriver := range cm.Spec.RegistrationConfiguration.RegistrationDrivers { if registrationDriver.AuthType == commonhelper.AwsIrsaAuthType && registrationDriver.AwsIrsa != nil { + if registrationDriver.AwsIrsa.DisableManagedIam { + return "" + } hubClusterArn := registrationDriver.AwsIrsa.HubClusterArn hubClusterAccountId, hubClusterName := commonhelper.GetAwsAccountIdAndClusterName(hubClusterArn) return "arn:aws:iam::" + hubClusterAccountId + ":role/" + hubClusterName + "_managed-cluster-identity-creator" diff --git a/pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_runtime_reconcile.go b/pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_runtime_reconcile.go index 1835c573d0..818fc95460 100644 --- a/pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_runtime_reconcile.go +++ b/pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_runtime_reconcile.go @@ -82,6 +82,7 @@ func (c *runtimeReconcile) reconcile(ctx context.Context, cm *operatorapiv1.Clus config.HubClusterArn = registrationDriver.AwsIrsa.HubClusterArn config.AutoApprovedARNPatterns = strings.Join(registrationDriver.AwsIrsa.AutoApprovedIdentities, ",") config.AwsResourceTags = strings.Join(registrationDriver.AwsIrsa.Tags, ",") + config.DisableManagedIam = registrationDriver.AwsIrsa.DisableManagedIam } else if registrationDriver.AuthType == commonhelpers.CSRAuthType && registrationDriver.CSR != nil { config.AutoApprovedCSRUsers = strings.Join(registrationDriver.CSR.AutoApprovedIdentities, ",") } diff --git a/pkg/operator/operators/klusterlet/controllers/klusterletcontroller/klusterlet_controller.go b/pkg/operator/operators/klusterlet/controllers/klusterletcontroller/klusterlet_controller.go index 2d1399ca89..36ace489e9 100644 --- a/pkg/operator/operators/klusterlet/controllers/klusterletcontroller/klusterlet_controller.go +++ b/pkg/operator/operators/klusterlet/controllers/klusterletcontroller/klusterlet_controller.go @@ -115,6 +115,7 @@ func NewKlusterletController( type AwsIrsa struct { HubClusterArn string ManagedClusterArn string + IamConfigSecret string } type RegistrationDriver struct { @@ -127,6 +128,9 @@ type ManagedClusterIamRole struct { } func (managedClusterIamRole *ManagedClusterIamRole) arn() string { + if managedClusterIamRole.AwsIrsa.ManagedClusterArn == "" { + return "" + } managedClusterAccountId, managedClusterName := commonhelpers.GetAwsAccountIdAndClusterName(managedClusterIamRole.AwsIrsa.ManagedClusterArn) hubClusterAccountId, hubClusterName := commonhelpers.GetAwsAccountIdAndClusterName(managedClusterIamRole.AwsIrsa.HubClusterArn) md5HashUniqueIdentifier := commonhelpers.Md5HashSuffix(hubClusterAccountId, hubClusterName, managedClusterAccountId, managedClusterName) @@ -355,19 +359,27 @@ func (n *klusterletController) sync(ctx context.Context, controllerContext facto hubClusterArn := klusterlet.Spec.RegistrationConfiguration.RegistrationDriver.AwsIrsa.HubClusterArn managedClusterArn := klusterlet.Spec.RegistrationConfiguration.RegistrationDriver.AwsIrsa.ManagedClusterArn + iamConfigSecret := klusterlet.Spec.RegistrationConfiguration.RegistrationDriver.AwsIrsa.IamConfigSecret config.RegistrationDriver = RegistrationDriver{ AuthType: klusterlet.Spec.RegistrationConfiguration.RegistrationDriver.AuthType, AwsIrsa: &AwsIrsa{ HubClusterArn: hubClusterArn, ManagedClusterArn: managedClusterArn, + IamConfigSecret: iamConfigSecret, }, } managedClusterIamRole := ManagedClusterIamRole{ AwsIrsa: config.RegistrationDriver.AwsIrsa, } config.ManagedClusterRoleArn = managedClusterIamRole.arn() - managedClusterAccountId, managedClusterName := commonhelpers.GetAwsAccountIdAndClusterName(managedClusterIamRole.AwsIrsa.ManagedClusterArn) + var managedClusterAccountId, managedClusterName string + if managedClusterIamRole.AwsIrsa.ManagedClusterArn != "" { + managedClusterAccountId, managedClusterName = commonhelpers.GetAwsAccountIdAndClusterName(managedClusterIamRole.AwsIrsa.ManagedClusterArn) + } else { + // Klusterlet running in non-AWS cluster, no account ID + managedClusterName = config.ClusterName + } hubClusterAccountId, hubClusterName := commonhelpers.GetAwsAccountIdAndClusterName(managedClusterIamRole.AwsIrsa.HubClusterArn) config.ManagedClusterRoleSuffix = commonhelpers.Md5HashSuffix(hubClusterAccountId, hubClusterName, managedClusterAccountId, managedClusterName) } else { diff --git a/pkg/registration/hub/manager.go b/pkg/registration/hub/manager.go index 486248df0f..7cdcbacf33 100644 --- a/pkg/registration/hub/manager.go +++ b/pkg/registration/hub/manager.go @@ -59,6 +59,7 @@ type HubManagerOptions struct { AutoApprovedCSRUsers []string AutoApprovedARNPatterns []string AwsResourceTags []string + DisableManagedIam bool Labels string GRPCCAFile string GRPCCAKeyFile string @@ -89,6 +90,7 @@ func (m *HubManagerOptions) AddFlags(fs *pflag.FlagSet) { "The flag works only when ResourceCleanup feature gate is enable.") fs.StringVar(&m.HubClusterArn, "hub-cluster-arn", m.HubClusterArn, "Hub Cluster Arn required to connect to Hub and create IAM Roles and Policies") + fs.BoolVar(&m.DisableManagedIam, "disable-managed-iam", m.DisableManagedIam, "Disable IAM role and access entry management for spoke clusters") fs.StringSliceVar(&m.AutoApprovedCSRUsers, "auto-approved-csr-users", m.AutoApprovedCSRUsers, "A bootstrap user list whose cluster registration requests can be automatically approved.") fs.StringSliceVar(&m.AutoApprovedARNPatterns, "auto-approved-arn-patterns", m.AutoApprovedARNPatterns, @@ -195,7 +197,7 @@ func (m *HubManagerOptions) RunControllerManagerWithInformers( } drivers = append(drivers, csrDriver) case commonhelpers.AwsIrsaAuthType: - awsIRSAHubDriver, err := awsirsa.NewAWSIRSAHubDriver(ctx, m.HubClusterArn, m.AutoApprovedARNPatterns, m.AwsResourceTags) + awsIRSAHubDriver, err := awsirsa.NewAWSIRSAHubDriver(ctx, m.HubClusterArn, m.AutoApprovedARNPatterns, m.AwsResourceTags, m.DisableManagedIam) if err != nil { return err } diff --git a/pkg/registration/register/aws_irsa/aws_irsa.go b/pkg/registration/register/aws_irsa/aws_irsa.go index ce06b6bf2c..052813a56b 100644 --- a/pkg/registration/register/aws_irsa/aws_irsa.go +++ b/pkg/registration/register/aws_irsa/aws_irsa.go @@ -93,7 +93,9 @@ func (c *AWSIRSADriver) ManagedClusterDecorator(cluster *clusterv1.ManagedCluste if cluster.Annotations == nil { cluster.Annotations = make(map[string]string) } - cluster.Annotations[operatorv1.ClusterAnnotationsKeyPrefix+"/"+ManagedClusterArn] = c.managedClusterArn + if c.managedClusterArn != "" { + cluster.Annotations[operatorv1.ClusterAnnotationsKeyPrefix+"/"+ManagedClusterArn] = c.managedClusterArn + } cluster.Annotations[operatorv1.ClusterAnnotationsKeyPrefix+"/"+ManagedClusterIAMRoleSuffix] = c.managedClusterRoleSuffix return cluster } diff --git a/pkg/registration/register/aws_irsa/hub_driver.go b/pkg/registration/register/aws_irsa/hub_driver.go index cc86c4e68f..05393cf0ab 100644 --- a/pkg/registration/register/aws_irsa/hub_driver.go +++ b/pkg/registration/register/aws_irsa/hub_driver.go @@ -39,6 +39,7 @@ type AWSIRSAHubDriver struct { cfg aws.Config autoApprovedARNPatterns []*regexp.Regexp awsResourceTags []string + disableManagedIam bool } func (a *AWSIRSAHubDriver) Accept(cluster *clusterv1.ManagedCluster) bool { @@ -61,12 +62,16 @@ func (a *AWSIRSAHubDriver) Accept(cluster *clusterv1.ManagedCluster) bool { // Cleanup is run when the cluster is deleting or hubAcceptClient is set false func (c *AWSIRSAHubDriver) Cleanup(ctx context.Context, managedCluster *clusterv1.ManagedCluster) error { + logger := klog.FromContext(ctx) + if c.disableManagedIam { + logger.V(4).Info("No Op Cleanup since IAM management is disabled for awsirsa") + return nil + } + _, isManagedClusterIamRoleSuffixPresent := managedCluster.Annotations[operatorv1.ClusterAnnotationsKeyPrefix+"/"+ManagedClusterIAMRoleSuffix] _, isManagedClusterArnPresent := managedCluster.Annotations[operatorv1.ClusterAnnotationsKeyPrefix+"/"+ManagedClusterArn] - logger := klog.FromContext(ctx) - if !isManagedClusterArnPresent && !isManagedClusterIamRoleSuffixPresent { logger.V(4).Info("No Op Cleanup since managedcluster annotations are not present for awsirsa.") return nil @@ -110,6 +115,11 @@ func (a *AWSIRSAHubDriver) CreatePermissions(ctx context.Context, cluster *clust } logger.V(4).Info("ManagedCluster is joined using aws-irsa registration-auth", "ManagedCluster", cluster.Name) + if a.disableManagedIam { + logger.V(4).Info("IAM management disabled, no roles or access entries created", "ManagedCluster", cluster.Name) + return nil + } + // Create an EKS client eksClient := eks.NewFromConfig(a.cfg) hubClusterName, roleArn, err := createIAMRoleAndPolicy(ctx, a.hubClusterArn, cluster, a.cfg, a.awsResourceTags) @@ -146,7 +156,6 @@ func createIAMRoleAndPolicy(ctx context.Context, hubClusterArn string, managedCl managedClusterArn, isManagedClusterArnPresent := managedCluster.Annotations[operatorv1.ClusterAnnotationsKeyPrefix+"/"+ManagedClusterArn] hubAccountId, hubClusterName = commonhelpers.GetAwsAccountIdAndClusterName(hubClusterArn) - managedClusterAccountId, managedClusterName = commonhelpers.GetAwsAccountIdAndClusterName(managedClusterArn) roleName, roleArn, err := getRoleNameAndArn(ctx, managedCluster, cfg) if err != nil { @@ -155,6 +164,7 @@ func createIAMRoleAndPolicy(ctx context.Context, hubClusterArn string, managedCl } if hubClusterArn != "" && isManagedClusterIamRoleSuffixPresent && isManagedClusterArnPresent { + managedClusterAccountId, managedClusterName = commonhelpers.GetAwsAccountIdAndClusterName(managedClusterArn) // Check if hash is the same hash := commonhelpers.Md5HashSuffix(hubAccountId, hubClusterName, managedClusterAccountId, managedClusterName) @@ -360,7 +370,7 @@ func parseTagsForRolesAndPolicies(tags []string) ([]iamtypes.Tag, error) { } func NewAWSIRSAHubDriver(ctx context.Context, hubClusterArn string, autoApprovedIdentityPatterns []string, - awsResourceTags []string) (register.HubDriver, error) { + awsResourceTags []string, disableManagedIam bool) (register.HubDriver, error) { logger := klog.FromContext(ctx) cfg, err := config.LoadDefaultConfig(ctx) if err != nil { @@ -382,6 +392,7 @@ func NewAWSIRSAHubDriver(ctx context.Context, hubClusterArn string, autoApproved cfg: cfg, autoApprovedARNPatterns: compiledPatterns, awsResourceTags: awsResourceTags, + disableManagedIam: disableManagedIam, } return awsIRSADriverForHub, nil diff --git a/pkg/registration/register/aws_irsa/hub_driver_test.go b/pkg/registration/register/aws_irsa/hub_driver_test.go index 0d7f0ff81c..3dad445626 100644 --- a/pkg/registration/register/aws_irsa/hub_driver_test.go +++ b/pkg/registration/register/aws_irsa/hub_driver_test.go @@ -126,6 +126,7 @@ func TestAccept(t *testing.T) { "arn:aws:eks:us-west-2:123456789012:cluster/.*", "arn:aws:eks:us-west-1:123456789012:cluster/.*", }, []string{}, + false, ) if err != nil { @@ -146,7 +147,7 @@ func TestNewDriverValidation(t *testing.T) { // Test with an invalid manager cluster approval pattern _, err := NewAWSIRSAHubDriver(context.Background(), "arn:aws:eks:us-west-2:123456789012:cluster/hub-cluster", []string{ "arn:(aws:eks:us-west-2:123456789012:cluster/.*", // bad pattern - }, []string{}) + }, []string{}, false) if err == nil { t.Errorf("Error expected") } @@ -485,7 +486,7 @@ func TestCleanup(t *testing.T) { t.Fatal(err) } - awsIrsaHubDriver, err := NewAWSIRSAHubDriver(context.Background(), "arn:aws:eks:us-west-2:123456789012:cluster/hub-cluster", []string{}, []string{}) + awsIrsaHubDriver, err := NewAWSIRSAHubDriver(context.Background(), "arn:aws:eks:us-west-2:123456789012:cluster/hub-cluster", []string{}, []string{}, false) if err != nil { t.Errorf("error creating AWSIRSAHubDriver") return diff --git a/pkg/registration/webhook/option.go b/pkg/registration/webhook/option.go index 82ab745aeb..767f373d24 100644 --- a/pkg/registration/webhook/option.go +++ b/pkg/registration/webhook/option.go @@ -4,20 +4,28 @@ import "github.com/spf13/pflag" // Config contains the server (the webhook) cert and key. type Options struct { - Port int - CertDir string + Port int + MetricsBindAddr string + HealthProbeBindAddr string + CertDir string } // NewOptions constructs a new set of default options for webhook. func NewOptions() *Options { return &Options{ - Port: 9443, + Port: 9443, + MetricsBindAddr: ":8080", + HealthProbeBindAddr: ":8000", } } func (c *Options) AddFlags(fs *pflag.FlagSet) { fs.IntVar(&c.Port, "port", c.Port, "Port is the port that the webhook server serves at.") + fs.StringVar(&c.MetricsBindAddr, "metrics-bind-address", c.MetricsBindAddr, + "The address the metric endpoint binds to.") + fs.StringVar(&c.HealthProbeBindAddr, "health-probe-bind-address", c.HealthProbeBindAddr, + "The address the health probe endpoint binds to.") fs.StringVar(&c.CertDir, "certdir", c.CertDir, "CertDir is the directory that contains the server key and certificate. If not set, "+ "webhook server would look up the server key and certificate in {TempDir}/k8s-webhook-server/serving-certs") diff --git a/pkg/registration/webhook/start.go b/pkg/registration/webhook/start.go index e42d6402ea..79ad7e4faf 100644 --- a/pkg/registration/webhook/start.go +++ b/pkg/registration/webhook/start.go @@ -11,6 +11,7 @@ import ( "k8s.io/klog/v2" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/healthz" + "sigs.k8s.io/controller-runtime/pkg/metrics/server" "sigs.k8s.io/controller-runtime/pkg/webhook" clusterv1 "open-cluster-management.io/api/cluster/v1" @@ -36,7 +37,10 @@ func (c *Options) RunWebhookServer() error { mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ Scheme: scheme, - HealthProbeBindAddress: ":8000", + HealthProbeBindAddress: c.HealthProbeBindAddr, + Metrics: server.Options{ + BindAddress: c.MetricsBindAddr, + }, WebhookServer: webhook.NewServer(webhook.Options{ Port: c.Port, CertDir: c.CertDir, @@ -52,15 +56,17 @@ func (c *Options) RunWebhookServer() error { return err } - // add healthz/readyz check handler - if err := mgr.AddHealthzCheck("healthz-ping", healthz.Ping); err != nil { - logger.Error(err, "unable to add healthz check handler") - return err - } + if c.HealthProbeBindAddr != "" && c.HealthProbeBindAddr != "0" { + // add healthz/readyz check handler + if err := mgr.AddHealthzCheck("healthz-ping", healthz.Ping); err != nil { + logger.Error(err, "unable to add healthz check handler") + return err + } - if err := mgr.AddReadyzCheck("readyz-ping", healthz.Ping); err != nil { - logger.Error(err, "unable to add readyz check handler") - return err + if err := mgr.AddReadyzCheck("readyz-ping", healthz.Ping); err != nil { + logger.Error(err, "unable to add readyz check handler") + return err + } } if err = (&internalv1.ManagedClusterWebhook{}).Init(mgr); err != nil { diff --git a/pkg/work/webhook/option.go b/pkg/work/webhook/option.go index ae1090a458..44129a31ab 100644 --- a/pkg/work/webhook/option.go +++ b/pkg/work/webhook/option.go @@ -4,22 +4,30 @@ import "github.com/spf13/pflag" // Config contains the server (the webhook) cert and key. type Options struct { - Port int - CertDir string - ManifestLimit int + Port int + MetricsBindAddr string + HealthProbeBindAddr string + CertDir string + ManifestLimit int } // NewOptions constructs a new set of default options for webhook. func NewOptions() *Options { return &Options{ - Port: 9443, - ManifestLimit: 500 * 1024, // the default manifest limit is 500k. + Port: 9443, + MetricsBindAddr: ":8080", + HealthProbeBindAddr: ":8000", + ManifestLimit: 500 * 1024, // the default manifest limit is 500k. } } func (c *Options) AddFlags(fs *pflag.FlagSet) { fs.IntVar(&c.Port, "port", c.Port, "Port is the port that the webhook server serves at.") + fs.StringVar(&c.MetricsBindAddr, "metrics-bind-address", c.MetricsBindAddr, + "The address the metric endpoint binds to.") + fs.StringVar(&c.HealthProbeBindAddr, "health-probe-bind-address", c.HealthProbeBindAddr, + "The address the health probe endpoint binds to.") fs.StringVar(&c.CertDir, "certdir", c.CertDir, "CertDir is the directory that contains the server key and certificate. If not set, "+ "webhook server would look up the server key and certificate in {TempDir}/k8s-webhook-server/serving-certs") diff --git a/pkg/work/webhook/start.go b/pkg/work/webhook/start.go index db06cfef0f..ebd6aa61ae 100644 --- a/pkg/work/webhook/start.go +++ b/pkg/work/webhook/start.go @@ -13,6 +13,7 @@ import ( "k8s.io/klog/v2" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/healthz" + "sigs.k8s.io/controller-runtime/pkg/metrics/server" "sigs.k8s.io/controller-runtime/pkg/webhook" ocmfeature "open-cluster-management.io/api/feature" @@ -41,7 +42,10 @@ func (c *Options) RunWebhookServer() error { mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ Scheme: scheme, - HealthProbeBindAddress: ":8000", + HealthProbeBindAddress: c.HealthProbeBindAddr, + Metrics: server.Options{ + BindAddress: c.MetricsBindAddr, + }, WebhookServer: webhook.NewServer(webhook.Options{ TLSOpts: []func(config *tls.Config){ func(config *tls.Config) { @@ -57,15 +61,17 @@ func (c *Options) RunWebhookServer() error { return err } - // add healthz/readyz check handler - if err := mgr.AddHealthzCheck("healthz-ping", healthz.Ping); err != nil { - logger.Error(err, "unable to add healthz check handler") - return err - } + if c.HealthProbeBindAddr != "" && c.HealthProbeBindAddr != "0" { + // add healthz/readyz check handler + if err := mgr.AddHealthzCheck("healthz-ping", healthz.Ping); err != nil { + logger.Error(err, "unable to add healthz check handler") + return err + } - if err := mgr.AddReadyzCheck("readyz-ping", healthz.Ping); err != nil { - logger.Error(err, "unable to add readyz check handler") - return err + if err := mgr.AddReadyzCheck("readyz-ping", healthz.Ping); err != nil { + logger.Error(err, "unable to add readyz check handler") + return err + } } common.ManifestValidator.WithLimit(c.ManifestLimit) diff --git a/test/integration/operator/integration_suite_test.go b/test/integration/operator/integration_suite_test.go index bea6e7b9af..c2ea1c999b 100644 --- a/test/integration/operator/integration_suite_test.go +++ b/test/integration/operator/integration_suite_test.go @@ -167,11 +167,11 @@ var _ = ginkgo.BeforeSuite(func() { DeployOption: operatorapiv1.ClusterManagerDeployOption{ Mode: operatorapiv1.InstallModeHosted, Hosted: &operatorapiv1.HostedClusterManagerConfiguration{ - RegistrationWebhookConfiguration: operatorapiv1.WebhookConfiguration{ + RegistrationWebhookConfiguration: operatorapiv1.HostedWebhookConfiguration{ Address: "localhost", Port: 443, }, - WorkWebhookConfiguration: operatorapiv1.WebhookConfiguration{ + WorkWebhookConfiguration: operatorapiv1.HostedWebhookConfiguration{ Address: "localhost", Port: 443, }, diff --git a/vendor/modules.txt b/vendor/modules.txt index 91571cdf8a..1e0b1f0b92 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1718,7 +1718,7 @@ open-cluster-management.io/addon-framework/pkg/agent open-cluster-management.io/addon-framework/pkg/assets open-cluster-management.io/addon-framework/pkg/index open-cluster-management.io/addon-framework/pkg/utils -# open-cluster-management.io/api v1.0.0 +# open-cluster-management.io/api v1.0.0 => github.com/bhperry/ocm-api v0.0.0-20250709173341-f336f4574c03 ## explicit; go 1.23.6 open-cluster-management.io/api/addon/v1alpha1 open-cluster-management.io/api/client/addon/clientset/versioned @@ -1948,3 +1948,4 @@ sigs.k8s.io/structured-merge-diff/v4/value sigs.k8s.io/yaml sigs.k8s.io/yaml/goyaml.v2 sigs.k8s.io/yaml/goyaml.v3 +# open-cluster-management.io/api => github.com/bhperry/ocm-api v0.0.0-20250709173341-f336f4574c03 diff --git a/vendor/open-cluster-management.io/api/operator/v1/0000_00_operator.open-cluster-management.io_klusterlets.crd.yaml b/vendor/open-cluster-management.io/api/operator/v1/0000_00_operator.open-cluster-management.io_klusterlets.crd.yaml index d515ca1163..4c71c41d0e 100644 --- a/vendor/open-cluster-management.io/api/operator/v1/0000_00_operator.open-cluster-management.io_klusterlets.crd.yaml +++ b/vendor/open-cluster-management.io/api/operator/v1/0000_00_operator.open-cluster-management.io_klusterlets.crd.yaml @@ -341,17 +341,20 @@ spec: minLength: 1 pattern: ^arn:aws:eks:([a-zA-Z0-9-]+):(\d{12}):cluster/([a-zA-Z0-9-]+)$ type: string + iamConfigSecret: + description: |- + IamConfigSecret is the name of a secret containing "config" and/or "credentials" files mounted to /.aws/config and /.aws/credentials respectively. + More Info: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html + type: string managedClusterArn: description: |- - The arn of the managed cluster (ie: an EKS cluster). This will be required to generate the md5hash which will be used as a suffix to create IAM role on hub + The arn of the managed cluster (ie: an EKS cluster). This will be used when managed IAM is enabled to generate the md5hash as a suffix to create IAM role on hub as well as used by kluslerlet-agent, to assume role suffixed with the md5hash, on startup. Example - arn:eks:us-west-2:12345678910:cluster/managed-cluster1. - minLength: 1 pattern: ^arn:aws:eks:([a-zA-Z0-9-]+):(\d{12}):cluster/([a-zA-Z0-9-]+)$ type: string required: - hubClusterArn - - managedClusterArn type: object required: - authType diff --git a/vendor/open-cluster-management.io/api/operator/v1/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml b/vendor/open-cluster-management.io/api/operator/v1/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml index e5fef5e047..a78d2be671 100644 --- a/vendor/open-cluster-management.io/api/operator/v1/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml +++ b/vendor/open-cluster-management.io/api/operator/v1/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml @@ -91,6 +91,71 @@ spec: DeployOption contains the options of deploying a cluster-manager Default mode is used if DeployOption is not set. properties: + default: + description: Default includes configurations for clustermanager + in the Default mode + properties: + registrationWebhookConfiguration: + description: RegistrationWebhookConfiguration represents the + customized webhook-server configuration of registration. + properties: + healthProbeBindAddress: + default: :8000 + description: |- + HealthProbeBindAddress represents the healthcheck address of a webhook-server. The default value is ":8000". + Healthchecks may be disabled by setting a value of "0" or "". + type: string + hostNetwork: + description: |- + HostNetwork enables running webhook pods with hostNetwork: true + This may be required in some installations, such as EKS with Calico CNI, + to allow the API Server to communicate with the webhook pods. + type: boolean + metricsBindAddress: + default: :8080 + description: |- + MetricsBindAddress represents the metrics address of a webhook-server. The default value is ":8080" + Metrics may be disabled by setting a value of "0" or "". + type: string + port: + default: 9443 + description: Port represents the port of a webhook-server. + The default value of Port is 9443. + format: int32 + maximum: 65535 + type: integer + type: object + workWebhookConfiguration: + description: WorkWebhookConfiguration represents the customized + webhook-server configuration of work. + properties: + healthProbeBindAddress: + default: :8000 + description: |- + HealthProbeBindAddress represents the healthcheck address of a webhook-server. The default value is ":8000". + Healthchecks may be disabled by setting a value of "0" or "". + type: string + hostNetwork: + description: |- + HostNetwork enables running webhook pods with hostNetwork: true + This may be required in some installations, such as EKS with Calico CNI, + to allow the API Server to communicate with the webhook pods. + type: boolean + metricsBindAddress: + default: :8080 + description: |- + MetricsBindAddress represents the metrics address of a webhook-server. The default value is ":8080" + Metrics may be disabled by setting a value of "0" or "". + type: string + port: + default: 9443 + description: Port represents the port of a webhook-server. + The default value of Port is 9443. + format: int32 + maximum: 65535 + type: integer + type: object + type: object hosted: description: Hosted includes configurations we need for clustermanager in the Hosted mode. @@ -106,6 +171,24 @@ spec: The Address must be reachable by apiserver of the hub cluster. pattern: ^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$ type: string + healthProbeBindAddress: + default: :8000 + description: |- + HealthProbeBindAddress represents the healthcheck address of a webhook-server. The default value is ":8000". + Healthchecks may be disabled by setting a value of "0" or "". + type: string + hostNetwork: + description: |- + HostNetwork enables running webhook pods with hostNetwork: true + This may be required in some installations, such as EKS with Calico CNI, + to allow the API Server to communicate with the webhook pods. + type: boolean + metricsBindAddress: + default: :8080 + description: |- + MetricsBindAddress represents the metrics address of a webhook-server. The default value is ":8080" + Metrics may be disabled by setting a value of "0" or "". + type: string port: default: 443 description: Port represents the port of a webhook-server. @@ -127,6 +210,24 @@ spec: The Address must be reachable by apiserver of the hub cluster. pattern: ^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$ type: string + healthProbeBindAddress: + default: :8000 + description: |- + HealthProbeBindAddress represents the healthcheck address of a webhook-server. The default value is ":8000". + Healthchecks may be disabled by setting a value of "0" or "". + type: string + hostNetwork: + description: |- + HostNetwork enables running webhook pods with hostNetwork: true + This may be required in some installations, such as EKS with Calico CNI, + to allow the API Server to communicate with the webhook pods. + type: boolean + metricsBindAddress: + default: :8080 + description: |- + MetricsBindAddress represents the metrics address of a webhook-server. The default value is ":8080" + Metrics may be disabled by setting a value of "0" or "". + type: string port: default: 443 description: Port represents the port of a webhook-server. @@ -279,6 +380,12 @@ spec: items: type: string type: array + disableManagedIam: + description: |- + DisableManagedIam disables creation and management of IAM roles and policies on the hub. + If true, all AWS permissions for awsirsa registration must be managed manually by the administrator. + Used in cases where IAM permissions cannot be granted to OCM, or to run an EKS hub with non-aws spoke clusters. + type: boolean hubClusterArn: description: |- This represents the hub cluster ARN diff --git a/vendor/open-cluster-management.io/api/operator/v1/types_clustermanager.go b/vendor/open-cluster-management.io/api/operator/v1/types_clustermanager.go index abfdc9b07d..36e7beaa74 100644 --- a/vendor/open-cluster-management.io/api/operator/v1/types_clustermanager.go +++ b/vendor/open-cluster-management.io/api/operator/v1/types_clustermanager.go @@ -151,6 +151,12 @@ type AwsIrsaConfig struct { // +optional AutoApprovedIdentities []string `json:"autoApprovedIdentities,omitempty"` + // DisableManagedIam disables creation and management of IAM roles and policies on the hub. + // If true, all AWS permissions for awsirsa registration must be managed manually by the administrator. + // Used in cases where IAM permissions cannot be granted to OCM, or to run an EKS hub with non-aws spoke clusters. + // +optional + DisableManagedIam bool `json:"disableManagedIam,omitempty"` + // List of tags to be added to AWS resources created by hub while processing awsirsa registration request // Example - "product:v1:tenant:app-name=My-App" // +optional @@ -232,19 +238,62 @@ const ( FeatureGateModeTypeDisable FeatureGateModeType = "Disable" ) +// DefaultClusterManagerConfiguration represents customized configurations for clustermanager in the Default mode +type DefaultClusterManagerConfiguration struct { + // RegistrationWebhookConfiguration represents the customized webhook-server configuration of registration. + // +optional + RegistrationWebhookConfiguration DefaultWebhookConfiguration `json:"registrationWebhookConfiguration,omitempty"` + + // WorkWebhookConfiguration represents the customized webhook-server configuration of work. + // +optional + WorkWebhookConfiguration DefaultWebhookConfiguration `json:"workWebhookConfiguration,omitempty"` +} + // HostedClusterManagerConfiguration represents customized configurations we need to set for clustermanager in the Hosted mode. type HostedClusterManagerConfiguration struct { // RegistrationWebhookConfiguration represents the customized webhook-server configuration of registration. // +optional - RegistrationWebhookConfiguration WebhookConfiguration `json:"registrationWebhookConfiguration,omitempty"` + RegistrationWebhookConfiguration HostedWebhookConfiguration `json:"registrationWebhookConfiguration,omitempty"` // WorkWebhookConfiguration represents the customized webhook-server configuration of work. // +optional - WorkWebhookConfiguration WebhookConfiguration `json:"workWebhookConfiguration,omitempty"` + WorkWebhookConfiguration HostedWebhookConfiguration `json:"workWebhookConfiguration,omitempty"` } -// WebhookConfiguration has two properties: Address and Port. +// WebhookConfiguration represents customization of webhook servers type WebhookConfiguration struct { + // HealthProbeBindAddress represents the healthcheck address of a webhook-server. The default value is ":8000". + // Healthchecks may be disabled by setting a value of "0" or "". + // +optional + // +kubebuilder:default=":8000" + HealthProbeBindAddress string `json:"healthProbeBindAddress"` + + // MetricsBindAddress represents the metrics address of a webhook-server. The default value is ":8080" + // Metrics may be disabled by setting a value of "0" or "". + // +optional + // +kubebuilder:default=":8080" + MetricsBindAddress string `json:"metricsBindAddress"` + + // HostNetwork enables running webhook pods with hostNetwork: true + // This may be required in some installations, such as EKS with Calico CNI, + // to allow the API Server to communicate with the webhook pods. + // +optional + HostNetwork bool `json:"hostNetwork,omitempty"` +} + +// DefaultWebhookConfiguration represents customization of webhook servers running in default installation mode +type DefaultWebhookConfiguration struct { + // Port represents the port of a webhook-server. The default value of Port is 9443. + // +optional + // +kubebuilder:default=9443 + // +kubebuilder:validation:Maximum=65535 + Port int32 `json:"port,omitempty"` + + WebhookConfiguration `json:",inline"` +} + +// HostedWebhookConfiguration represents customization of webhook servers running in hosted installation mode +type HostedWebhookConfiguration struct { // Address represents the address of a webhook-server. // It could be in IP format or fqdn format. // The Address must be reachable by apiserver of the hub cluster. @@ -258,6 +307,8 @@ type WebhookConfiguration struct { // +kubebuilder:default=443 // +kubebuilder:validation:Maximum=65535 Port int32 `json:"port,omitempty"` + + WebhookConfiguration `json:",inline"` } // ClusterManagerDeployOption describes the deployment options for cluster-manager @@ -274,6 +325,10 @@ type ClusterManagerDeployOption struct { // +kubebuilder:validation:Enum=Default;Hosted Mode InstallMode `json:"mode,omitempty"` + // Default includes configurations for clustermanager in the Default mode + // +optional + Default *DefaultClusterManagerConfiguration `json:"default,omitempty"` + // Hosted includes configurations we need for clustermanager in the Hosted mode. // +optional Hosted *HostedClusterManagerConfiguration `json:"hosted,omitempty"` diff --git a/vendor/open-cluster-management.io/api/operator/v1/types_klusterlet.go b/vendor/open-cluster-management.io/api/operator/v1/types_klusterlet.go index faa87f1d39..b97cb31d81 100644 --- a/vendor/open-cluster-management.io/api/operator/v1/types_klusterlet.go +++ b/vendor/open-cluster-management.io/api/operator/v1/types_klusterlet.go @@ -218,13 +218,16 @@ type AwsIrsa struct { // +kubebuilder:validation:MinLength=1 // +kubebuilder:validation:Pattern=`^arn:aws:eks:([a-zA-Z0-9-]+):(\d{12}):cluster/([a-zA-Z0-9-]+)$` HubClusterArn string `json:"hubClusterArn"` - // The arn of the managed cluster (ie: an EKS cluster). This will be required to generate the md5hash which will be used as a suffix to create IAM role on hub + // The arn of the managed cluster (ie: an EKS cluster). This will be used when managed IAM is enabled to generate the md5hash as a suffix to create IAM role on hub // as well as used by kluslerlet-agent, to assume role suffixed with the md5hash, on startup. // Example - arn:eks:us-west-2:12345678910:cluster/managed-cluster1. - // +required - // +kubebuilder:validation:MinLength=1 + // +optional // +kubebuilder:validation:Pattern=`^arn:aws:eks:([a-zA-Z0-9-]+):(\d{12}):cluster/([a-zA-Z0-9-]+)$` ManagedClusterArn string `json:"managedClusterArn"` + + // IamConfigSecret is the name of a secret containing "config" and/or "credentials" files mounted to /.aws/config and /.aws/credentials respectively. + // More Info: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html + IamConfigSecret string `json:"iamConfigSecret"` } type TypeBootstrapKubeConfigs string diff --git a/vendor/open-cluster-management.io/api/operator/v1/zz_generated.deepcopy.go b/vendor/open-cluster-management.io/api/operator/v1/zz_generated.deepcopy.go index af3ca25844..619c09d25c 100644 --- a/vendor/open-cluster-management.io/api/operator/v1/zz_generated.deepcopy.go +++ b/vendor/open-cluster-management.io/api/operator/v1/zz_generated.deepcopy.go @@ -168,6 +168,11 @@ func (in *ClusterManager) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterManagerDeployOption) DeepCopyInto(out *ClusterManagerDeployOption) { *out = *in + if in.Default != nil { + in, out := &in.Default, &out.Default + *out = new(DefaultClusterManagerConfiguration) + **out = **in + } if in.Hosted != nil { in, out := &in.Hosted, &out.Hosted *out = new(HostedClusterManagerConfiguration) @@ -290,6 +295,41 @@ func (in *ClusterManagerStatus) DeepCopy() *ClusterManagerStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DefaultClusterManagerConfiguration) DeepCopyInto(out *DefaultClusterManagerConfiguration) { + *out = *in + out.RegistrationWebhookConfiguration = in.RegistrationWebhookConfiguration + out.WorkWebhookConfiguration = in.WorkWebhookConfiguration + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DefaultClusterManagerConfiguration. +func (in *DefaultClusterManagerConfiguration) DeepCopy() *DefaultClusterManagerConfiguration { + if in == nil { + return nil + } + out := new(DefaultClusterManagerConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DefaultWebhookConfiguration) DeepCopyInto(out *DefaultWebhookConfiguration) { + *out = *in + out.WebhookConfiguration = in.WebhookConfiguration + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DefaultWebhookConfiguration. +func (in *DefaultWebhookConfiguration) DeepCopy() *DefaultWebhookConfiguration { + if in == nil { + return nil + } + out := new(DefaultWebhookConfiguration) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *FeatureGate) DeepCopyInto(out *FeatureGate) { *out = *in @@ -340,6 +380,23 @@ func (in *HostedClusterManagerConfiguration) DeepCopy() *HostedClusterManagerCon return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HostedWebhookConfiguration) DeepCopyInto(out *HostedWebhookConfiguration) { + *out = *in + out.WebhookConfiguration = in.WebhookConfiguration + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostedWebhookConfiguration. +func (in *HostedWebhookConfiguration) DeepCopy() *HostedWebhookConfiguration { + if in == nil { + return nil + } + out := new(HostedWebhookConfiguration) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HubApiServerHostAlias) DeepCopyInto(out *HubApiServerHostAlias) { *out = *in diff --git a/vendor/open-cluster-management.io/api/operator/v1/zz_generated.swagger_doc_generated.go b/vendor/open-cluster-management.io/api/operator/v1/zz_generated.swagger_doc_generated.go index 49e19c5741..34bbddf067 100644 --- a/vendor/open-cluster-management.io/api/operator/v1/zz_generated.swagger_doc_generated.go +++ b/vendor/open-cluster-management.io/api/operator/v1/zz_generated.swagger_doc_generated.go @@ -22,6 +22,7 @@ func (AddOnManagerConfiguration) SwaggerDoc() map[string]string { var map_AwsIrsaConfig = map[string]string{ "hubClusterArn": "This represents the hub cluster ARN Example - arn:eks:us-west-2:12345678910:cluster/hub-cluster1", "autoApprovedIdentities": "AutoApprovedIdentities represent a list of approved arn patterns", + "disableManagedIam": "DisableManagedIam disables creation and management of IAM roles and policies on the hub. If true, all AWS permissions for awsirsa registration must be managed manually by the administrator. Used in cases where IAM permissions cannot be granted to OCM, or to run an EKS hub with non-aws spoke clusters.", "tags": "List of tags to be added to AWS resources created by hub while processing awsirsa registration request Example - \"product:v1:tenant:app-name=My-App\"", } @@ -48,9 +49,10 @@ func (ClusterManager) SwaggerDoc() map[string]string { } var map_ClusterManagerDeployOption = map[string]string{ - "": "ClusterManagerDeployOption describes the deployment options for cluster-manager", - "mode": "Mode can be Default or Hosted. In Default mode, the Hub is installed as a whole and all parts of Hub are deployed in the same cluster. In Hosted mode, only crd and configurations are installed on one cluster(defined as hub-cluster). Controllers run in another cluster (defined as management-cluster) and connect to the hub with the kubeconfig in secret of \"external-hub-kubeconfig\"(a kubeconfig of hub-cluster with cluster-admin permission). Note: Do not modify the Mode field once it's applied.", - "hosted": "Hosted includes configurations we need for clustermanager in the Hosted mode.", + "": "ClusterManagerDeployOption describes the deployment options for cluster-manager", + "mode": "Mode can be Default or Hosted. In Default mode, the Hub is installed as a whole and all parts of Hub are deployed in the same cluster. In Hosted mode, only crd and configurations are installed on one cluster(defined as hub-cluster). Controllers run in another cluster (defined as management-cluster) and connect to the hub with the kubeconfig in secret of \"external-hub-kubeconfig\"(a kubeconfig of hub-cluster with cluster-admin permission). Note: Do not modify the Mode field once it's applied.", + "default": "Default includes configurations for clustermanager in the Default mode", + "hosted": "Hosted includes configurations we need for clustermanager in the Hosted mode.", } func (ClusterManagerDeployOption) SwaggerDoc() map[string]string { @@ -97,6 +99,25 @@ func (ClusterManagerStatus) SwaggerDoc() map[string]string { return map_ClusterManagerStatus } +var map_DefaultClusterManagerConfiguration = map[string]string{ + "": "DefaultClusterManagerConfiguration represents customized configurations for clustermanager in the Default mode", + "registrationWebhookConfiguration": "RegistrationWebhookConfiguration represents the customized webhook-server configuration of registration.", + "workWebhookConfiguration": "WorkWebhookConfiguration represents the customized webhook-server configuration of work.", +} + +func (DefaultClusterManagerConfiguration) SwaggerDoc() map[string]string { + return map_DefaultClusterManagerConfiguration +} + +var map_DefaultWebhookConfiguration = map[string]string{ + "": "DefaultWebhookConfiguration represents customization of webhook servers running in default installation mode", + "port": "Port represents the port of a webhook-server. The default value of Port is 9443.", +} + +func (DefaultWebhookConfiguration) SwaggerDoc() map[string]string { + return map_DefaultWebhookConfiguration +} + var map_FeatureGate = map[string]string{ "feature": "Feature is the key of feature gate. e.g. featuregate/Foo.", "mode": "Mode is either Enable, Disable, \"\" where \"\" is Disable by default. In Enable mode, a valid feature gate `featuregate/Foo` will be set to \"--featuregate/Foo=true\". In Disable mode, a valid feature gate `featuregate/Foo` will be set to \"--featuregate/Foo=false\".", @@ -130,6 +151,16 @@ func (HostedClusterManagerConfiguration) SwaggerDoc() map[string]string { return map_HostedClusterManagerConfiguration } +var map_HostedWebhookConfiguration = map[string]string{ + "": "HostedWebhookConfiguration represents customization of webhook servers running in hosted installation mode", + "address": "Address represents the address of a webhook-server. It could be in IP format or fqdn format. The Address must be reachable by apiserver of the hub cluster.", + "port": "Port represents the port of a webhook-server. The default value of Port is 443.", +} + +func (HostedWebhookConfiguration) SwaggerDoc() map[string]string { + return map_HostedWebhookConfiguration +} + var map_NodePlacement = map[string]string{ "": "NodePlacement describes node scheduling configuration for the pods.", "nodeSelector": "NodeSelector defines which Nodes the Pods are scheduled on. The default is an empty list.", @@ -174,9 +205,10 @@ func (RelatedResourceMeta) SwaggerDoc() map[string]string { } var map_WebhookConfiguration = map[string]string{ - "": "WebhookConfiguration has two properties: Address and Port.", - "address": "Address represents the address of a webhook-server. It could be in IP format or fqdn format. The Address must be reachable by apiserver of the hub cluster.", - "port": "Port represents the port of a webhook-server. The default value of Port is 443.", + "": "WebhookConfiguration represents customization of webhook servers", + "healthProbeBindAddress": "HealthProbeBindAddress represents the healthcheck address of a webhook-server. The default value is \":8000\". Healthchecks may be disabled by setting a value of \"0\" or \"\".", + "metricsBindAddress": "MetricsBindAddress represents the metrics address of a webhook-server. The default value is \":8080\" Metrics may be disabled by setting a value of \"0\" or \"\".", + "hostNetwork": "HostNetwork enables running webhook pods with hostNetwork: true This may be required in some installations, such as EKS with Calico CNI, to allow the API Server to communicate with the webhook pods.", } func (WebhookConfiguration) SwaggerDoc() map[string]string { @@ -194,7 +226,8 @@ func (WorkConfiguration) SwaggerDoc() map[string]string { var map_AwsIrsa = map[string]string{ "hubClusterArn": "The arn of the hub cluster (ie: an EKS cluster). This will be required to pass information to hub, which hub will use to create IAM identities for this klusterlet. Example - arn:eks:us-west-2:12345678910:cluster/hub-cluster1.", - "managedClusterArn": "The arn of the managed cluster (ie: an EKS cluster). This will be required to generate the md5hash which will be used as a suffix to create IAM role on hub as well as used by kluslerlet-agent, to assume role suffixed with the md5hash, on startup. Example - arn:eks:us-west-2:12345678910:cluster/managed-cluster1.", + "managedClusterArn": "The arn of the managed cluster (ie: an EKS cluster). This will be used when managed IAM is enabled to generate the md5hash as a suffix to create IAM role on hub as well as used by kluslerlet-agent, to assume role suffixed with the md5hash, on startup. Example - arn:eks:us-west-2:12345678910:cluster/managed-cluster1.", + "iamConfigSecret": "IamConfigSecret is the name of a secret containing \"config\" and/or \"credentials\" files mounted to /.aws/config and /.aws/credentials respectively. More Info: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html", } func (AwsIrsa) SwaggerDoc() map[string]string { diff --git a/vendor/open-cluster-management.io/api/work/v1/types.go b/vendor/open-cluster-management.io/api/work/v1/types.go index 2e74ef9057..9e3d4c6c02 100644 --- a/vendor/open-cluster-management.io/api/work/v1/types.go +++ b/vendor/open-cluster-management.io/api/work/v1/types.go @@ -503,6 +503,16 @@ const ( // WorkDegraded represents that the current state of work does not match // the desired state for a certain period. WorkDegraded string = "Degraded" + // WorkComplete represents that the work has completed and should no longer + // be updated. + WorkComplete string = "Complete" +) + +// Work condition reasons +const ( + // WorkManifestsComplete represents that all completable manifests in the work + // have the Complete condition + WorkManifestsComplete string = "ManifestsComplete" ) // ManifestCondition represents the conditions of the resources deployed on a @@ -596,7 +606,10 @@ const ( ManifestComplete string = "Complete" ) -// Condition reasons +// Manifest condition reasons +// +// All reasons set by condition rule evaluation are expected to be prefixed with "ConditionRule" +// in order to determine which conditions were set by rules. const ( // ConditionRuleTrue is set when a rule is evaluated without error ConditionRuleEvaluated string = "ConditionRuleEvaluated"