From 615aa6942fd434236c7570ce5ab00ed72a3ac7e8 Mon Sep 17 00:00:00 2001 From: Sandhya Dasu Date: Thu, 20 Jul 2023 17:16:18 -0400 Subject: [PATCH 1/3] Add custom DNS configuration to AWSPlatformStatus When a customer configures their own DNS solution for API and API-Int in place of the default cloud provided DNS, the state of the DNS provider is added to the Infrastructure CR's AWSPlatformStatus. This feature is in TechPreview. --- ...frastructure-TechPreviewNoUpgrade.crd.yaml | 18 ++++++++ config/v1/feature_gates.go | 10 +++++ config/v1/types_feature.go | 1 + config/v1/types_infrastructure.go | 40 ++++++++++++++++++ config/v1/zz_generated.deepcopy.go | 21 ++++++++++ .../v1/zz_generated.swagger_doc_generated.go | 10 +++++ .../generated_openapi/zz_generated.openapi.go | 41 ++++++++++++++++++- openapi/openapi.json | 24 +++++++++++ 8 files changed, 164 insertions(+), 1 deletion(-) diff --git a/config/v1/0000_10_config-operator_01_infrastructure-TechPreviewNoUpgrade.crd.yaml b/config/v1/0000_10_config-operator_01_infrastructure-TechPreviewNoUpgrade.crd.yaml index 13d0d1f4658..7ac73c5552b 100644 --- a/config/v1/0000_10_config-operator_01_infrastructure-TechPreviewNoUpgrade.crd.yaml +++ b/config/v1/0000_10_config-operator_01_infrastructure-TechPreviewNoUpgrade.crd.yaml @@ -466,6 +466,24 @@ spec: aws: description: AWS contains settings specific to the Amazon Web Services infrastructure provider. properties: + dnsConfig: + default: + provider: "" + description: dnsConfig contains information about the type of DNS solution in use for the cluster. + properties: + provider: + default: "" + description: provider determines which DNS solution is in use for this cluster. When the user wants to use their own DNS solution, the `provider` is set to "UserAndClusterProvided". When the cluster's DNS solution is the default for IPI or UPI, then `provider` is set to "" which is also its default value. + enum: + - UserAndClusterProvided + - "" + type: string + x-kubernetes-validations: + - message: provider is immutable once set + rule: oldSelf == '' || self == oldSelf + required: + - provider + type: object region: description: region holds the default AWS region for new AWS resources created by the cluster. type: string diff --git a/config/v1/feature_gates.go b/config/v1/feature_gates.go index 07f03f61841..017e1ee2b3f 100644 --- a/config/v1/feature_gates.go +++ b/config/v1/feature_gates.go @@ -311,4 +311,14 @@ var ( ResponsiblePerson: "msluiter", OwningProduct: ocpSpecific, } + + FeatureGateCustomDNSAWS = FeatureGateName("CustomDNSAWS") + customDNSAWS = FeatureGateDescription{ + FeatureGateAttributes: FeatureGateAttributes{ + Name: FeatureGateCustomDNSAWS, + }, + OwningJiraComponent: "installer", + ResponsiblePerson: "sadasu", + OwningProduct: ocpSpecific, + } ) diff --git a/config/v1/types_feature.go b/config/v1/types_feature.go index d2dbc11884a..e056699c373 100644 --- a/config/v1/types_feature.go +++ b/config/v1/types_feature.go @@ -186,6 +186,7 @@ var FeatureSets = map[FeatureSet]*FeatureGateEnabledDisabled{ with(automatedEtcdBackup). without(machineAPIOperatorDisableMachineHealthCheckController). with(adminNetworkPolicy). + with(customDNSAWS). toFeatures(defaultFeatures), LatencySensitive: newDefaultFeatures(). toFeatures(defaultFeatures), diff --git a/config/v1/types_infrastructure.go b/config/v1/types_infrastructure.go index 2c1423dedaf..e59aeba1237 100644 --- a/config/v1/types_infrastructure.go +++ b/config/v1/types_infrastructure.go @@ -478,6 +478,14 @@ type AWSPlatformStatus struct { // +kubebuilder:validation:MaxItems=25 // +optional ResourceTags []AWSResourceTag `json:"resourceTags,omitempty"` + + // dnsConfig contains information about the type of DNS solution in use + // for the cluster. + // +default={"provider": ""} + // +kubebuilder:default={"provider": ""} + // +openshift:enable:FeatureSets=TechPreviewNoUpgrade + // +optional + DNSConfig *DNSConfigurationType `json:"dnsConfig,omitempty"` } // AWSResourceTag is a tag to apply to AWS resources created for the cluster. @@ -500,6 +508,38 @@ type AWSResourceTag struct { Value string `json:"value"` } +// DNSConfigurationType contains information about who configures DNS for the +// cluster. +// +union +type DNSConfigurationType struct { + // provider determines which DNS solution is in use for this cluster. + // When the user wants to use their own DNS solution, the `provider` + // is set to "UserAndClusterProvided". + // When the cluster's DNS solution is the default for IPI or UPI, then + // `provider` is set to "" which is also its default value. + // +default="" + // +kubebuilder:default:="" + // +kubebuilder:validation:Enum="UserAndClusterProvided";"" + // +kubebuilder:validation:Required + // +kubebuilder:validation:XValidation:rule="oldSelf == '' || self == oldSelf",message="provider is immutable once set" + // +unionDiscriminator + // +optional + Provider DNSProviderType `json:"provider,omitempty"` +} + +// DNSProviderType defines the source of the DNS and LB configuration. +type DNSProviderType string + +const ( + // DNSUserAndClusterProvided indicates that the user configures DNS for API and API-Int. + // The cluster handles some of its in-cluster DNS needs without user intervention. + DNSUserAndClusterProvided DNSProviderType = "UserAndClusterProvided" + + // DNSDefault indicates the cluster's default way of handling DNS configuration. + // This refers to the default DNS configuration expected for both IPI and UPI installs. + DNSDefault DNSProviderType = "" +) + // AzurePlatformSpec holds the desired state of the Azure infrastructure provider. // This only includes fields that can be modified in the cluster. type AzurePlatformSpec struct{} diff --git a/config/v1/zz_generated.deepcopy.go b/config/v1/zz_generated.deepcopy.go index 57383546056..7807d007e4c 100644 --- a/config/v1/zz_generated.deepcopy.go +++ b/config/v1/zz_generated.deepcopy.go @@ -245,6 +245,11 @@ func (in *AWSPlatformStatus) DeepCopyInto(out *AWSPlatformStatus) { *out = make([]AWSResourceTag, len(*in)) copy(*out, *in) } + if in.DNSConfig != nil { + in, out := &in.DNSConfig, &out.DNSConfig + *out = new(DNSConfigurationType) + **out = **in + } return } @@ -1579,6 +1584,22 @@ func (in *DNS) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DNSConfigurationType) DeepCopyInto(out *DNSConfigurationType) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSConfigurationType. +func (in *DNSConfigurationType) DeepCopy() *DNSConfigurationType { + if in == nil { + return nil + } + out := new(DNSConfigurationType) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DNSList) DeepCopyInto(out *DNSList) { *out = *in diff --git a/config/v1/zz_generated.swagger_doc_generated.go b/config/v1/zz_generated.swagger_doc_generated.go index f84e44573bb..f286f447493 100644 --- a/config/v1/zz_generated.swagger_doc_generated.go +++ b/config/v1/zz_generated.swagger_doc_generated.go @@ -1066,6 +1066,7 @@ var map_AWSPlatformStatus = map[string]string{ "region": "region holds the default AWS region for new AWS resources created by the cluster.", "serviceEndpoints": "ServiceEndpoints list contains custom endpoints which will override default service endpoint of AWS Services. There must be only one ServiceEndpoint for a service.", "resourceTags": "resourceTags is a list of additional tags to apply to AWS resources created for the cluster. See https://docs.aws.amazon.com/general/latest/gr/aws_tagging.html for information on tagging AWS resources. AWS supports a maximum of 50 tags per resource. OpenShift reserves 25 tags for its use, leaving 25 tags available for the user.", + "dnsConfig": "dnsConfig contains information about the type of DNS solution in use for the cluster.", } func (AWSPlatformStatus) SwaggerDoc() map[string]string { @@ -1192,6 +1193,15 @@ func (CloudControllerManagerStatus) SwaggerDoc() map[string]string { return map_CloudControllerManagerStatus } +var map_DNSConfigurationType = map[string]string{ + "": "DNSConfigurationType contains information about who configures DNS for the cluster.", + "provider": "provider determines which DNS solution is in use for this cluster. When the user wants to use their own DNS solution, the `provider` is set to \"UserAndClusterProvided\". When the cluster's DNS solution is the default for IPI or UPI, then `provider` is set to \"\" which is also its default value.", +} + +func (DNSConfigurationType) SwaggerDoc() map[string]string { + return map_DNSConfigurationType +} + var map_EquinixMetalPlatformSpec = map[string]string{ "": "EquinixMetalPlatformSpec holds the desired state of the Equinix Metal infrastructure provider. This only includes fields that can be modified in the cluster.", } diff --git a/openapi/generated_openapi/zz_generated.openapi.go b/openapi/generated_openapi/zz_generated.openapi.go index 238b8928cb9..fdcc89a754b 100644 --- a/openapi/generated_openapi/zz_generated.openapi.go +++ b/openapi/generated_openapi/zz_generated.openapi.go @@ -210,6 +210,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/openshift/api/config/v1.CustomFeatureGates": schema_openshift_api_config_v1_CustomFeatureGates(ref), "github.com/openshift/api/config/v1.CustomTLSProfile": schema_openshift_api_config_v1_CustomTLSProfile(ref), "github.com/openshift/api/config/v1.DNS": schema_openshift_api_config_v1_DNS(ref), + "github.com/openshift/api/config/v1.DNSConfigurationType": schema_openshift_api_config_v1_DNSConfigurationType(ref), "github.com/openshift/api/config/v1.DNSList": schema_openshift_api_config_v1_DNSList(ref), "github.com/openshift/api/config/v1.DNSPlatformSpec": schema_openshift_api_config_v1_DNSPlatformSpec(ref), "github.com/openshift/api/config/v1.DNSSpec": schema_openshift_api_config_v1_DNSSpec(ref), @@ -8427,12 +8428,19 @@ func schema_openshift_api_config_v1_AWSPlatformStatus(ref common.ReferenceCallba }, }, }, + "dnsConfig": { + SchemaProps: spec.SchemaProps{ + Description: "dnsConfig contains information about the type of DNS solution in use for the cluster.", + Default: map[string]interface{}{"provider": ""}, + Ref: ref("github.com/openshift/api/config/v1.DNSConfigurationType"), + }, + }, }, Required: []string{"region"}, }, }, Dependencies: []string{ - "github.com/openshift/api/config/v1.AWSResourceTag", "github.com/openshift/api/config/v1.AWSServiceEndpoint"}, + "github.com/openshift/api/config/v1.AWSResourceTag", "github.com/openshift/api/config/v1.AWSServiceEndpoint", "github.com/openshift/api/config/v1.DNSConfigurationType"}, } } @@ -10978,6 +10986,37 @@ func schema_openshift_api_config_v1_DNS(ref common.ReferenceCallback) common.Ope } } +func schema_openshift_api_config_v1_DNSConfigurationType(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "DNSConfigurationType contains information about who configures DNS for the cluster.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "provider": { + SchemaProps: spec.SchemaProps{ + Description: "provider determines which DNS solution is in use for this cluster. When the user wants to use their own DNS solution, the `provider` is set to \"UserAndClusterProvided\". When the cluster's DNS solution is the default for IPI or UPI, then `provider` is set to \"\" which is also its default value.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-unions": []interface{}{ + map[string]interface{}{ + "discriminator": "provider", + "fields-to-discriminateBy": map[string]interface{}{}, + }, + }, + }, + }, + }, + } +} + func schema_openshift_api_config_v1_DNSList(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ diff --git a/openapi/openapi.json b/openapi/openapi.json index 6071095b1d6..e0474ebb605 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -4170,6 +4170,13 @@ "region" ], "properties": { + "dnsConfig": { + "description": "dnsConfig contains information about the type of DNS solution in use for the cluster.", + "default": { + "provider": "" + }, + "$ref": "#/definitions/com.github.openshift.api.config.v1.DNSConfigurationType" + }, "region": { "description": "region holds the default AWS region for new AWS resources created by the cluster.", "type": "string", @@ -5712,6 +5719,23 @@ } } }, + "com.github.openshift.api.config.v1.DNSConfigurationType": { + "description": "DNSConfigurationType contains information about who configures DNS for the cluster.", + "type": "object", + "properties": { + "provider": { + "description": "provider determines which DNS solution is in use for this cluster. When the user wants to use their own DNS solution, the `provider` is set to \"UserAndClusterProvided\". When the cluster's DNS solution is the default for IPI or UPI, then `provider` is set to \"\" which is also its default value.", + "type": "string", + "default": "" + } + }, + "x-kubernetes-unions": [ + { + "discriminator": "provider", + "fields-to-discriminateBy": {} + } + ] + }, "com.github.openshift.api.config.v1.DNSList": { "description": "Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).", "type": "object", From 4d307a775fef55d246f13caec295abacdf8db68f Mon Sep 17 00:00:00 2001 From: Sandhya Dasu Date: Thu, 20 Jul 2023 17:20:53 -0400 Subject: [PATCH 2/3] Allow testsuite to compare strings of length > 4000 Update the MaxLength within the format package of gomega. This allows for the test suite to compare strings of size greater than 4000 which for required for the new tests added for the custom DNS feature. --- tests/suite_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/suite_test.go b/tests/suite_test.go index 1419ee92bd9..663eb869045 100644 --- a/tests/suite_test.go +++ b/tests/suite_test.go @@ -9,6 +9,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + format "github.com/onsi/gomega/format" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/discovery" @@ -34,6 +35,8 @@ func TestAPIs(t *testing.T) { g := NewGomegaWithT(t) + format.MaxLength = 0 + var err error suites, err = LoadTestSuiteSpecs(filepath.Join("..")) g.Expect(err).ToNot(HaveOccurred()) From 30112267182a0e4d6407ad9ee140a993d439f6fd Mon Sep 17 00:00:00 2001 From: Sandhya Dasu Date: Thu, 20 Jul 2023 19:51:56 -0400 Subject: [PATCH 3/3] Add new tests to verify behavior of the new byo DNS feature Currently feature is in Tech preview --- .../techpreview.infrastructure.testsuite.yaml | 129 ++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/config/v1/techpreview.infrastructure.testsuite.yaml b/config/v1/techpreview.infrastructure.testsuite.yaml index f9829b9a396..19d503b66ba 100644 --- a/config/v1/techpreview.infrastructure.testsuite.yaml +++ b/config/v1/techpreview.infrastructure.testsuite.yaml @@ -211,3 +211,132 @@ tests: type: FooBar type: BareMetal expectedStatusError: "status.platformStatus.baremetal.loadBalancer.type: Unsupported value: \"FooBar\": supported values: \"OpenShiftManagedDefault\", \"UserManaged\"" + - name: Should set dnsConfig provider to "" if not specified + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: + platformSpec: + aws: {} + type: AWS + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: + platformSpec: + aws: {} + type: AWS + status: + platform: AWS + platformStatus: + aws: {} + type: AWS + expected: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: + platformSpec: + aws: {} + type: AWS + status: + controlPlaneTopology: HighlyAvailable + cpuPartitioning: None + infrastructureTopology: HighlyAvailable + platform: AWS + platformStatus: + aws: + dnsConfig: + provider: "" + type: AWS + - name: Should be able to override the default Provider with a valid value + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: + platformSpec: + aws: {} + type: AWS + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: + platformSpec: + aws: {} + type: AWS + status: + platform: AWS + platformStatus: + aws: + dnsConfig: + provider: UserAndClusterProvided + type: AWS + expected: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: + platformSpec: + aws: {} + type: AWS + status: + controlPlaneTopology: HighlyAvailable + cpuPartitioning: None + infrastructureTopology: HighlyAvailable + platform: AWS + platformStatus: + aws: + dnsConfig: + provider: UserAndClusterProvided + type: AWS + - name: Should be not be able to modify immutable 'provider' + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: + platformSpec: + aws: {} + type: AWS + status: + platform: AWS + platformStatus: + aws: + dnsConfig: + provider: UserAndClusterProvided + type: AWS + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: + platformSpec: + aws: {} + type: AWS + status: + platform: AWS + platformStatus: + aws: + dnsConfig: + provider: "" + type: AWS + expectedStatusError: "status.platformStatus.aws.dnsConfig.provider: Invalid value: \"string\": provider is immutable once set" + - name: Should be not be able to set Provider with an invalid value + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: + platformSpec: + aws: {} + type: AWS + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: + platformSpec: + aws: {} + type: AWS + status: + platform: AWS + platformStatus: + aws: + dnsConfig: + provider: CloudProvided + type: AWS + expectedStatusError: "status.platformStatus.aws.dnsConfig.provider: Unsupported value: \"CloudProvided\": supported values: \"UserAndClusterProvided\", \"\""