diff --git a/.github/workflows/envtest-kube.yaml b/.github/workflows/envtest-kube.yaml index 0717d402fda4..eb6b3f15628e 100644 --- a/.github/workflows/envtest-kube.yaml +++ b/.github/workflows/envtest-kube.yaml @@ -41,7 +41,7 @@ jobs: if [ "$EVENT_NAME" = "pull_request" ]; then ref="$PR_DIFF_REF" fi - if git diff --name-only "$ref" | grep -qE '^(api/|test/envtest/|cmd/install/assets/crds/hypershift-operator/tests/|\.github/workflows/envtest-kube\.yaml$)'; then + if git diff --name-only "$ref" | grep -qE '^(api/|test/envtest/|cmd/install/assets/crds/hypershift-operator/tests/|karpenter-operator/controllers/karpenter/assets/tests/|\.github/workflows/envtest-kube\.yaml$)'; then echo "should_run=true" else echo "should_run=false" diff --git a/.github/workflows/envtest-ocp.yaml b/.github/workflows/envtest-ocp.yaml index 28002e8291e5..45bf504d79d6 100644 --- a/.github/workflows/envtest-ocp.yaml +++ b/.github/workflows/envtest-ocp.yaml @@ -41,7 +41,7 @@ jobs: if [ "$EVENT_NAME" = "pull_request" ]; then ref="$PR_DIFF_REF" fi - if git diff --name-only "$ref" | grep -qE '^(api/|test/envtest/|cmd/install/assets/crds/hypershift-operator/tests/|\.github/workflows/envtest-ocp\.yaml$)'; then + if git diff --name-only "$ref" | grep -qE '^(api/|test/envtest/|cmd/install/assets/crds/hypershift-operator/tests/|karpenter-operator/controllers/karpenter/assets/tests/|\.github/workflows/envtest-ocp\.yaml$)'; then echo "should_run=true" else echo "should_run=false" diff --git a/Makefile b/Makefile index 46bfbf6c80e7..3ed7879c16ea 100644 --- a/Makefile +++ b/Makefile @@ -199,6 +199,7 @@ karpenter-api: $(CONTROLLER_GEN) $(YQ) karpenter-operator/hack/crds-sync.sh karpenter-operator/hack/adjust-cel.sh $(CONTROLLER_GEN) $(CRD_OPTIONS) paths="./api/karpenter/..." output:crd:artifacts:config=karpenter-operator/controllers/karpenter/assets + cp karpenter-operator/controllers/karpenter/assets/karpenter.hypershift.openshift.io_openshiftec2nodeclasses.yaml karpenter-operator/controllers/karpenter/assets/zz_generated.crd-manifests/openshiftec2nodeclasses.crd.yaml .PHONY: control-plane-operator control-plane-operator: diff --git a/api/.golangci.yml b/api/.golangci.yml index 80e2916f9de2..822c8a8d9b61 100644 --- a/api/.golangci.yml +++ b/api/.golangci.yml @@ -202,11 +202,6 @@ linters: - kubeapilinter path: hypershift/v1beta1/openstack.go text: 'arrayofstruct: OpenStackPlatformSpec.Subnets is an array of structs, but the struct has no required fields. At least one field should be marked as required to prevent ambiguous YAML configurations' - - linters: - - kubeapilinter - path: karpenter/v1beta1/karpenter_types.go - text: 'arrayofstruct: OpenshiftEC2NodeClassSpec.CapacityReservationSelectorTerms is an array of structs, but the struct has no required fields. At least one field should be marked as required to prevent ambiguous YAML configurations' - # conditions (1 issue) - linters: - kubeapilinter diff --git a/api/hypershift/v1beta1/featuregates/featureGate-Hypershift-Default.yaml b/api/hypershift/v1beta1/featuregates/featureGate-Hypershift-Default.yaml index 9b77b0a53630..49e57fef36f1 100644 --- a/api/hypershift/v1beta1/featuregates/featureGate-Hypershift-Default.yaml +++ b/api/hypershift/v1beta1/featuregates/featureGate-Hypershift-Default.yaml @@ -15,9 +15,6 @@ "featureGates": [ { "disabled": [ - { - "name": "AutoNodeKarpenter", - }, { "name": "AROHCPManagedIdentities" }, diff --git a/api/hypershift/v1beta1/featuregates/featureGate-Hypershift-TechPreviewNoUpgrade.yaml b/api/hypershift/v1beta1/featuregates/featureGate-Hypershift-TechPreviewNoUpgrade.yaml index 6bf6115cb585..39a658ee9697 100644 --- a/api/hypershift/v1beta1/featuregates/featureGate-Hypershift-TechPreviewNoUpgrade.yaml +++ b/api/hypershift/v1beta1/featuregates/featureGate-Hypershift-TechPreviewNoUpgrade.yaml @@ -16,9 +16,6 @@ { "disabled": [], "enabled": [ - { - "name": "AutoNodeKarpenter", - }, { "name": "ExternalOIDC" }, diff --git a/api/hypershift/v1beta1/featuregates/featureGate-SelfManagedHA-Default.yaml b/api/hypershift/v1beta1/featuregates/featureGate-SelfManagedHA-Default.yaml index e39f3861a86f..fd5c9fe89f9d 100644 --- a/api/hypershift/v1beta1/featuregates/featureGate-SelfManagedHA-Default.yaml +++ b/api/hypershift/v1beta1/featuregates/featureGate-SelfManagedHA-Default.yaml @@ -15,9 +15,6 @@ "featureGates": [ { "disabled": [ - { - "name": "AutoNodeKarpenter", - }, { "name": "ExternalOIDCWithUpstreamParity" }, diff --git a/api/hypershift/v1beta1/featuregates/featureGate-SelfManagedHA-TechPreviewNoUpgrade.yaml b/api/hypershift/v1beta1/featuregates/featureGate-SelfManagedHA-TechPreviewNoUpgrade.yaml index be4bd6ea1c9e..0de2b3b93ba2 100644 --- a/api/hypershift/v1beta1/featuregates/featureGate-SelfManagedHA-TechPreviewNoUpgrade.yaml +++ b/api/hypershift/v1beta1/featuregates/featureGate-SelfManagedHA-TechPreviewNoUpgrade.yaml @@ -16,9 +16,6 @@ { "disabled": [], "enabled": [ - { - "name": "AutoNodeKarpenter", - }, { "name": "ExternalOIDC" }, diff --git a/api/hypershift/v1beta1/hosted_controlplane.go b/api/hypershift/v1beta1/hosted_controlplane.go index 585a3b3d4193..8486514f0a18 100644 --- a/api/hypershift/v1beta1/hosted_controlplane.go +++ b/api/hypershift/v1beta1/hosted_controlplane.go @@ -230,9 +230,8 @@ type HostedControlPlaneSpec struct { // using the specified provisioner (e.g. Karpenter) instead of requiring // manual NodePool management. // - // +openshift:enable:FeatureGate=AutoNodeKarpenter // +optional - AutoNode *AutoNode `json:"autoNode,omitempty"` + AutoNode AutoNode `json:"autoNode,omitzero"` // nodeSelector when specified, must be true for the pods managed by the HostedCluster to be scheduled. // @@ -414,7 +413,6 @@ type HostedControlPlaneStatus struct { NodeCount *int `json:"nodeCount,omitempty"` // autoNode contains the observed state of the autoNode (Karpenter) provisioner. - // +openshift:enable:FeatureGate=AutoNodeKarpenter // +optional AutoNode AutoNodeStatus `json:"autoNode,omitzero"` diff --git a/api/hypershift/v1beta1/hostedcluster_types.go b/api/hypershift/v1beta1/hostedcluster_types.go index d99f765f090f..8d4db6c2bb34 100644 --- a/api/hypershift/v1beta1/hostedcluster_types.go +++ b/api/hypershift/v1beta1/hostedcluster_types.go @@ -642,9 +642,8 @@ type HostedClusterSpec struct { // autoNode specifies the configuration for automatic node provisioning and lifecycle management. // When set, the provisioner(e.g. Karpenter) will be used to provision nodes for targeted workloads. // - // +openshift:enable:FeatureGate=AutoNodeKarpenter // +optional - AutoNode *AutoNode `json:"autoNode,omitempty"` + AutoNode AutoNode `json:"autoNode,omitzero"` // etcd specifies configuration for the control plane etcd cluster. The // default managementType is Managed. Once set, the managementType cannot be @@ -1398,7 +1397,7 @@ type ProvisionerConfig struct { // // +optional // +unionMember - Karpenter *KarpenterConfig `json:"karpenter,omitempty"` + Karpenter KarpenterConfig `json:"karpenter,omitzero"` } // KarpenterConfig specifies the configuration for the Karpenter provisioner @@ -1418,7 +1417,7 @@ type KarpenterConfig struct { // // +optional // +unionMember - AWS *KarpenterAWSConfig `json:"aws,omitempty"` + AWS KarpenterAWSConfig `json:"aws,omitzero"` } // KarpenterAWSConfig specifies AWS-specific configuration for the Karpenter provisioner. @@ -2174,7 +2173,6 @@ type HostedClusterStatus struct { Platform *PlatformStatus `json:"platform,omitempty"` // autoNode contains the observed state of the autoNode (Karpenter) provisioner. - // +openshift:enable:FeatureGate=AutoNodeKarpenter // +optional AutoNode AutoNodeStatus `json:"autoNode,omitzero"` diff --git a/api/hypershift/v1beta1/zz_generated.deepcopy.go b/api/hypershift/v1beta1/zz_generated.deepcopy.go index 558be0746f8f..0f69bb3bcdeb 100644 --- a/api/hypershift/v1beta1/zz_generated.deepcopy.go +++ b/api/hypershift/v1beta1/zz_generated.deepcopy.go @@ -558,7 +558,7 @@ func (in *AllocationPool) DeepCopy() *AllocationPool { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AutoNode) DeepCopyInto(out *AutoNode) { *out = *in - in.Provisioner.DeepCopyInto(&out.Provisioner) + out.Provisioner = in.Provisioner } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AutoNode. @@ -2305,11 +2305,7 @@ func (in *HostedClusterSpec) DeepCopyInto(out *HostedClusterSpec) { in.DNS.DeepCopyInto(&out.DNS) in.Networking.DeepCopyInto(&out.Networking) in.Autoscaling.DeepCopyInto(&out.Autoscaling) - if in.AutoNode != nil { - in, out := &in.AutoNode, &out.AutoNode - *out = new(AutoNode) - (*in).DeepCopyInto(*out) - } + out.AutoNode = in.AutoNode in.Etcd.DeepCopyInto(&out.Etcd) if in.Services != nil { in, out := &in.Services, &out.Services @@ -2583,11 +2579,7 @@ func (in *HostedControlPlaneSpec) DeepCopyInto(out *HostedControlPlaneSpec) { **out = **in } in.Autoscaling.DeepCopyInto(&out.Autoscaling) - if in.AutoNode != nil { - in, out := &in.AutoNode, &out.AutoNode - *out = new(AutoNode) - (*in).DeepCopyInto(*out) - } + out.AutoNode = in.AutoNode if in.NodeSelector != nil { in, out := &in.NodeSelector, &out.NodeSelector *out = make(map[string]string, len(*in)) @@ -2910,11 +2902,7 @@ func (in *KarpenterAWSConfig) DeepCopy() *KarpenterAWSConfig { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KarpenterConfig) DeepCopyInto(out *KarpenterConfig) { *out = *in - if in.AWS != nil { - in, out := &in.AWS, &out.AWS - *out = new(KarpenterAWSConfig) - **out = **in - } + out.AWS = in.AWS } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KarpenterConfig. @@ -4211,11 +4199,7 @@ func (in *PowerVSVPC) DeepCopy() *PowerVSVPC { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ProvisionerConfig) DeepCopyInto(out *ProvisionerConfig) { *out = *in - if in.Karpenter != nil { - in, out := &in.Karpenter, &out.Karpenter - *out = new(KarpenterConfig) - (*in).DeepCopyInto(*out) - } + out.Karpenter = in.Karpenter } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProvisionerConfig. diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests.yaml index e4be0c29179b..ae4043f97aa0 100644 --- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests.yaml +++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests.yaml @@ -204,7 +204,6 @@ hostedclusters.hypershift.openshift.io: Capability: "" Category: "" FeatureGates: - - AutoNodeKarpenter - ClusterUpdateAcceptRisks - ClusterVersionOperatorConfiguration - ExternalOIDC @@ -278,7 +277,6 @@ hostedcontrolplanes.hypershift.openshift.io: Capability: "" Category: cluster-api FeatureGates: - - AutoNodeKarpenter - ClusterUpdateAcceptRisks - ClusterVersionOperatorConfiguration - ExternalOIDC diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AAA_ungated.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AAA_ungated.yaml index ee9f79007604..1abed4220a44 100644 --- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AAA_ungated.yaml +++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AAA_ungated.yaml @@ -124,6 +124,142 @@ spec: type: string type: object x-kubernetes-map-type: atomic + autoNode: + description: |- + autoNode specifies the configuration for automatic node provisioning and lifecycle management. + When set, the provisioner(e.g. Karpenter) will be used to provision nodes for targeted workloads. + properties: + provisionerConfig: + description: provisionerConfig specifies the provisioner used + for automatic node management. + properties: + karpenter: + description: karpenter specifies the configuration for the + Karpenter provisioner. + properties: + aws: + description: aws specifies the AWS-specific configuration + for Karpenter. + properties: + roleARN: + description: "roleARN specifies the ARN of the IAM + role that Karpenter assumes to provision\nand manage + EC2 instances in the hosted cluster's AWS account.\n\nThe + referenced role must have a trust relationship that + allows it to be assumed\nby the karpenter service + account in the hosted cluster via OIDC.\nExample:\n{\n\t\"Version\": + \"2012-10-17\",\n\t\"Statement\": [\n\t\t{\n\t\t\t\"Effect\": + \"Allow\",\n\t\t\t\"Principal\": {\n\t\t\t\t\"Federated\": + \"\"\n\t\t\t},\n\t\t\t\"Action\": + \"sts:AssumeRoleWithWebIdentity\",\n\t\t\t\"Condition\": + {\n\t\t\t\t\"StringEquals\": {\n\t\t\t\t\t\":sub\": + \"system:serviceaccount:kube-system:karpenter\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t]\n}\n\nThe + following is an example of the policy document for + this role.\n\n{\n\t\"Version\": \"2012-10-17\",\n\t\"Statement\": + [\n\t\t{\n\t\t\t\"Sid\": \"AllowScopedEC2InstanceAccessActions\",\n\t\t\t\"Effect\": + \"Allow\",\n\t\t\t\"Resource\": [\n\t\t\t\t\"arn:*:ec2:*::image/*\",\n\t\t\t\t\"arn:*:ec2:*::snapshot/*\",\n\t\t\t\t\"arn:*:ec2:*:*:security-group/*\",\n\t\t\t\t\"arn:*:ec2:*:*:subnet/*\"\n\t\t\t],\n\t\t\t\"Action\": + [\n\t\t\t\t\"ec2:RunInstances\",\n\t\t\t\t\"ec2:CreateFleet\"\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"Sid\": + \"AllowScopedEC2LaunchTemplateAccessActions\",\n\t\t\t\"Effect\": + \"Allow\",\n\t\t\t\"Resource\": \"arn:*:ec2:*:*:launch-template/*\",\n\t\t\t\"Action\": + [\n\t\t\t\t\"ec2:RunInstances\",\n\t\t\t\t\"ec2:CreateFleet\"\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"Sid\": + \"AllowScopedEC2InstanceActionsWithTags\",\n\t\t\t\"Effect\": + \"Allow\",\n\t\t\t\"Resource\": [\n\t\t\t\t\"arn:*:ec2:*:*:fleet/*\",\n\t\t\t\t\"arn:*:ec2:*:*:instance/*\",\n\t\t\t\t\"arn:*:ec2:*:*:volume/*\",\n\t\t\t\t\"arn:*:ec2:*:*:network-interface/*\",\n\t\t\t\t\"arn:*:ec2:*:*:launch-template/*\",\n\t\t\t\t\"arn:*:ec2:*:*:spot-instances-request/*\"\n\t\t\t],\n\t\t\t\"Action\": + [\n\t\t\t\t\"ec2:RunInstances\",\n\t\t\t\t\"ec2:CreateFleet\",\n\t\t\t\t\"ec2:CreateLaunchTemplate\"\n\t\t\t],\n\t\t\t\"Condition\": + {\n\t\t\t\t\"StringLike\": {\n\t\t\t\t\t\"aws:RequestTag/karpenter.sh/nodepool\": + \"*\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"Sid\": + \"AllowScopedResourceCreationTagging\",\n\t\t\t\"Effect\": + \"Allow\",\n\t\t\t\"Resource\": [\n\t\t\t\t\"arn:*:ec2:*:*:fleet/*\",\n\t\t\t\t\"arn:*:ec2:*:*:instance/*\",\n\t\t\t\t\"arn:*:ec2:*:*:volume/*\",\n\t\t\t\t\"arn:*:ec2:*:*:network-interface/*\",\n\t\t\t\t\"arn:*:ec2:*:*:launch-template/*\",\n\t\t\t\t\"arn:*:ec2:*:*:spot-instances-request/*\"\n\t\t\t],\n\t\t\t\"Action\": + \"ec2:CreateTags\",\n\t\t\t\"Condition\": {\n\t\t\t\t\"StringEquals\": + {\n\t\t\t\t\t\"ec2:CreateAction\": [\n\t\t\t\t\t\t\"RunInstances\",\n\t\t\t\t\t\t\"CreateFleet\",\n\t\t\t\t\t\t\"CreateLaunchTemplate\"\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t\"StringLike\": + {\n\t\t\t\t\t\"aws:RequestTag/karpenter.sh/nodepool\": + \"*\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"Sid\": + \"AllowScopedResourceTagging\",\n\t\t\t\"Effect\": + \"Allow\",\n\t\t\t\"Resource\": \"arn:*:ec2:*:*:instance/*\",\n\t\t\t\"Action\": + \"ec2:CreateTags\",\n\t\t\t\"Condition\": {\n\t\t\t\t\"StringLike\": + {\n\t\t\t\t\t\"aws:ResourceTag/karpenter.sh/nodepool\": + \"*\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"Sid\": + \"AllowScopedDeletion\",\n\t\t\t\"Effect\": \"Allow\",\n\t\t\t\"Resource\": + [\n\t\t\t\t\"arn:*:ec2:*:*:instance/*\",\n\t\t\t\t\"arn:*:ec2:*:*:launch-template/*\"\n\t\t\t],\n\t\t\t\"Action\": + [\n\t\t\t\t\"ec2:TerminateInstances\",\n\t\t\t\t\"ec2:DeleteLaunchTemplate\"\n\t\t\t],\n\t\t\t\"Condition\": + {\n\t\t\t\t\"StringLike\": {\n\t\t\t\t\t\"aws:ResourceTag/karpenter.sh/nodepool\": + \"*\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"Sid\": + \"AllowRegionalReadActions\",\n\t\t\t\"Effect\": + \"Allow\",\n\t\t\t\"Resource\": \"*\",\n\t\t\t\"Action\": + [\n\t\t\t\t\"ec2:DescribeImages\",\n\t\t\t\t\"ec2:DescribeInstances\",\n\t\t\t\t\"ec2:DescribeInstanceTypeOfferings\",\n\t\t\t\t\"ec2:DescribeInstanceTypes\",\n\t\t\t\t\"ec2:DescribeLaunchTemplates\",\n\t\t\t\t\"ec2:DescribeSecurityGroups\",\n\t\t\t\t\"ec2:DescribeSpotPriceHistory\",\n\t\t\t\t\"ec2:DescribeSubnets\"\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"Sid\": + \"AllowSSMReadActions\",\n\t\t\t\"Effect\": \"Allow\",\n\t\t\t\"Resource\": + \"arn:*:ssm:*::parameter/aws/service/*\",\n\t\t\t\"Action\": + \"ssm:GetParameter\"\n\t\t},\n\t\t{\n\t\t\t\"Sid\": + \"AllowPricingReadActions\",\n\t\t\t\"Effect\": + \"Allow\",\n\t\t\t\"Resource\": \"*\",\n\t\t\t\"Action\": + \"pricing:GetProducts\"\n\t\t},\n\t\t{\n\t\t\t\"Sid\": + \"AllowInterruptionQueueActions\",\n\t\t\t\"Effect\": + \"Allow\",\n\t\t\t\"Resource\": \"*\",\n\t\t\t\"Action\": + [\n\t\t\t\t\"sqs:DeleteMessage\",\n\t\t\t\t\"sqs:GetQueueUrl\",\n\t\t\t\t\"sqs:ReceiveMessage\"\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"Sid\": + \"AllowPassingInstanceRole\",\n\t\t\t\"Effect\": + \"Allow\",\n\t\t\t\"Resource\": \"arn:*:iam::*:role/*\",\n\t\t\t\"Action\": + \"iam:PassRole\",\n\t\t\t\"Condition\": {\n\t\t\t\t\"StringEquals\": + {\n\t\t\t\t\t\"iam:PassedToService\": [\n\t\t\t\t\t\t\"ec2.amazonaws.com\",\n\t\t\t\t\t\t\"ec2.amazonaws.com.cn\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"Sid\": + \"AllowScopedInstanceProfileCreationActions\",\n\t\t\t\"Effect\": + \"Allow\",\n\t\t\t\"Resource\": \"arn:*:iam::*:instance-profile/*\",\n\t\t\t\"Action\": + [\n\t\t\t\t\"iam:CreateInstanceProfile\"\n\t\t\t],\n\t\t\t\"Condition\": + {\n\t\t\t\t\"StringLike\": {\n\t\t\t\t\t\"aws:RequestTag/karpenter.k8s.aws/ec2nodeclass\": + \"*\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"Sid\": + \"AllowScopedInstanceProfileTagActions\",\n\t\t\t\"Effect\": + \"Allow\",\n\t\t\t\"Resource\": \"arn:*:iam::*:instance-profile/*\",\n\t\t\t\"Action\": + [\n\t\t\t\t\"iam:TagInstanceProfile\"\n\t\t\t],\n\t\t\t\"Condition\": + {\n\t\t\t\t\"StringLike\": {\n\t\t\t\t\t\"aws:ResourceTag/karpenter.k8s.aws/ec2nodeclass\": + \"*\",\n\t\t\t\t\t\"aws:RequestTag/karpenter.k8s.aws/ec2nodeclass\": + \"*\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"Sid\": + \"AllowScopedInstanceProfileActions\",\n\t\t\t\"Effect\": + \"Allow\",\n\t\t\t\"Resource\": \"arn:*:iam::*:instance-profile/*\",\n\t\t\t\"Action\": + [\n\t\t\t\t\"iam:AddRoleToInstanceProfile\",\n\t\t\t\t\"iam:RemoveRoleFromInstanceProfile\",\n\t\t\t\t\"iam:DeleteInstanceProfile\"\n\t\t\t],\n\t\t\t\"Condition\": + {\n\t\t\t\t\"StringLike\": {\n\t\t\t\t\t\"aws:ResourceTag/karpenter.k8s.aws/ec2nodeclass\": + \"*\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"Sid\": + \"AllowInstanceProfileReadActions\",\n\t\t\t\"Effect\": + \"Allow\",\n\t\t\t\"Resource\": \"arn:*:iam::*:instance-profile/*\",\n\t\t\t\"Action\": + \"iam:GetInstanceProfile\"\n\t\t},\n\t\t{\n\t\t\t\"Sid\": + \"AllowUnscopedInstanceProfileListAction\",\n\t\t\t\"Effect\": + \"Allow\",\n\t\t\t\"Resource\": \"*\",\n\t\t\t\"Action\": + \"iam:ListInstanceProfiles\"\n\t\t}\n\t]\n}" + maxLength: 2048 + type: string + x-kubernetes-validations: + - message: roleARN must be a valid AWS IAM role ARN + (e.g. arn:aws:iam::123456789012:role/MyRole) + rule: self.matches('^arn:(aws|aws-cn|aws-us-gov):iam::[0-9]{12}:role/.+$') + required: + - roleARN + type: object + platform: + description: platform specifies the infrastructure platform + that Karpenter should provision nodes on. + enum: + - AWS + maxLength: 100 + type: string + required: + - platform + type: object + x-kubernetes-validations: + - message: aws is required when platform is AWS, and forbidden + otherwise + rule: 'self.platform == ''AWS'' ? has(self.aws) : !has(self.aws)' + name: + description: name specifies the name of the provisioner to + use for automatic node management. + enum: + - Karpenter + type: string + required: + - name + type: object + x-kubernetes-validations: + - message: karpenter is required when name is Karpenter, and forbidden + otherwise + rule: 'self.name == ''Karpenter'' ? has(self.karpenter) : !has(self.karpenter)' + required: + - provisionerConfig + type: object autoscaling: description: |- autoscaling specifies auto-scaling behavior that applies to all NodePools @@ -6368,6 +6504,26 @@ spec: status: description: status is the latest observed status of the HostedCluster. properties: + autoNode: + description: autoNode contains the observed state of the autoNode + (Karpenter) provisioner. + minProperties: 1 + properties: + nodeClaimCount: + description: |- + nodeClaimCount is the total number of NodeClaims managed by Karpenter. + This represents what Karpenter intends to provision, whether or not the node object exists yet. + format: int32 + minimum: 0 + type: integer + nodeCount: + description: |- + nodeCount is the number of nodes fully provisioned by Karpenter. + These are node objects that exist in the cluster and carry the karpenter.sh/nodepool label. + format: int32 + minimum: 0 + type: integer + type: object conditions: description: |- conditions represents the latest available observations of a control diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AutoNodeKarpenter.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AutoNodeKarpenter.yaml deleted file mode 100644 index 8cc9488a00ab..000000000000 --- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AutoNodeKarpenter.yaml +++ /dev/null @@ -1,7207 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - feature-gate.release.openshift.io/AutoNodeKarpenter: "true" - name: hostedclusters.hypershift.openshift.io -spec: - group: hypershift.openshift.io - names: - kind: HostedCluster - listKind: HostedClusterList - plural: hostedclusters - shortNames: - - hc - - hcs - singular: hostedcluster - scope: Namespaced - versions: - - additionalPrinterColumns: - - description: Version - jsonPath: .status.version.history[?(@.state=="Completed")].version - name: Version - type: string - - description: Control Plane Version - jsonPath: .status.controlPlaneVersion.history[?(@.state=="Completed")].version - name: CP Version - type: string - - description: KubeConfig Secret - jsonPath: .status.kubeconfig.name - name: KubeConfig - type: string - - description: Progress - jsonPath: .status.version.history[?(@.state!="")].state - name: Progress - type: string - - description: Available - jsonPath: .status.conditions[?(@.type=="Available")].status - name: Available - type: string - - description: Progressing - jsonPath: .status.conditions[?(@.type=="Progressing")].status - name: Progressing - type: string - - description: Message - jsonPath: .status.conditions[?(@.type=="Available")].message - name: Message - type: string - - description: Control Plane Progress - jsonPath: .status.controlPlaneVersion.history[0].state - name: CP Progress - priority: 1 - type: string - - description: Data Plane Progress - jsonPath: .status.version.history[0].state - name: DP Progress - priority: 1 - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: |- - HostedCluster is the primary representation of a HyperShift cluster and encapsulates - the control plane and common data plane configuration. Creating a HostedCluster - results in a fully functional OpenShift control plane with no attached nodes. - To support workloads (e.g. pods), a HostedCluster may have one or more associated - NodePool resources. - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: spec is the desired behavior of the HostedCluster. - properties: - additionalTrustBundle: - description: |- - additionalTrustBundle is a local reference to a ConfigMap that must have a "ca-bundle.crt" key - whose content must be a PEM-encoded X.509 certificate bundle that will be added to the hosted controlplane and nodes - If the reference is set but none of the above requirements are met, the HostedCluster will enter a degraded state. - This will be part of every payload generated by the controllers for any NodePool of the HostedCluster. - Changing this value will trigger a rollout for all existing NodePools in the cluster. - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - type: object - x-kubernetes-map-type: atomic - auditWebhook: - description: |- - auditWebhook contains metadata for configuring an audit webhook endpoint - for a cluster to process cluster audit events. It references a secret that - contains the webhook information for the audit webhook endpoint. It is a - secret because if the endpoint has mTLS the kubeconfig will contain client - keys. The kubeconfig needs to be stored in the secret with a secret key - name that corresponds to the constant AuditWebhookKubeconfigKey. - properties: - name: - default: "" - description: |- - Name of the referent. - This field is effectively required, but due to backwards compatibility is - allowed to be empty. Instances of this type with an empty value here are - almost certainly wrong. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - type: object - x-kubernetes-map-type: atomic - autoNode: - description: |- - autoNode specifies the configuration for automatic node provisioning and lifecycle management. - When set, the provisioner(e.g. Karpenter) will be used to provision nodes for targeted workloads. - properties: - provisionerConfig: - description: provisionerConfig specifies the provisioner used - for automatic node management. - properties: - karpenter: - description: karpenter specifies the configuration for the - Karpenter provisioner. - properties: - aws: - description: aws specifies the AWS-specific configuration - for Karpenter. - properties: - roleARN: - description: "roleARN specifies the ARN of the IAM - role that Karpenter assumes to provision\nand manage - EC2 instances in the hosted cluster's AWS account.\n\nThe - referenced role must have a trust relationship that - allows it to be assumed\nby the karpenter service - account in the hosted cluster via OIDC.\nExample:\n{\n\t\"Version\": - \"2012-10-17\",\n\t\"Statement\": [\n\t\t{\n\t\t\t\"Effect\": - \"Allow\",\n\t\t\t\"Principal\": {\n\t\t\t\t\"Federated\": - \"\"\n\t\t\t},\n\t\t\t\"Action\": - \"sts:AssumeRoleWithWebIdentity\",\n\t\t\t\"Condition\": - {\n\t\t\t\t\"StringEquals\": {\n\t\t\t\t\t\":sub\": - \"system:serviceaccount:kube-system:karpenter\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t]\n}\n\nThe - following is an example of the policy document for - this role.\n\n{\n\t\"Version\": \"2012-10-17\",\n\t\"Statement\": - [\n\t\t{\n\t\t\t\"Sid\": \"AllowScopedEC2InstanceAccessActions\",\n\t\t\t\"Effect\": - \"Allow\",\n\t\t\t\"Resource\": [\n\t\t\t\t\"arn:*:ec2:*::image/*\",\n\t\t\t\t\"arn:*:ec2:*::snapshot/*\",\n\t\t\t\t\"arn:*:ec2:*:*:security-group/*\",\n\t\t\t\t\"arn:*:ec2:*:*:subnet/*\"\n\t\t\t],\n\t\t\t\"Action\": - [\n\t\t\t\t\"ec2:RunInstances\",\n\t\t\t\t\"ec2:CreateFleet\"\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"Sid\": - \"AllowScopedEC2LaunchTemplateAccessActions\",\n\t\t\t\"Effect\": - \"Allow\",\n\t\t\t\"Resource\": \"arn:*:ec2:*:*:launch-template/*\",\n\t\t\t\"Action\": - [\n\t\t\t\t\"ec2:RunInstances\",\n\t\t\t\t\"ec2:CreateFleet\"\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"Sid\": - \"AllowScopedEC2InstanceActionsWithTags\",\n\t\t\t\"Effect\": - \"Allow\",\n\t\t\t\"Resource\": [\n\t\t\t\t\"arn:*:ec2:*:*:fleet/*\",\n\t\t\t\t\"arn:*:ec2:*:*:instance/*\",\n\t\t\t\t\"arn:*:ec2:*:*:volume/*\",\n\t\t\t\t\"arn:*:ec2:*:*:network-interface/*\",\n\t\t\t\t\"arn:*:ec2:*:*:launch-template/*\",\n\t\t\t\t\"arn:*:ec2:*:*:spot-instances-request/*\"\n\t\t\t],\n\t\t\t\"Action\": - [\n\t\t\t\t\"ec2:RunInstances\",\n\t\t\t\t\"ec2:CreateFleet\",\n\t\t\t\t\"ec2:CreateLaunchTemplate\"\n\t\t\t],\n\t\t\t\"Condition\": - {\n\t\t\t\t\"StringLike\": {\n\t\t\t\t\t\"aws:RequestTag/karpenter.sh/nodepool\": - \"*\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"Sid\": - \"AllowScopedResourceCreationTagging\",\n\t\t\t\"Effect\": - \"Allow\",\n\t\t\t\"Resource\": [\n\t\t\t\t\"arn:*:ec2:*:*:fleet/*\",\n\t\t\t\t\"arn:*:ec2:*:*:instance/*\",\n\t\t\t\t\"arn:*:ec2:*:*:volume/*\",\n\t\t\t\t\"arn:*:ec2:*:*:network-interface/*\",\n\t\t\t\t\"arn:*:ec2:*:*:launch-template/*\",\n\t\t\t\t\"arn:*:ec2:*:*:spot-instances-request/*\"\n\t\t\t],\n\t\t\t\"Action\": - \"ec2:CreateTags\",\n\t\t\t\"Condition\": {\n\t\t\t\t\"StringEquals\": - {\n\t\t\t\t\t\"ec2:CreateAction\": [\n\t\t\t\t\t\t\"RunInstances\",\n\t\t\t\t\t\t\"CreateFleet\",\n\t\t\t\t\t\t\"CreateLaunchTemplate\"\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t\"StringLike\": - {\n\t\t\t\t\t\"aws:RequestTag/karpenter.sh/nodepool\": - \"*\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"Sid\": - \"AllowScopedResourceTagging\",\n\t\t\t\"Effect\": - \"Allow\",\n\t\t\t\"Resource\": \"arn:*:ec2:*:*:instance/*\",\n\t\t\t\"Action\": - \"ec2:CreateTags\",\n\t\t\t\"Condition\": {\n\t\t\t\t\"StringLike\": - {\n\t\t\t\t\t\"aws:ResourceTag/karpenter.sh/nodepool\": - \"*\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"Sid\": - \"AllowScopedDeletion\",\n\t\t\t\"Effect\": \"Allow\",\n\t\t\t\"Resource\": - [\n\t\t\t\t\"arn:*:ec2:*:*:instance/*\",\n\t\t\t\t\"arn:*:ec2:*:*:launch-template/*\"\n\t\t\t],\n\t\t\t\"Action\": - [\n\t\t\t\t\"ec2:TerminateInstances\",\n\t\t\t\t\"ec2:DeleteLaunchTemplate\"\n\t\t\t],\n\t\t\t\"Condition\": - {\n\t\t\t\t\"StringLike\": {\n\t\t\t\t\t\"aws:ResourceTag/karpenter.sh/nodepool\": - \"*\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"Sid\": - \"AllowRegionalReadActions\",\n\t\t\t\"Effect\": - \"Allow\",\n\t\t\t\"Resource\": \"*\",\n\t\t\t\"Action\": - [\n\t\t\t\t\"ec2:DescribeImages\",\n\t\t\t\t\"ec2:DescribeInstances\",\n\t\t\t\t\"ec2:DescribeInstanceTypeOfferings\",\n\t\t\t\t\"ec2:DescribeInstanceTypes\",\n\t\t\t\t\"ec2:DescribeLaunchTemplates\",\n\t\t\t\t\"ec2:DescribeSecurityGroups\",\n\t\t\t\t\"ec2:DescribeSpotPriceHistory\",\n\t\t\t\t\"ec2:DescribeSubnets\"\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"Sid\": - \"AllowSSMReadActions\",\n\t\t\t\"Effect\": \"Allow\",\n\t\t\t\"Resource\": - \"arn:*:ssm:*::parameter/aws/service/*\",\n\t\t\t\"Action\": - \"ssm:GetParameter\"\n\t\t},\n\t\t{\n\t\t\t\"Sid\": - \"AllowPricingReadActions\",\n\t\t\t\"Effect\": - \"Allow\",\n\t\t\t\"Resource\": \"*\",\n\t\t\t\"Action\": - \"pricing:GetProducts\"\n\t\t},\n\t\t{\n\t\t\t\"Sid\": - \"AllowInterruptionQueueActions\",\n\t\t\t\"Effect\": - \"Allow\",\n\t\t\t\"Resource\": \"*\",\n\t\t\t\"Action\": - [\n\t\t\t\t\"sqs:DeleteMessage\",\n\t\t\t\t\"sqs:GetQueueUrl\",\n\t\t\t\t\"sqs:ReceiveMessage\"\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"Sid\": - \"AllowPassingInstanceRole\",\n\t\t\t\"Effect\": - \"Allow\",\n\t\t\t\"Resource\": \"arn:*:iam::*:role/*\",\n\t\t\t\"Action\": - \"iam:PassRole\",\n\t\t\t\"Condition\": {\n\t\t\t\t\"StringEquals\": - {\n\t\t\t\t\t\"iam:PassedToService\": [\n\t\t\t\t\t\t\"ec2.amazonaws.com\",\n\t\t\t\t\t\t\"ec2.amazonaws.com.cn\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"Sid\": - \"AllowScopedInstanceProfileCreationActions\",\n\t\t\t\"Effect\": - \"Allow\",\n\t\t\t\"Resource\": \"arn:*:iam::*:instance-profile/*\",\n\t\t\t\"Action\": - [\n\t\t\t\t\"iam:CreateInstanceProfile\"\n\t\t\t],\n\t\t\t\"Condition\": - {\n\t\t\t\t\"StringLike\": {\n\t\t\t\t\t\"aws:RequestTag/karpenter.k8s.aws/ec2nodeclass\": - \"*\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"Sid\": - \"AllowScopedInstanceProfileTagActions\",\n\t\t\t\"Effect\": - \"Allow\",\n\t\t\t\"Resource\": \"arn:*:iam::*:instance-profile/*\",\n\t\t\t\"Action\": - [\n\t\t\t\t\"iam:TagInstanceProfile\"\n\t\t\t],\n\t\t\t\"Condition\": - {\n\t\t\t\t\"StringLike\": {\n\t\t\t\t\t\"aws:ResourceTag/karpenter.k8s.aws/ec2nodeclass\": - \"*\",\n\t\t\t\t\t\"aws:RequestTag/karpenter.k8s.aws/ec2nodeclass\": - \"*\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"Sid\": - \"AllowScopedInstanceProfileActions\",\n\t\t\t\"Effect\": - \"Allow\",\n\t\t\t\"Resource\": \"arn:*:iam::*:instance-profile/*\",\n\t\t\t\"Action\": - [\n\t\t\t\t\"iam:AddRoleToInstanceProfile\",\n\t\t\t\t\"iam:RemoveRoleFromInstanceProfile\",\n\t\t\t\t\"iam:DeleteInstanceProfile\"\n\t\t\t],\n\t\t\t\"Condition\": - {\n\t\t\t\t\"StringLike\": {\n\t\t\t\t\t\"aws:ResourceTag/karpenter.k8s.aws/ec2nodeclass\": - \"*\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"Sid\": - \"AllowInstanceProfileReadActions\",\n\t\t\t\"Effect\": - \"Allow\",\n\t\t\t\"Resource\": \"arn:*:iam::*:instance-profile/*\",\n\t\t\t\"Action\": - \"iam:GetInstanceProfile\"\n\t\t},\n\t\t{\n\t\t\t\"Sid\": - \"AllowUnscopedInstanceProfileListAction\",\n\t\t\t\"Effect\": - \"Allow\",\n\t\t\t\"Resource\": \"*\",\n\t\t\t\"Action\": - \"iam:ListInstanceProfiles\"\n\t\t}\n\t]\n}" - maxLength: 2048 - type: string - x-kubernetes-validations: - - message: roleARN must be a valid AWS IAM role ARN - (e.g. arn:aws:iam::123456789012:role/MyRole) - rule: self.matches('^arn:(aws|aws-cn|aws-us-gov):iam::[0-9]{12}:role/.+$') - required: - - roleARN - type: object - platform: - description: platform specifies the infrastructure platform - that Karpenter should provision nodes on. - enum: - - AWS - maxLength: 100 - type: string - required: - - platform - type: object - x-kubernetes-validations: - - message: aws is required when platform is AWS, and forbidden - otherwise - rule: 'self.platform == ''AWS'' ? has(self.aws) : !has(self.aws)' - name: - description: name specifies the name of the provisioner to - use for automatic node management. - enum: - - Karpenter - type: string - required: - - name - type: object - x-kubernetes-validations: - - message: karpenter is required when name is Karpenter, and forbidden - otherwise - rule: 'self.name == ''Karpenter'' ? has(self.karpenter) : !has(self.karpenter)' - required: - - provisionerConfig - type: object - autoscaling: - description: |- - autoscaling specifies auto-scaling behavior that applies to all NodePools - associated with this HostedCluster. - properties: - balancingIgnoredLabels: - description: |- - balancingIgnoredLabels sets "--balancing-ignore-label