Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨Add new fields to ROSAControlPlane - additionalTags, etcdEncryption, endpointAccess #4844

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ spec:
spec:
description: RosaControlPlaneSpec defines the desired state of ROSAControlPlane.
properties:
additionalTags:
additionalProperties:
type: string
description: AdditionalTags are user-defined tags to be added on the
AWS resources associated with the control plane.
type: object
autoscaling:
description: Autoscaling specifies auto scaling behaviour for the
MachinePools.
Expand Down Expand Up @@ -102,6 +108,19 @@ spec:
type: string
type: object
x-kubernetes-map-type: atomic
endpointAccess:
default: Public
description: EndpointAccess specifies the publishing scope of cluster
endpoints. The default is Public.
enum:
- Public
- Private
type: string
etcdEncryptionKMSArn:
description: EtcdEncryptionKMSArn is the ARN of the KMS key used to
encrypt etcd. The key itself needs to be created out-of-band by
the user and tagged with `red-hat:true`.
type: string
identityRef:
description: IdentityRef is a reference to an identity to be used
when reconciling the managed control plane. If no identity is specified,
Expand Down Expand Up @@ -361,7 +380,7 @@ spec:
description: RosaControlPlaneStatus defines the observed state of ROSAControlPlane.
properties:
conditions:
description: Conditions specifies the cpnditions for the managed control
description: Conditions specifies the conditions for the managed control
plane
items:
description: Condition defines an observation of a Cluster API resource
Expand Down Expand Up @@ -433,7 +452,7 @@ spec:
type: boolean
oidcEndpointURL:
description: OIDCEndpointURL is the endpoint url for the managed OIDC
porvider.
provider.
type: string
ready:
default: false
Expand Down
21 changes: 21 additions & 0 deletions controlplane/rosa/api/v1beta2/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
Copyright 2024 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Package v1beta2 contains API Schema definitions for the controlplane v1beta2 API group
// +gencrdrefdocs:force
// +groupName=controlplane.cluster.x-k8s.io
// +k8s:defaulter-gen=TypeMeta
package v1beta2
34 changes: 32 additions & 2 deletions controlplane/rosa/api/v1beta2/rosacontrolplane_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,19 @@ import (
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
)

// RosaEndpointAccessType specifies the publishing scope of cluster endpoints.
type RosaEndpointAccessType string

const (
// Public endpoint access allows public API server access and
// private node communication with the control plane.
Public RosaEndpointAccessType = "Public"

// Private endpoint access allows only private API server access and private
// node communication with the control plane.
Private RosaEndpointAccessType = "Private"
)

// RosaControlPlaneSpec defines the desired state of ROSAControlPlane.
type RosaControlPlaneSpec struct { //nolint: maligned
// Cluster name must be valid DNS-1035 label, so it must consist of lower case alphanumeric
Expand Down Expand Up @@ -90,6 +103,14 @@ type RosaControlPlaneSpec struct { //nolint: maligned
// +optional
Network *NetworkSpec `json:"network,omitempty"`

// EndpointAccess specifies the publishing scope of cluster endpoints. The
// default is Public.
//
// +kubebuilder:validation:Enum=Public;Private
// +kubebuilder:default=Public
// +optional
EndpointAccess RosaEndpointAccessType `json:"endpointAccess,omitempty"`

// The instance type to use, for example `r5.xlarge`. Instance type ref; https://aws.amazon.com/ec2/instance-types/
// +optional
InstanceType string `json:"instanceType,omitempty"`
Expand All @@ -98,6 +119,15 @@ type RosaControlPlaneSpec struct { //nolint: maligned
// +optional
Autoscaling *expinfrav1.RosaMachinePoolAutoScaling `json:"autoscaling,omitempty"`

// AdditionalTags are user-defined tags to be added on the AWS resources associated with the control plane.
// +optional
AdditionalTags infrav1.Tags `json:"additionalTags,omitempty"`

// EtcdEncryptionKMSArn is the ARN of the KMS key used to encrypt etcd. The key itself needs to be
// created out-of-band by the user and tagged with `red-hat:true`.
// +optional
EtcdEncryptionKMSArn string `json:"etcdEncryptionKMSArn,omitempty"`

// ControlPlaneEndpoint represents the endpoint used to communicate with the control plane.
// +optional
ControlPlaneEndpoint clusterv1.APIEndpoint `json:"controlPlaneEndpoint"`
Expand Down Expand Up @@ -534,14 +564,14 @@ type RosaControlPlaneStatus struct {
//
// +optional
FailureMessage *string `json:"failureMessage,omitempty"`
// Conditions specifies the cpnditions for the managed control plane
// Conditions specifies the conditions for the managed control plane
Conditions clusterv1.Conditions `json:"conditions,omitempty"`

// ID is the cluster ID given by ROSA.
ID string `json:"id,omitempty"`
// ConsoleURL is the url for the openshift console.
ConsoleURL string `json:"consoleURL,omitempty"`
// OIDCEndpointURL is the endpoint url for the managed OIDC porvider.
// OIDCEndpointURL is the endpoint url for the managed OIDC provider.
OIDCEndpointURL string `json:"oidcEndpointURL,omitempty"`
}

Expand Down
20 changes: 20 additions & 0 deletions controlplane/rosa/api/v1beta2/rosacontrolplane_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"net"

"github.com/blang/semver"
kmsArnRegexpValidator "github.com/openshift-online/ocm-common/pkg/resource/validations"
apierrors "k8s.io/apimachinery/pkg/api/errors"
runtime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/validation/field"
Expand Down Expand Up @@ -33,7 +34,12 @@ func (r *ROSAControlPlane) ValidateCreate() (warnings admission.Warnings, err er
allErrs = append(allErrs, err)
}

if err := r.validateEtcdEncryptionKMSArn(); err != nil {
allErrs = append(allErrs, err)
}

allErrs = append(allErrs, r.validateNetwork()...)
allErrs = append(allErrs, r.Spec.AdditionalTags.Validate()...)

if len(allErrs) == 0 {
return nil, nil
Expand All @@ -54,7 +60,12 @@ func (r *ROSAControlPlane) ValidateUpdate(old runtime.Object) (warnings admissio
allErrs = append(allErrs, err)
}

if err := r.validateEtcdEncryptionKMSArn(); err != nil {
allErrs = append(allErrs, err)
}

allErrs = append(allErrs, r.validateNetwork()...)
allErrs = append(allErrs, r.Spec.AdditionalTags.Validate()...)

if len(allErrs) == 0 {
return nil, nil
Expand Down Expand Up @@ -113,6 +124,15 @@ func (r *ROSAControlPlane) validateNetwork() field.ErrorList {
return allErrs
}

func (r *ROSAControlPlane) validateEtcdEncryptionKMSArn() *field.Error {
err := kmsArnRegexpValidator.ValidateKMSKeyARN(&r.Spec.EtcdEncryptionKMSArn)
if err != nil {
return field.Invalid(field.NewPath("spec.EtcdEncryptionKMSArn"), r.Spec.EtcdEncryptionKMSArn, err.Error())
}

return nil
}

// Default implements admission.Defaulter.
func (r *ROSAControlPlane) Default() {
SetObjectDefaults_ROSAControlPlane(r)
Expand Down
7 changes: 7 additions & 0 deletions controlplane/rosa/api/v1beta2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions controlplane/rosa/api/v1beta2/zz_generated.defaults.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion controlplane/rosa/controllers/rosacontrolplane_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,10 +280,12 @@ func (r *ROSAControlPlaneReconciler) reconcileNormal(ctx context.Context, rosaSc
MultiAZ: true,
Version: ocm.CreateVersionID(rosaScope.ControlPlane.Spec.Version, ocm.DefaultChannelGroup),
ChannelGroup: ocm.DefaultChannelGroup,
Expiration: time.Now().Add(1 * time.Hour),
DisableWorkloadMonitoring: ptr.To(true),
DefaultIngress: ocm.NewDefaultIngressSpec(), // n.b. this is a no-op when it's set to the default value
ComputeMachineType: rosaScope.ControlPlane.Spec.InstanceType,
Tags: rosaScope.ControlPlane.Spec.AdditionalTags,
EtcdEncryption: rosaScope.ControlPlane.Spec.EtcdEncryptionKMSArn != "",
EtcdEncryptionKMSArn: rosaScope.ControlPlane.Spec.EtcdEncryptionKMSArn,

SubnetIds: rosaScope.ControlPlane.Spec.Subnets,
AvailabilityZones: rosaScope.ControlPlane.Spec.AvailabilityZones,
Expand All @@ -301,6 +303,11 @@ func (r *ROSAControlPlaneReconciler) reconcileNormal(ctx context.Context, rosaSc
AWSCreator: creator,
}

if rosaScope.ControlPlane.Spec.EndpointAccess == rosacontrolplanev1.Private {
ocmClusterSpec.Private = ptr.To(true)
ocmClusterSpec.PrivateLink = ptr.To(true)
}

if networkSpec := rosaScope.ControlPlane.Spec.Network; networkSpec != nil {
if networkSpec.MachineCIDR != "" {
_, machineCIDR, err := net.ParseCIDR(networkSpec.MachineCIDR)
Expand Down
Loading