diff --git a/machine/v1beta1/tests/machines.machine.openshift.io/IPv6NetworkInterface.yaml b/machine/v1beta1/tests/machines.machine.openshift.io/IPv6NetworkInterface.yaml new file mode 100644 index 00000000000..6bfa0c9463d --- /dev/null +++ b/machine/v1beta1/tests/machines.machine.openshift.io/IPv6NetworkInterface.yaml @@ -0,0 +1,555 @@ +apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this +name: "Machine (GCP IPv6 Network Interface Support)" +crdName: machines.machine.openshift.io +tests: + onCreate: + - name: Should be able to create a GCP machine with IPv4Only stack type + initial: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: IPv4Only + expected: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + authoritativeAPI: MachineAPI + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: IPv4Only + - name: Should be able to create a GCP machine with DualStack stack type + initial: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: DualStack + expected: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + authoritativeAPI: MachineAPI + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: DualStack + - name: Should be able to create a GCP machine with DualStack and external IPv6 access + initial: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: DualStack + ipv6AccessType: External + expected: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + authoritativeAPI: MachineAPI + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: DualStack + ipv6AccessType: External + - name: Should be able to create a GCP machine with DualStack and internal IPv6 access + initial: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: DualStack + ipv6AccessType: Internal + expected: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + authoritativeAPI: MachineAPI + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: DualStack + ipv6AccessType: Internal + - name: Should be able to create a GCP machine with DualStack and static IPv6 address + initial: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: DualStack + ipv6Address: "2001:db8::1" + ipv6AccessType: External + expected: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + authoritativeAPI: MachineAPI + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: DualStack + ipv6Address: "2001:db8::1" + ipv6AccessType: External + - name: Should be able to create a GCP machine with multiple network interfaces with different stack types + initial: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network-1 + subnetwork: test-subnet-1 + stackType: IPv4Only + - network: test-network-2 + subnetwork: test-subnet-2 + stackType: DualStack + ipv6AccessType: External + expected: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + authoritativeAPI: MachineAPI + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network-1 + subnetwork: test-subnet-1 + stackType: IPv4Only + - network: test-network-2 + subnetwork: test-subnet-2 + stackType: DualStack + ipv6AccessType: External + - name: Should reject invalid stackType value + initial: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: InvalidStackType + expectedError: "spec.providerSpec.value.networkInterfaces[0].stackType: Unsupported value: \"InvalidStackType\": supported values: \"DualStack\", \"IPv4Only\"" + - name: Should reject invalid ipv6AccessType value + initial: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: DualStack + ipv6AccessType: InvalidAccessType + expectedError: "spec.providerSpec.value.networkInterfaces[0].ipv6AccessType: Unsupported value: \"InvalidAccessType\": supported values: \"External\", \"Internal\"" + - name: Should be able to create a GCP machine with IPv4Only and IPv6 fields omitted + initial: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: IPv4Only + expected: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + authoritativeAPI: MachineAPI + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: IPv4Only + - name: Should default stackType to IPv4Only when not specified + initial: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + expected: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + authoritativeAPI: MachineAPI + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: IPv4Only + onUpdate: + - name: Should allow updating stackType from IPv4Only to DualStack + initial: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: IPv4Only + updated: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: DualStack + expected: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + authoritativeAPI: MachineAPI + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: DualStack + - name: Should allow updating stackType from DualStack to IPv4Only + initial: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: DualStack + updated: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: IPv4Only + expected: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + authoritativeAPI: MachineAPI + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: IPv4Only + - name: Should allow adding IPv6 address to existing DualStack interface + initial: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: DualStack + updated: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: DualStack + ipv6Address: "2001:db8::1" + expected: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + authoritativeAPI: MachineAPI + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: DualStack + ipv6Address: "2001:db8::1" + - name: Should allow changing ipv6AccessType from External to Internal + initial: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: DualStack + ipv6AccessType: External + updated: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: DualStack + ipv6AccessType: Internal + expected: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + authoritativeAPI: MachineAPI + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: DualStack + ipv6AccessType: Internal + - name: Should allow changing IPv6 address on DualStack interface + initial: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: DualStack + ipv6Address: "2001:db8::1" + updated: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: DualStack + ipv6Address: "2001:db8::2" + expected: | + apiVersion: machine.openshift.io/v1beta1 + kind: Machine + spec: + authoritativeAPI: MachineAPI + providerSpec: + value: + apiVersion: machine.openshift.io/v1beta1 + kind: GCPMachineProviderSpec + machineType: n1-standard-4 + region: us-central1 + zone: us-central1-a + networkInterfaces: + - network: test-network + subnetwork: test-subnet + stackType: DualStack + ipv6Address: "2001:db8::2" diff --git a/machine/v1beta1/types_gcpprovider.go b/machine/v1beta1/types_gcpprovider.go index 9713a4e4a87..385bd7ee861 100644 --- a/machine/v1beta1/types_gcpprovider.go +++ b/machine/v1beta1/types_gcpprovider.go @@ -254,6 +254,30 @@ type GCPMetadata struct { Value *string `json:"value"` } +// StackType represents the type of network stack for the cluster. +// +kubebuilder:validation:Enum=IPv4Only;DualStack +type StackType string + +const ( + // IPv4OnlyStackType indicates that the network can only accept and use IPv4 addresses. + IPv4OnlyStackType StackType = "IPv4Only" + + // DualStackStackType indicates that the network can accept and use IPv4 and IPv6 addresses. + DualStackStackType StackType = "DualStack" +) + +// IPv6AccessType represents the type of network access for the IPv6 capable network interface. +// +kubebuilder:validation:Enum=External;Internal +type IPv6AccessType string + +const ( + // ExternalIPv6AccessType indicates that the network contains IPv6 addresses that can access the internet. + ExternalIPv6AccessType IPv6AccessType = "External" + + // InternalIPv6AccessType indicates that the network contains IPv6 addresses that cannot access the internet. + InternalIPv6AccessType IPv6AccessType = "Internal" +) + // GCPNetworkInterface describes network interfaces for GCP type GCPNetworkInterface struct { // publicIP indicates if true a public IP will be used @@ -264,6 +288,28 @@ type GCPNetworkInterface struct { ProjectID string `json:"projectID,omitempty"` // subnetwork is the subnetwork name. Subnetwork string `json:"subnetwork,omitempty"` + + // stackType determines the IP stack configuration for the network interface. + // This field defaults to IPv4Only. Valid values are "IPv4Only" and "DualStack". + // + // +kubebuilder:default:="IPv4Only" + // +optional + // +default="IPv4Only" + StackType StackType `json:"stackType,omitempty"` + + // ipv6Address is an IPv6 internal network address for this network interface. + // To use a static internal IP address, it must be unused and in the same region as the instance's zone. + // If not specified and stackType is "DualStack", Google Cloud can automatically assign an internal IPv6 address. + // +optional + IPv6Address string `json:"ipv6Address,omitempty"` + + // ipv6AccessType indicates whether the IPv6 endpoint can be accessed from the Internet. + // Valid values are "External" or "Internal". Only valid when stackType is "DualStack". + // + // +kubebuilder:default:="External" + // +optional + // +default="External" + IPv6AccessType IPv6AccessType `json:"ipv6AccessType,omitempty"` } // GCPServiceAccount describes service accounts for GCP. diff --git a/machine/v1beta1/zz_generated.swagger_doc_generated.go b/machine/v1beta1/zz_generated.swagger_doc_generated.go index 2c4a9030cc9..3ed228c93b9 100644 --- a/machine/v1beta1/zz_generated.swagger_doc_generated.go +++ b/machine/v1beta1/zz_generated.swagger_doc_generated.go @@ -528,11 +528,14 @@ func (GCPMetadata) SwaggerDoc() map[string]string { } var map_GCPNetworkInterface = map[string]string{ - "": "GCPNetworkInterface describes network interfaces for GCP", - "publicIP": "publicIP indicates if true a public IP will be used", - "network": "network is the network name.", - "projectID": "projectID is the project in which the GCP machine provider will create the VM.", - "subnetwork": "subnetwork is the subnetwork name.", + "": "GCPNetworkInterface describes network interfaces for GCP", + "publicIP": "publicIP indicates if true a public IP will be used", + "network": "network is the network name.", + "projectID": "projectID is the project in which the GCP machine provider will create the VM.", + "subnetwork": "subnetwork is the subnetwork name.", + "stackType": "stackType determines the IP stack configuration for the network interface. This field defaults to IPv4Only. Valid values are \"IPv4Only\" and \"DualStack\".", + "ipv6Address": "ipv6Address is an IPv6 internal network address for this network interface. To use a static internal IP address, it must be unused and in the same region as the instance's zone. If not specified and stackType is \"DualStack\", Google Cloud can automatically assign an internal IPv6 address.", + "ipv6AccessType": "ipv6AccessType indicates whether the IPv6 endpoint can be accessed from the Internet. Valid values are \"External\" or \"Internal\". Only valid when stackType is \"DualStack\".", } func (GCPNetworkInterface) SwaggerDoc() map[string]string { diff --git a/openapi/generated_openapi/zz_generated.openapi.go b/openapi/generated_openapi/zz_generated.openapi.go index 967c191d6be..52e813b3f9d 100644 --- a/openapi/generated_openapi/zz_generated.openapi.go +++ b/openapi/generated_openapi/zz_generated.openapi.go @@ -44059,6 +44059,29 @@ func schema_openshift_api_machine_v1beta1_GCPNetworkInterface(ref common.Referen Format: "", }, }, + "stackType": { + SchemaProps: spec.SchemaProps{ + Description: "stackType determines the IP stack configuration for the network interface. This field defaults to IPv4Only. Valid values are \"IPv4Only\" and \"DualStack\".", + Default: "IPv4Only", + Type: []string{"string"}, + Format: "", + }, + }, + "ipv6Address": { + SchemaProps: spec.SchemaProps{ + Description: "ipv6Address is an IPv6 internal network address for this network interface. To use a static internal IP address, it must be unused and in the same region as the instance's zone. If not specified and stackType is \"DualStack\", Google Cloud can automatically assign an internal IPv6 address.", + Type: []string{"string"}, + Format: "", + }, + }, + "ipv6AccessType": { + SchemaProps: spec.SchemaProps{ + Description: "ipv6AccessType indicates whether the IPv6 endpoint can be accessed from the Internet. Valid values are \"External\" or \"Internal\". Only valid when stackType is \"DualStack\".", + Default: "External", + Type: []string{"string"}, + Format: "", + }, + }, }, }, },