From 891839157e3ddf5e378a24430cd79e0ceaddc0fe Mon Sep 17 00:00:00 2001 From: Joel Speed Date: Fri, 23 Jun 2023 10:56:29 +0100 Subject: [PATCH 1/3] Update actuator pkg vendor --- go.mod | 4 +- go.sum | 8 +- .../openshift/api/machine/v1alpha1/doc.go | 7 + .../api/machine/v1alpha1/register.go | 38 ++ .../api/machine/v1alpha1/types_openstack.go | 368 ++++++++++++++++++ .../machine/v1alpha1/zz_generated.deepcopy.go | 346 ++++++++++++++++ .../zz_generated.swagger_doc_generated.go | 196 ++++++++++ .../testutils/Makefile | 2 +- .../config/v1/infrastructure.go | 27 ++ .../machine/v1/openstack_failure_domains.go | 106 +++++ .../machine/v1beta1/machine.go | 10 + .../v1beta1/openstack_provider_spec.go | 134 +++++++ vendor/k8s.io/klog/v2/format.go | 65 ++++ .../klog/v2/internal/serialize/keyvalues.go | 47 ++- vendor/k8s.io/klog/v2/k8s_references.go | 12 +- vendor/k8s.io/klog/v2/klog.go | 13 + vendor/modules.txt | 5 +- 17 files changed, 1354 insertions(+), 34 deletions(-) create mode 100644 vendor/github.com/openshift/api/machine/v1alpha1/doc.go create mode 100644 vendor/github.com/openshift/api/machine/v1alpha1/register.go create mode 100644 vendor/github.com/openshift/api/machine/v1alpha1/types_openstack.go create mode 100644 vendor/github.com/openshift/api/machine/v1alpha1/zz_generated.deepcopy.go create mode 100644 vendor/github.com/openshift/api/machine/v1alpha1/zz_generated.swagger_doc_generated.go create mode 100644 vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/machine/v1/openstack_failure_domains.go create mode 100644 vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/machine/v1beta1/openstack_provider_spec.go create mode 100644 vendor/k8s.io/klog/v2/format.go diff --git a/go.mod b/go.mod index c06fd1907..bec41a4a2 100644 --- a/go.mod +++ b/go.mod @@ -11,14 +11,14 @@ require ( github.com/onsi/gomega v1.27.7 github.com/openshift/api v0.0.0-20230627091025-b88ff67980ac github.com/openshift/client-go v0.0.0-20230503144108-75015d2347cb - github.com/openshift/cluster-api-actuator-pkg/testutils v0.0.0-20230428103603-98e6d5c4def7 + github.com/openshift/cluster-api-actuator-pkg/testutils v0.0.0-20230622171654-75c6bcfa831c github.com/openshift/library-go v0.0.0-20230523150659-ab179469ba38 github.com/spf13/pflag v1.0.5 k8s.io/api v0.27.2 k8s.io/apimachinery v0.27.2 k8s.io/client-go v0.27.2 k8s.io/component-base v0.27.2 - k8s.io/klog/v2 v2.90.1 + k8s.io/klog/v2 v2.100.1 k8s.io/utils v0.0.0-20230505201702-9f6742963106 sigs.k8s.io/controller-runtime v0.15.0 sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20230524094249-73949d01fbbe diff --git a/go.sum b/go.sum index 38c78e040..bbe9abaab 100644 --- a/go.sum +++ b/go.sum @@ -449,8 +449,8 @@ github.com/openshift/api v0.0.0-20230627091025-b88ff67980ac h1:bY6f6tb7ZUNb6Lfsm github.com/openshift/api v0.0.0-20230627091025-b88ff67980ac/go.mod h1:4VWG+W22wrB4HfBL88P40DxLEpSOaiBVxUnfalfJo9k= github.com/openshift/client-go v0.0.0-20230503144108-75015d2347cb h1:Nij5OnaECrkmcRQMAE9LMbQXPo95aqFnf+12B7SyFVI= github.com/openshift/client-go v0.0.0-20230503144108-75015d2347cb/go.mod h1:Rhb3moCqeiTuGHAbXBOlwPubUMlOZEkrEWTRjIF3jzs= -github.com/openshift/cluster-api-actuator-pkg/testutils v0.0.0-20230428103603-98e6d5c4def7 h1:I4kHqyechQ8p0BpEXanEsT4oavRs9ldWFv6uOvuPAAU= -github.com/openshift/cluster-api-actuator-pkg/testutils v0.0.0-20230428103603-98e6d5c4def7/go.mod h1:p8CKj6ENJj5euJ3Grs71A9wwzBs9EzC1BcVlHCIPJg8= +github.com/openshift/cluster-api-actuator-pkg/testutils v0.0.0-20230622171654-75c6bcfa831c h1:2EpVQ7ZZIvpm3PExUIjrIHknRAfyJBr0xjUJFQjYaxA= +github.com/openshift/cluster-api-actuator-pkg/testutils v0.0.0-20230622171654-75c6bcfa831c/go.mod h1:w4P7zcu7okmBpkjKJK71rl5hp1a8RFm1NraVrxVqiUs= github.com/openshift/library-go v0.0.0-20230523150659-ab179469ba38 h1:rKEpSwRxeQ6eN915GbcuyikwyWu//V61w5zIUWD9b2U= github.com/openshift/library-go v0.0.0-20230523150659-ab179469ba38/go.mod h1:PJVatR/oS/EaFciwylyAr9hORSqQHrC+5bXf4L0wsBY= github.com/otiai10/copy v1.2.0 h1:HvG945u96iNadPoG2/Ja2+AUJeW5YuFQMixq9yirC+k= @@ -1067,8 +1067,8 @@ k8s.io/client-go v0.27.2 h1:vDLSeuYvCHKeoQRhCXjxXO45nHVv2Ip4Fe0MfioMrhE= k8s.io/client-go v0.27.2/go.mod h1:tY0gVmUsHrAmjzHX9zs7eCjxcBsf8IiNe7KQ52biTcQ= k8s.io/component-base v0.27.2 h1:neju+7s/r5O4x4/txeUONNTS9r1HsPbyoPBAtHsDCpo= k8s.io/component-base v0.27.2/go.mod h1:5UPk7EjfgrfgRIuDBFtsEFAe4DAvP3U+M8RTzoSJkpo= -k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= -k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= k8s.io/utils v0.0.0-20230505201702-9f6742963106 h1:EObNQ3TW2D+WptiYXlApGNLVy0zm/JIBVY9i+M4wpAU= diff --git a/vendor/github.com/openshift/api/machine/v1alpha1/doc.go b/vendor/github.com/openshift/api/machine/v1alpha1/doc.go new file mode 100644 index 000000000..111cacb63 --- /dev/null +++ b/vendor/github.com/openshift/api/machine/v1alpha1/doc.go @@ -0,0 +1,7 @@ +// +k8s:deepcopy-gen=package,register +// +k8s:defaulter-gen=TypeMeta +// +k8s:openapi-gen=true + +// +kubebuilder:validation:Optional +// +groupName=machine.openshift.io +package v1alpha1 diff --git a/vendor/github.com/openshift/api/machine/v1alpha1/register.go b/vendor/github.com/openshift/api/machine/v1alpha1/register.go new file mode 100644 index 000000000..ef96c4720 --- /dev/null +++ b/vendor/github.com/openshift/api/machine/v1alpha1/register.go @@ -0,0 +1,38 @@ +/* + Copyright 2022 Red Hat, Inc. + + 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 v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +const GroupName = "machine.openshift.io" + +var ( + GroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} + schemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + // Install is a function which adds this version to a scheme + Install = schemeBuilder.AddToScheme +) + +// Adds the list of known types to api.Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + metav1.AddToGroupVersion(scheme, GroupVersion) + return nil +} diff --git a/vendor/github.com/openshift/api/machine/v1alpha1/types_openstack.go b/vendor/github.com/openshift/api/machine/v1alpha1/types_openstack.go new file mode 100644 index 000000000..e3dd4d0a0 --- /dev/null +++ b/vendor/github.com/openshift/api/machine/v1alpha1/types_openstack.go @@ -0,0 +1,368 @@ +/* +Copyright 2018 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 v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// OpenstackProviderSpec is the type that will be embedded in a Machine.Spec.ProviderSpec field +// for an OpenStack Instance. It is used by the Openstack machine actuator to create a single machine instance. +// +k8s:openapi-gen=true +// Compatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support. +// +openshift:compatibility-gen:level=4 +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type OpenstackProviderSpec struct { + metav1.TypeMeta `json:",inline"` + + // metadata is the standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata,omitempty"` + + // The name of the secret containing the openstack credentials + CloudsSecret *corev1.SecretReference `json:"cloudsSecret"` + + // The name of the cloud to use from the clouds secret + CloudName string `json:"cloudName"` + + // The flavor reference for the flavor for your server instance. + Flavor string `json:"flavor"` + + // The name of the image to use for your server instance. + // If the RootVolume is specified, this will be ignored and use rootVolume directly. + Image string `json:"image"` + + // The ssh key to inject in the instance + KeyName string `json:"keyName,omitempty"` + + // The machine ssh username + SshUserName string `json:"sshUserName,omitempty"` + + // A networks object. Required parameter when there are multiple networks defined for the tenant. + // When you do not specify the networks parameter, the server attaches to the only network created for the current tenant. + Networks []NetworkParam `json:"networks,omitempty"` + + // Create and assign additional ports to instances + Ports []PortOpts `json:"ports,omitempty"` + + // floatingIP specifies a floating IP to be associated with the machine. + // Note that it is not safe to use this parameter in a MachineSet, as + // only one Machine may be assigned the same floating IP. + // + // Deprecated: floatingIP will be removed in a future release as it cannot be implemented correctly. + FloatingIP string `json:"floatingIP,omitempty"` + + // The availability zone from which to launch the server. + AvailabilityZone string `json:"availabilityZone,omitempty"` + + // The names of the security groups to assign to the instance + SecurityGroups []SecurityGroupParam `json:"securityGroups,omitempty"` + + // The name of the secret containing the user data (startup script in most cases) + UserDataSecret *corev1.SecretReference `json:"userDataSecret,omitempty"` + + // Whether the server instance is created on a trunk port or not. + Trunk bool `json:"trunk,omitempty"` + + // Machine tags + // Requires Nova api 2.52 minimum! + Tags []string `json:"tags,omitempty"` + + // Metadata mapping. Allows you to create a map of key value pairs to add to the server instance. + ServerMetadata map[string]string `json:"serverMetadata,omitempty"` + + // Config Drive support + ConfigDrive *bool `json:"configDrive,omitempty"` + + // The volume metadata to boot from + RootVolume *RootVolume `json:"rootVolume,omitempty"` + + // The server group to assign the machine to. + ServerGroupID string `json:"serverGroupID,omitempty"` + + // The server group to assign the machine to. A server group with that + // name will be created if it does not exist. If both ServerGroupID and + // ServerGroupName are non-empty, they must refer to the same OpenStack + // resource. + ServerGroupName string `json:"serverGroupName,omitempty"` + + // The subnet that a set of machines will get ingress/egress traffic from + PrimarySubnet string `json:"primarySubnet,omitempty"` +} + +type SecurityGroupParam struct { + // Security Group UUID + UUID string `json:"uuid,omitempty"` + // Security Group name + Name string `json:"name,omitempty"` + // Filters used to query security groups in openstack + Filter SecurityGroupFilter `json:"filter,omitempty"` +} + +type SecurityGroupFilter struct { + // id specifies the ID of a security group to use. If set, id will not + // be validated before use. An invalid id will result in failure to + // create a server with an appropriate error message. + ID string `json:"id,omitempty"` + // name filters security groups by name. + Name string `json:"name,omitempty"` + // description filters security groups by description. + Description string `json:"description,omitempty"` + // tenantId filters security groups by tenant ID. + // Deprecated: use projectId instead. tenantId will be ignored if projectId is set. + TenantID string `json:"tenantId,omitempty"` + // projectId filters security groups by project ID. + ProjectID string `json:"projectId,omitempty"` + // tags filters by security groups containing all specified tags. + // Multiple tags are comma separated. + Tags string `json:"tags,omitempty"` + // tagsAny filters by security groups containing any specified tags. + // Multiple tags are comma separated. + TagsAny string `json:"tagsAny,omitempty"` + // notTags filters by security groups which don't match all specified tags. NOT (t1 AND t2...) + // Multiple tags are comma separated. + NotTags string `json:"notTags,omitempty"` + // notTagsAny filters by security groups which don't match any specified tags. NOT (t1 OR t2...) + // Multiple tags are comma separated. + NotTagsAny string `json:"notTagsAny,omitempty"` + + // Deprecated: limit is silently ignored. It has no replacement. + DeprecatedLimit int `json:"limit,omitempty"` + // Deprecated: marker is silently ignored. It has no replacement. + DeprecatedMarker string `json:"marker,omitempty"` + // Deprecated: sortKey is silently ignored. It has no replacement. + DeprecatedSortKey string `json:"sortKey,omitempty"` + // Deprecated: sortDir is silently ignored. It has no replacement. + DeprecatedSortDir string `json:"sortDir,omitempty"` +} + +type NetworkParam struct { + // The UUID of the network. Required if you omit the port attribute. + UUID string `json:"uuid,omitempty"` + // A fixed IPv4 address for the NIC. + FixedIp string `json:"fixedIp,omitempty"` + // Filters for optional network query + Filter Filter `json:"filter,omitempty"` + // Subnet within a network to use + Subnets []SubnetParam `json:"subnets,omitempty"` + // NoAllowedAddressPairs disables creation of allowed address pairs for the network ports + NoAllowedAddressPairs bool `json:"noAllowedAddressPairs,omitempty"` + // PortTags allows users to specify a list of tags to add to ports created in a given network + PortTags []string `json:"portTags,omitempty"` + // The virtual network interface card (vNIC) type that is bound to the + // neutron port. + VNICType string `json:"vnicType,omitempty"` + // A dictionary that enables the application running on the specified + // host to pass and receive virtual network interface (VIF) port-specific + // information to the plug-in. + Profile map[string]string `json:"profile,omitempty"` + // PortSecurity optionally enables or disables security on ports managed by OpenStack + PortSecurity *bool `json:"portSecurity,omitempty"` +} + +type Filter struct { + // Deprecated: use NetworkParam.uuid instead. Ignored if NetworkParam.uuid is set. + ID string `json:"id,omitempty"` + // name filters networks by name. + Name string `json:"name,omitempty"` + // description filters networks by description. + Description string `json:"description,omitempty"` + // tenantId filters networks by tenant ID. + // Deprecated: use projectId instead. tenantId will be ignored if projectId is set. + TenantID string `json:"tenantId,omitempty"` + // projectId filters networks by project ID. + ProjectID string `json:"projectId,omitempty"` + // tags filters by networks containing all specified tags. + // Multiple tags are comma separated. + Tags string `json:"tags,omitempty"` + // tagsAny filters by networks containing any specified tags. + // Multiple tags are comma separated. + TagsAny string `json:"tagsAny,omitempty"` + // notTags filters by networks which don't match all specified tags. NOT (t1 AND t2...) + // Multiple tags are comma separated. + NotTags string `json:"notTags,omitempty"` + // notTagsAny filters by networks which don't match any specified tags. NOT (t1 OR t2...) + // Multiple tags are comma separated. + NotTagsAny string `json:"notTagsAny,omitempty"` + + // Deprecated: status is silently ignored. It has no replacement. + DeprecatedStatus string `json:"status,omitempty"` + // Deprecated: adminStateUp is silently ignored. It has no replacement. + DeprecatedAdminStateUp *bool `json:"adminStateUp,omitempty"` + // Deprecated: shared is silently ignored. It has no replacement. + DeprecatedShared *bool `json:"shared,omitempty"` + // Deprecated: marker is silently ignored. It has no replacement. + DeprecatedMarker string `json:"marker,omitempty"` + // Deprecated: limit is silently ignored. It has no replacement. + DeprecatedLimit int `json:"limit,omitempty"` + // Deprecated: sortKey is silently ignored. It has no replacement. + DeprecatedSortKey string `json:"sortKey,omitempty"` + // Deprecated: sortDir is silently ignored. It has no replacement. + DeprecatedSortDir string `json:"sortDir,omitempty"` +} + +type SubnetParam struct { + // The UUID of the network. Required if you omit the port attribute. + UUID string `json:"uuid,omitempty"` + + // Filters for optional network query + Filter SubnetFilter `json:"filter,omitempty"` + + // PortTags are tags that are added to ports created on this subnet + PortTags []string `json:"portTags,omitempty"` + + // PortSecurity optionally enables or disables security on ports managed by OpenStack + PortSecurity *bool `json:"portSecurity,omitempty"` +} + +type SubnetFilter struct { + // id is the uuid of a specific subnet to use. If specified, id will not + // be validated. Instead server creation will fail with an appropriate + // error. + ID string `json:"id,omitempty"` + // name filters subnets by name. + Name string `json:"name,omitempty"` + // description filters subnets by description. + Description string `json:"description,omitempty"` + // Deprecated: networkId is silently ignored. Set uuid on the containing network definition instead. + NetworkID string `json:"networkId,omitempty"` + // tenantId filters subnets by tenant ID. + // Deprecated: use projectId instead. tenantId will be ignored if projectId is set. + TenantID string `json:"tenantId,omitempty"` + // projectId filters subnets by project ID. + ProjectID string `json:"projectId,omitempty"` + // ipVersion filters subnets by IP version. + IPVersion int `json:"ipVersion,omitempty"` + // gateway_ip filters subnets by gateway IP. + GatewayIP string `json:"gateway_ip,omitempty"` + // cidr filters subnets by CIDR. + CIDR string `json:"cidr,omitempty"` + // ipv6AddressMode filters subnets by IPv6 address mode. + IPv6AddressMode string `json:"ipv6AddressMode,omitempty"` + // ipv6RaMode filters subnets by IPv6 router adversiement mode. + IPv6RAMode string `json:"ipv6RaMode,omitempty"` + // subnetpoolId filters subnets by subnet pool ID. + SubnetPoolID string `json:"subnetpoolId,omitempty"` + // tags filters by subnets containing all specified tags. + // Multiple tags are comma separated. + Tags string `json:"tags,omitempty"` + // tagsAny filters by subnets containing any specified tags. + // Multiple tags are comma separated. + TagsAny string `json:"tagsAny,omitempty"` + // notTags filters by subnets which don't match all specified tags. NOT (t1 AND t2...) + // Multiple tags are comma separated. + NotTags string `json:"notTags,omitempty"` + // notTagsAny filters by subnets which don't match any specified tags. NOT (t1 OR t2...) + // Multiple tags are comma separated. + NotTagsAny string `json:"notTagsAny,omitempty"` + + // Deprecated: enableDhcp is silently ignored. It has no replacement. + DeprecatedEnableDHCP *bool `json:"enableDhcp,omitempty"` + // Deprecated: limit is silently ignored. It has no replacement. + DeprecatedLimit int `json:"limit,omitempty"` + // Deprecated: marker is silently ignored. It has no replacement. + DeprecatedMarker string `json:"marker,omitempty"` + // Deprecated: sortKey is silently ignored. It has no replacement. + DeprecatedSortKey string `json:"sortKey,omitempty"` + // Deprecated: sortDir is silently ignored. It has no replacement. + DeprecatedSortDir string `json:"sortDir,omitempty"` +} + +type PortOpts struct { + // networkID is the ID of the network the port will be created in. It is required. + // +required + NetworkID string `json:"networkID"` + // If nameSuffix is specified the created port will be named -. + // If not specified the port will be named -. + NameSuffix string `json:"nameSuffix,omitempty"` + // description specifies the description of the created port. + Description string `json:"description,omitempty"` + // adminStateUp sets the administrative state of the created port to up (true), or down (false). + AdminStateUp *bool `json:"adminStateUp,omitempty"` + // macAddress specifies the MAC address of the created port. + MACAddress string `json:"macAddress,omitempty"` + // fixedIPs specifies a set of fixed IPs to assign to the port. They must all be valid for the port's network. + FixedIPs []FixedIPs `json:"fixedIPs,omitempty"` + // tenantID specifies the tenant ID of the created port. Note that this + // requires OpenShift to have administrative permissions, which is + // typically not the case. Use of this field is not recommended. + // Deprecated: use projectID instead. It will be ignored if projectID is set. + TenantID string `json:"tenantID,omitempty"` + // projectID specifies the project ID of the created port. Note that this + // requires OpenShift to have administrative permissions, which is + // typically not the case. Use of this field is not recommended. + ProjectID string `json:"projectID,omitempty"` + // securityGroups specifies a set of security group UUIDs to use instead + // of the machine's default security groups. The default security groups + // will be used if this is left empty or not specified. + SecurityGroups *[]string `json:"securityGroups,omitempty"` + // allowedAddressPairs specifies a set of allowed address pairs to add to the port. + AllowedAddressPairs []AddressPair `json:"allowedAddressPairs,omitempty"` + // tags species a set of tags to add to the port. + Tags []string `json:"tags,omitempty"` + // The virtual network interface card (vNIC) type that is bound to the + // neutron port. + VNICType string `json:"vnicType,omitempty"` + // A dictionary that enables the application running on the specified + // host to pass and receive virtual network interface (VIF) port-specific + // information to the plug-in. + Profile map[string]string `json:"profile,omitempty"` + // enable or disable security on a given port + // incompatible with securityGroups and allowedAddressPairs + PortSecurity *bool `json:"portSecurity,omitempty"` + // Enables and disables trunk at port level. If not provided, openStackMachine.Spec.Trunk is inherited. + Trunk *bool `json:"trunk,omitempty"` + + // The ID of the host where the port is allocated. Do not use this + // field: it cannot be used correctly. + // Deprecated: hostID is silently ignored. It will be removed with no replacement. + DeprecatedHostID string `json:"hostID,omitempty"` +} + +type AddressPair struct { + IPAddress string `json:"ipAddress,omitempty"` + MACAddress string `json:"macAddress,omitempty"` +} + +type FixedIPs struct { + // subnetID specifies the ID of the subnet where the fixed IP will be allocated. + SubnetID string `json:"subnetID"` + // ipAddress is a specific IP address to use in the given subnet. Port + // creation will fail if the address is not available. If not specified, + // an available IP from the given subnet will be selected automatically. + IPAddress string `json:"ipAddress,omitempty"` +} + +type RootVolume struct { + // sourceUUID specifies the UUID of a glance image used to populate the root volume. + // Deprecated: set image in the platform spec instead. This will be + // ignored if image is set in the platform spec. + SourceUUID string `json:"sourceUUID,omitempty"` + // volumeType specifies a volume type to use when creating the root + // volume. If not specified the default volume type will be used. + VolumeType string `json:"volumeType,omitempty"` + // diskSize specifies the size, in GB, of the created root volume. + Size int `json:"diskSize,omitempty"` + // availabilityZone specifies the Cinder availability where the root volume will be created. + Zone string `json:"availabilityZone,omitempty"` + + // Deprecated: sourceType will be silently ignored. There is no replacement. + DeprecatedSourceType string `json:"sourceType,omitempty"` + // Deprecated: deviceType will be silently ignored. There is no replacement. + DeprecatedDeviceType string `json:"deviceType,omitempty"` +} diff --git a/vendor/github.com/openshift/api/machine/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/openshift/api/machine/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 000000000..7210713e3 --- /dev/null +++ b/vendor/github.com/openshift/api/machine/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,346 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/api/core/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AddressPair) DeepCopyInto(out *AddressPair) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AddressPair. +func (in *AddressPair) DeepCopy() *AddressPair { + if in == nil { + return nil + } + out := new(AddressPair) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Filter) DeepCopyInto(out *Filter) { + *out = *in + if in.DeprecatedAdminStateUp != nil { + in, out := &in.DeprecatedAdminStateUp, &out.DeprecatedAdminStateUp + *out = new(bool) + **out = **in + } + if in.DeprecatedShared != nil { + in, out := &in.DeprecatedShared, &out.DeprecatedShared + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Filter. +func (in *Filter) DeepCopy() *Filter { + if in == nil { + return nil + } + out := new(Filter) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FixedIPs) DeepCopyInto(out *FixedIPs) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FixedIPs. +func (in *FixedIPs) DeepCopy() *FixedIPs { + if in == nil { + return nil + } + out := new(FixedIPs) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetworkParam) DeepCopyInto(out *NetworkParam) { + *out = *in + in.Filter.DeepCopyInto(&out.Filter) + if in.Subnets != nil { + in, out := &in.Subnets, &out.Subnets + *out = make([]SubnetParam, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.PortTags != nil { + in, out := &in.PortTags, &out.PortTags + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Profile != nil { + in, out := &in.Profile, &out.Profile + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.PortSecurity != nil { + in, out := &in.PortSecurity, &out.PortSecurity + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkParam. +func (in *NetworkParam) DeepCopy() *NetworkParam { + if in == nil { + return nil + } + out := new(NetworkParam) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenstackProviderSpec) DeepCopyInto(out *OpenstackProviderSpec) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.CloudsSecret != nil { + in, out := &in.CloudsSecret, &out.CloudsSecret + *out = new(v1.SecretReference) + **out = **in + } + if in.Networks != nil { + in, out := &in.Networks, &out.Networks + *out = make([]NetworkParam, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Ports != nil { + in, out := &in.Ports, &out.Ports + *out = make([]PortOpts, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.SecurityGroups != nil { + in, out := &in.SecurityGroups, &out.SecurityGroups + *out = make([]SecurityGroupParam, len(*in)) + copy(*out, *in) + } + if in.UserDataSecret != nil { + in, out := &in.UserDataSecret, &out.UserDataSecret + *out = new(v1.SecretReference) + **out = **in + } + if in.Tags != nil { + in, out := &in.Tags, &out.Tags + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.ServerMetadata != nil { + in, out := &in.ServerMetadata, &out.ServerMetadata + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.ConfigDrive != nil { + in, out := &in.ConfigDrive, &out.ConfigDrive + *out = new(bool) + **out = **in + } + if in.RootVolume != nil { + in, out := &in.RootVolume, &out.RootVolume + *out = new(RootVolume) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenstackProviderSpec. +func (in *OpenstackProviderSpec) DeepCopy() *OpenstackProviderSpec { + if in == nil { + return nil + } + out := new(OpenstackProviderSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OpenstackProviderSpec) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PortOpts) DeepCopyInto(out *PortOpts) { + *out = *in + if in.AdminStateUp != nil { + in, out := &in.AdminStateUp, &out.AdminStateUp + *out = new(bool) + **out = **in + } + if in.FixedIPs != nil { + in, out := &in.FixedIPs, &out.FixedIPs + *out = make([]FixedIPs, len(*in)) + copy(*out, *in) + } + if in.SecurityGroups != nil { + in, out := &in.SecurityGroups, &out.SecurityGroups + *out = new([]string) + if **in != nil { + in, out := *in, *out + *out = make([]string, len(*in)) + copy(*out, *in) + } + } + if in.AllowedAddressPairs != nil { + in, out := &in.AllowedAddressPairs, &out.AllowedAddressPairs + *out = make([]AddressPair, len(*in)) + copy(*out, *in) + } + if in.Tags != nil { + in, out := &in.Tags, &out.Tags + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Profile != nil { + in, out := &in.Profile, &out.Profile + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.PortSecurity != nil { + in, out := &in.PortSecurity, &out.PortSecurity + *out = new(bool) + **out = **in + } + if in.Trunk != nil { + in, out := &in.Trunk, &out.Trunk + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PortOpts. +func (in *PortOpts) DeepCopy() *PortOpts { + if in == nil { + return nil + } + out := new(PortOpts) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RootVolume) DeepCopyInto(out *RootVolume) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RootVolume. +func (in *RootVolume) DeepCopy() *RootVolume { + if in == nil { + return nil + } + out := new(RootVolume) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecurityGroupFilter) DeepCopyInto(out *SecurityGroupFilter) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityGroupFilter. +func (in *SecurityGroupFilter) DeepCopy() *SecurityGroupFilter { + if in == nil { + return nil + } + out := new(SecurityGroupFilter) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecurityGroupParam) DeepCopyInto(out *SecurityGroupParam) { + *out = *in + out.Filter = in.Filter + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityGroupParam. +func (in *SecurityGroupParam) DeepCopy() *SecurityGroupParam { + if in == nil { + return nil + } + out := new(SecurityGroupParam) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubnetFilter) DeepCopyInto(out *SubnetFilter) { + *out = *in + if in.DeprecatedEnableDHCP != nil { + in, out := &in.DeprecatedEnableDHCP, &out.DeprecatedEnableDHCP + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubnetFilter. +func (in *SubnetFilter) DeepCopy() *SubnetFilter { + if in == nil { + return nil + } + out := new(SubnetFilter) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubnetParam) DeepCopyInto(out *SubnetParam) { + *out = *in + in.Filter.DeepCopyInto(&out.Filter) + if in.PortTags != nil { + in, out := &in.PortTags, &out.PortTags + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.PortSecurity != nil { + in, out := &in.PortSecurity, &out.PortSecurity + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubnetParam. +func (in *SubnetParam) DeepCopy() *SubnetParam { + if in == nil { + return nil + } + out := new(SubnetParam) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/github.com/openshift/api/machine/v1alpha1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/machine/v1alpha1/zz_generated.swagger_doc_generated.go new file mode 100644 index 000000000..3ea9595d2 --- /dev/null +++ b/vendor/github.com/openshift/api/machine/v1alpha1/zz_generated.swagger_doc_generated.go @@ -0,0 +1,196 @@ +package v1alpha1 + +// This file contains a collection of methods that can be used from go-restful to +// generate Swagger API documentation for its models. Please read this PR for more +// information on the implementation: https://github.com/emicklei/go-restful/pull/215 +// +// TODOs are ignored from the parser (e.g. TODO(andronat):... || TODO:...) if and only if +// they are on one line! For multiple line or blocks that you want to ignore use ---. +// Any context after a --- is ignored. +// +// Those methods can be generated by using hack/update-swagger-docs.sh + +// AUTO-GENERATED FUNCTIONS START HERE +var map_Filter = map[string]string{ + "id": "Deprecated: use NetworkParam.uuid instead. Ignored if NetworkParam.uuid is set.", + "name": "name filters networks by name.", + "description": "description filters networks by description.", + "tenantId": "tenantId filters networks by tenant ID. Deprecated: use projectId instead. tenantId will be ignored if projectId is set.", + "projectId": "projectId filters networks by project ID.", + "tags": "tags filters by networks containing all specified tags. Multiple tags are comma separated.", + "tagsAny": "tagsAny filters by networks containing any specified tags. Multiple tags are comma separated.", + "notTags": "notTags filters by networks which don't match all specified tags. NOT (t1 AND t2...) Multiple tags are comma separated.", + "notTagsAny": "notTagsAny filters by networks which don't match any specified tags. NOT (t1 OR t2...) Multiple tags are comma separated.", + "status": "Deprecated: status is silently ignored. It has no replacement.", + "adminStateUp": "Deprecated: adminStateUp is silently ignored. It has no replacement.", + "shared": "Deprecated: shared is silently ignored. It has no replacement.", + "marker": "Deprecated: marker is silently ignored. It has no replacement.", + "limit": "Deprecated: limit is silently ignored. It has no replacement.", + "sortKey": "Deprecated: sortKey is silently ignored. It has no replacement.", + "sortDir": "Deprecated: sortDir is silently ignored. It has no replacement.", +} + +func (Filter) SwaggerDoc() map[string]string { + return map_Filter +} + +var map_FixedIPs = map[string]string{ + "subnetID": "subnetID specifies the ID of the subnet where the fixed IP will be allocated.", + "ipAddress": "ipAddress is a specific IP address to use in the given subnet. Port creation will fail if the address is not available. If not specified, an available IP from the given subnet will be selected automatically.", +} + +func (FixedIPs) SwaggerDoc() map[string]string { + return map_FixedIPs +} + +var map_NetworkParam = map[string]string{ + "uuid": "The UUID of the network. Required if you omit the port attribute.", + "fixedIp": "A fixed IPv4 address for the NIC.", + "filter": "Filters for optional network query", + "subnets": "Subnet within a network to use", + "noAllowedAddressPairs": "NoAllowedAddressPairs disables creation of allowed address pairs for the network ports", + "portTags": "PortTags allows users to specify a list of tags to add to ports created in a given network", + "vnicType": "The virtual network interface card (vNIC) type that is bound to the neutron port.", + "profile": "A dictionary that enables the application running on the specified host to pass and receive virtual network interface (VIF) port-specific information to the plug-in.", + "portSecurity": "PortSecurity optionally enables or disables security on ports managed by OpenStack", +} + +func (NetworkParam) SwaggerDoc() map[string]string { + return map_NetworkParam +} + +var map_OpenstackProviderSpec = map[string]string{ + "": "OpenstackProviderSpec is the type that will be embedded in a Machine.Spec.ProviderSpec field for an OpenStack Instance. It is used by the Openstack machine actuator to create a single machine instance. Compatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support.", + "metadata": "metadata is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "cloudsSecret": "The name of the secret containing the openstack credentials", + "cloudName": "The name of the cloud to use from the clouds secret", + "flavor": "The flavor reference for the flavor for your server instance.", + "image": "The name of the image to use for your server instance. If the RootVolume is specified, this will be ignored and use rootVolume directly.", + "keyName": "The ssh key to inject in the instance", + "sshUserName": "The machine ssh username", + "networks": "A networks object. Required parameter when there are multiple networks defined for the tenant. When you do not specify the networks parameter, the server attaches to the only network created for the current tenant.", + "ports": "Create and assign additional ports to instances", + "floatingIP": "floatingIP specifies a floating IP to be associated with the machine. Note that it is not safe to use this parameter in a MachineSet, as only one Machine may be assigned the same floating IP.\n\nDeprecated: floatingIP will be removed in a future release as it cannot be implemented correctly.", + "availabilityZone": "The availability zone from which to launch the server.", + "securityGroups": "The names of the security groups to assign to the instance", + "userDataSecret": "The name of the secret containing the user data (startup script in most cases)", + "trunk": "Whether the server instance is created on a trunk port or not.", + "tags": "Machine tags Requires Nova api 2.52 minimum!", + "serverMetadata": "Metadata mapping. Allows you to create a map of key value pairs to add to the server instance.", + "configDrive": "Config Drive support", + "rootVolume": "The volume metadata to boot from", + "serverGroupID": "The server group to assign the machine to.", + "serverGroupName": "The server group to assign the machine to. A server group with that name will be created if it does not exist. If both ServerGroupID and ServerGroupName are non-empty, they must refer to the same OpenStack resource.", + "primarySubnet": "The subnet that a set of machines will get ingress/egress traffic from", +} + +func (OpenstackProviderSpec) SwaggerDoc() map[string]string { + return map_OpenstackProviderSpec +} + +var map_PortOpts = map[string]string{ + "networkID": "networkID is the ID of the network the port will be created in. It is required.", + "nameSuffix": "If nameSuffix is specified the created port will be named -. If not specified the port will be named -.", + "description": "description specifies the description of the created port.", + "adminStateUp": "adminStateUp sets the administrative state of the created port to up (true), or down (false).", + "macAddress": "macAddress specifies the MAC address of the created port.", + "fixedIPs": "fixedIPs specifies a set of fixed IPs to assign to the port. They must all be valid for the port's network.", + "tenantID": "tenantID specifies the tenant ID of the created port. Note that this requires OpenShift to have administrative permissions, which is typically not the case. Use of this field is not recommended. Deprecated: use projectID instead. It will be ignored if projectID is set.", + "projectID": "projectID specifies the project ID of the created port. Note that this requires OpenShift to have administrative permissions, which is typically not the case. Use of this field is not recommended.", + "securityGroups": "securityGroups specifies a set of security group UUIDs to use instead of the machine's default security groups. The default security groups will be used if this is left empty or not specified.", + "allowedAddressPairs": "allowedAddressPairs specifies a set of allowed address pairs to add to the port.", + "tags": "tags species a set of tags to add to the port.", + "vnicType": "The virtual network interface card (vNIC) type that is bound to the neutron port.", + "profile": "A dictionary that enables the application running on the specified host to pass and receive virtual network interface (VIF) port-specific information to the plug-in.", + "portSecurity": "enable or disable security on a given port incompatible with securityGroups and allowedAddressPairs", + "trunk": "Enables and disables trunk at port level. If not provided, openStackMachine.Spec.Trunk is inherited.", + "hostID": "The ID of the host where the port is allocated. Do not use this field: it cannot be used correctly. Deprecated: hostID is silently ignored. It will be removed with no replacement.", +} + +func (PortOpts) SwaggerDoc() map[string]string { + return map_PortOpts +} + +var map_RootVolume = map[string]string{ + "sourceUUID": "sourceUUID specifies the UUID of a glance image used to populate the root volume. Deprecated: set image in the platform spec instead. This will be ignored if image is set in the platform spec.", + "volumeType": "volumeType specifies a volume type to use when creating the root volume. If not specified the default volume type will be used.", + "diskSize": "diskSize specifies the size, in GB, of the created root volume.", + "availabilityZone": "availabilityZone specifies the Cinder availability where the root volume will be created.", + "sourceType": "Deprecated: sourceType will be silently ignored. There is no replacement.", + "deviceType": "Deprecated: deviceType will be silently ignored. There is no replacement.", +} + +func (RootVolume) SwaggerDoc() map[string]string { + return map_RootVolume +} + +var map_SecurityGroupFilter = map[string]string{ + "id": "id specifies the ID of a security group to use. If set, id will not be validated before use. An invalid id will result in failure to create a server with an appropriate error message.", + "name": "name filters security groups by name.", + "description": "description filters security groups by description.", + "tenantId": "tenantId filters security groups by tenant ID. Deprecated: use projectId instead. tenantId will be ignored if projectId is set.", + "projectId": "projectId filters security groups by project ID.", + "tags": "tags filters by security groups containing all specified tags. Multiple tags are comma separated.", + "tagsAny": "tagsAny filters by security groups containing any specified tags. Multiple tags are comma separated.", + "notTags": "notTags filters by security groups which don't match all specified tags. NOT (t1 AND t2...) Multiple tags are comma separated.", + "notTagsAny": "notTagsAny filters by security groups which don't match any specified tags. NOT (t1 OR t2...) Multiple tags are comma separated.", + "limit": "Deprecated: limit is silently ignored. It has no replacement.", + "marker": "Deprecated: marker is silently ignored. It has no replacement.", + "sortKey": "Deprecated: sortKey is silently ignored. It has no replacement.", + "sortDir": "Deprecated: sortDir is silently ignored. It has no replacement.", +} + +func (SecurityGroupFilter) SwaggerDoc() map[string]string { + return map_SecurityGroupFilter +} + +var map_SecurityGroupParam = map[string]string{ + "uuid": "Security Group UUID", + "name": "Security Group name", + "filter": "Filters used to query security groups in openstack", +} + +func (SecurityGroupParam) SwaggerDoc() map[string]string { + return map_SecurityGroupParam +} + +var map_SubnetFilter = map[string]string{ + "id": "id is the uuid of a specific subnet to use. If specified, id will not be validated. Instead server creation will fail with an appropriate error.", + "name": "name filters subnets by name.", + "description": "description filters subnets by description.", + "networkId": "Deprecated: networkId is silently ignored. Set uuid on the containing network definition instead.", + "tenantId": "tenantId filters subnets by tenant ID. Deprecated: use projectId instead. tenantId will be ignored if projectId is set.", + "projectId": "projectId filters subnets by project ID.", + "ipVersion": "ipVersion filters subnets by IP version.", + "gateway_ip": "gateway_ip filters subnets by gateway IP.", + "cidr": "cidr filters subnets by CIDR.", + "ipv6AddressMode": "ipv6AddressMode filters subnets by IPv6 address mode.", + "ipv6RaMode": "ipv6RaMode filters subnets by IPv6 router adversiement mode.", + "subnetpoolId": "subnetpoolId filters subnets by subnet pool ID.", + "tags": "tags filters by subnets containing all specified tags. Multiple tags are comma separated.", + "tagsAny": "tagsAny filters by subnets containing any specified tags. Multiple tags are comma separated.", + "notTags": "notTags filters by subnets which don't match all specified tags. NOT (t1 AND t2...) Multiple tags are comma separated.", + "notTagsAny": "notTagsAny filters by subnets which don't match any specified tags. NOT (t1 OR t2...) Multiple tags are comma separated.", + "enableDhcp": "Deprecated: enableDhcp is silently ignored. It has no replacement.", + "limit": "Deprecated: limit is silently ignored. It has no replacement.", + "marker": "Deprecated: marker is silently ignored. It has no replacement.", + "sortKey": "Deprecated: sortKey is silently ignored. It has no replacement.", + "sortDir": "Deprecated: sortDir is silently ignored. It has no replacement.", +} + +func (SubnetFilter) SwaggerDoc() map[string]string { + return map_SubnetFilter +} + +var map_SubnetParam = map[string]string{ + "uuid": "The UUID of the network. Required if you omit the port attribute.", + "filter": "Filters for optional network query", + "portTags": "PortTags are tags that are added to ports created on this subnet", + "portSecurity": "PortSecurity optionally enables or disables security on ports managed by OpenStack", +} + +func (SubnetParam) SwaggerDoc() map[string]string { + return map_SubnetParam +} + +// AUTO-GENERATED FUNCTIONS END HERE diff --git a/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/Makefile b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/Makefile index 227f58817..9c4d7ac9c 100644 --- a/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/Makefile +++ b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/Makefile @@ -6,7 +6,7 @@ GOPROXY ?= export GOPROXY # ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. -ENVTEST_K8S_VERSION = 1.26 +ENVTEST_K8S_VERSION = 1.27 PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST)))) ENVTEST = go run ${PROJECT_DIR}/vendor/sigs.k8s.io/controller-runtime/tools/setup-envtest diff --git a/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/config/v1/infrastructure.go b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/config/v1/infrastructure.go index e073cef1d..07b229b64 100644 --- a/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/config/v1/infrastructure.go +++ b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/config/v1/infrastructure.go @@ -134,6 +134,33 @@ func (i InfrastructureBuilder) AsGCP(name string, region string) InfrastructureB return i } +// AsOpenStack sets the Status for the infrastructure builder. +func (i InfrastructureBuilder) AsOpenStack(name string) InfrastructureBuilder { + i.spec = &configv1.InfrastructureSpec{ + PlatformSpec: configv1.PlatformSpec{ + Type: configv1.OpenStackPlatformType, + OpenStack: &configv1.OpenStackPlatformSpec{}, + }, + } + i.status = &configv1.InfrastructureStatus{ + InfrastructureName: name, + APIServerURL: "https://api.test-cluster.test-domain:6443", + APIServerInternalURL: "https://api-int.test-cluster.test-domain:6443", + EtcdDiscoveryDomain: "", + ControlPlaneTopology: configv1.HighlyAvailableTopologyMode, + InfrastructureTopology: configv1.HighlyAvailableTopologyMode, + PlatformStatus: &configv1.PlatformStatus{ + Type: configv1.OpenStackPlatformType, + OpenStack: &configv1.OpenStackPlatformStatus{ + APIServerInternalIPs: []string{"10.0.0.5"}, + IngressIPs: []string{"10.0.0.7"}, + }, + }, + } + + return i +} + // WithGenerateName sets the generateName for the infrastructure builder. func (i InfrastructureBuilder) WithGenerateName(generateName string) InfrastructureBuilder { i.generateName = generateName diff --git a/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/machine/v1/openstack_failure_domains.go b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/machine/v1/openstack_failure_domains.go new file mode 100644 index 000000000..902bf13b3 --- /dev/null +++ b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/machine/v1/openstack_failure_domains.go @@ -0,0 +1,106 @@ +/* +Copyright 2023 Red Hat, Inc. + +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. +*/ + +// Linter warns about duplicated code with OpenStack, GCP, and OpenStack FailureDomains builders. +// While the builders are almost identical, we need to keep them separate because they build different objects. +// +//nolint:dupl +package v1 + +import ( + configv1 "github.com/openshift/api/config/v1" + machinev1 "github.com/openshift/api/machine/v1" +) + +// OpenStackFailureDomains creates a new failure domains builder for OpenStack. +func OpenStackFailureDomains() OpenStackFailureDomainsBuilder { + return OpenStackFailureDomainsBuilder{[]OpenStackFailureDomainBuilder{ + OpenStackFailureDomain().WithComputeAvailabilityZone("nova-az0"). + WithRootVolume(machinev1.RootVolume{ + AvailabilityZone: "cinder-az0", + }), + OpenStackFailureDomain().WithComputeAvailabilityZone("nova-az1"). + WithRootVolume(machinev1.RootVolume{ + AvailabilityZone: "cinder-az1", + }), + OpenStackFailureDomain().WithComputeAvailabilityZone("nova-az2"). + WithRootVolume(machinev1.RootVolume{ + AvailabilityZone: "cinder-az2", + }), + }} +} + +// OpenStackFailureDomainsBuilder is used to build a failuredomains. +type OpenStackFailureDomainsBuilder struct { + failureDomainsBuilders []OpenStackFailureDomainBuilder +} + +// BuildFailureDomains builds a failuredomains from the configuration. +func (a OpenStackFailureDomainsBuilder) BuildFailureDomains() machinev1.FailureDomains { + fds := machinev1.FailureDomains{ + Platform: configv1.OpenStackPlatformType, + OpenStack: []machinev1.OpenStackFailureDomain{}, + } + + for _, builder := range a.failureDomainsBuilders { + fds.OpenStack = append(fds.OpenStack, builder.Build()) + } + + return fds +} + +// WithFailureDomainBuilder adds a failure domain builder to the failure domains builder's builders. +func (a OpenStackFailureDomainsBuilder) WithFailureDomainBuilder(fdbuilder OpenStackFailureDomainBuilder) OpenStackFailureDomainsBuilder { + a.failureDomainsBuilders = append(a.failureDomainsBuilders, fdbuilder) + return a +} + +// WithFailureDomainBuilders replaces the failure domains builder's builders with the given builders. +func (a OpenStackFailureDomainsBuilder) WithFailureDomainBuilders(fdbuilders ...OpenStackFailureDomainBuilder) OpenStackFailureDomainsBuilder { + a.failureDomainsBuilders = fdbuilders + return a +} + +// OpenStackFailureDomain creates a new OpenStack failure domain builder for OpenStack. +func OpenStackFailureDomain() OpenStackFailureDomainBuilder { + return OpenStackFailureDomainBuilder{} +} + +// OpenStackFailureDomainBuilder is used to build an OpenStack failuredomain. +type OpenStackFailureDomainBuilder struct { + AvailabilityZone string + RootVolume *machinev1.RootVolume +} + +// Build builds a OpenStack failuredomain from the configuration. +func (a OpenStackFailureDomainBuilder) Build() machinev1.OpenStackFailureDomain { + return machinev1.OpenStackFailureDomain{ + AvailabilityZone: a.AvailabilityZone, + RootVolume: a.RootVolume, + } +} + +// WithComputeAvailabilityZone sets the nova availability zone for the OpenStack failuredomain builder. +func (a OpenStackFailureDomainBuilder) WithComputeAvailabilityZone(zone string) OpenStackFailureDomainBuilder { + a.AvailabilityZone = zone + return a +} + +// WithRootVolume sets the root volume for the OpenStack failuredomain builder. +func (a OpenStackFailureDomainBuilder) WithRootVolume(rootVolume machinev1.RootVolume) OpenStackFailureDomainBuilder { + a.RootVolume = &rootVolume + return a +} diff --git a/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/machine/v1beta1/machine.go b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/machine/v1beta1/machine.go index 9f3158b3b..22c50e390 100644 --- a/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/machine/v1beta1/machine.go +++ b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/machine/v1beta1/machine.go @@ -35,6 +35,7 @@ type MachineBuilder struct { namespace string labels map[string]string creationTimestamp metav1.Time + deletionTimestamp *metav1.Time providerSpecBuilder resourcebuilder.RawExtensionBuilder // status fields @@ -49,6 +50,7 @@ func (m MachineBuilder) Build() *machinev1beta1.Machine { ObjectMeta: metav1.ObjectMeta{ GenerateName: m.generateName, CreationTimestamp: m.creationTimestamp, + DeletionTimestamp: m.deletionTimestamp, Name: m.name, Namespace: m.namespace, Labels: m.labels, @@ -89,6 +91,14 @@ func (m MachineBuilder) WithCreationTimestamp(time metav1.Time) MachineBuilder { return m } +// WithDeletionTimestamp sets the deletionTimestamp for the machine builder. +// Note: This can only be used in unit testing as the API server will drop this +// field if a create/update request tries to set it. +func (m MachineBuilder) WithDeletionTimestamp(time *metav1.Time) MachineBuilder { + m.deletionTimestamp = time + return m +} + // WithGenerateName sets the generateName for the machine builder. func (m MachineBuilder) WithGenerateName(generateName string) MachineBuilder { m.generateName = generateName diff --git a/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/machine/v1beta1/openstack_provider_spec.go b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/machine/v1beta1/openstack_provider_spec.go new file mode 100644 index 000000000..add435810 --- /dev/null +++ b/vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/machine/v1beta1/openstack_provider_spec.go @@ -0,0 +1,134 @@ +/* +Copyright 2022 Red Hat, Inc. + +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 v1beta1 + +import ( + "encoding/json" + + machinev1alpha1 "github.com/openshift/api/machine/v1alpha1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// OpenStackProviderSpec creates a new OpenStack machine config builder. +func OpenStackProviderSpec() OpenStackProviderSpecBuilder { + return OpenStackProviderSpecBuilder{ + flavor: "m1.large", + availabilityZone: "", + rootVolume: &machinev1alpha1.RootVolume{}, + serverGroupName: "master", + } +} + +// OpenStackProviderSpecBuilder is used to build a OpenStack machine config object. +type OpenStackProviderSpecBuilder struct { + flavor string + availabilityZone string + rootVolume *machinev1alpha1.RootVolume + serverGroupName string +} + +// Build builds a new OpenStack machine config based on the configuration provided. +func (m OpenStackProviderSpecBuilder) Build() *machinev1alpha1.OpenstackProviderSpec { + return &machinev1alpha1.OpenstackProviderSpec{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "machine.openshift.io/v1alpha1", + Kind: "OpenstackProviderSpec", + }, + AvailabilityZone: m.availabilityZone, + CloudsSecret: &v1.SecretReference{ + Name: "openstack-cloud-credentials", + Namespace: "openshift-machine-api", + }, + CloudName: "openstack", + Flavor: m.flavor, + Image: "rhcos", + Networks: []machinev1alpha1.NetworkParam{ + { + Subnets: []machinev1alpha1.SubnetParam{ + { + Filter: machinev1alpha1.SubnetFilter{ + ID: "810c3d97-98c2-4cf3-b0f6-8977b6e0b4b2", + }, + }, + }, + UUID: "d06af90b-1677-4b35-a7fb-3ae023dc8f62", + }, + }, + PrimarySubnet: "810c3d97-98c2-4cf3-b0f6-8977b6e0b4b2", + SecurityGroups: []machinev1alpha1.SecurityGroupParam{ + { + Filter: machinev1alpha1.SecurityGroupFilter{ + Name: "test-cluster-worker", + }, + }, + }, + ServerGroupName: m.serverGroupName, + ServerMetadata: map[string]string{ + "Name": "test-cluster-worker", + "openshiftClusterID": "test-cluster", + }, + Tags: []string{ + "openshiftClusterID=test-cluster", + }, + Trunk: true, + UserDataSecret: &v1.SecretReference{ + Name: "worker-user-data", + }, + RootVolume: m.rootVolume, + } +} + +// BuildRawExtension builds a new OpenStack machine config based on the configuration provided. +func (m OpenStackProviderSpecBuilder) BuildRawExtension() *runtime.RawExtension { + providerConfig := m.Build() + + raw, err := json.Marshal(providerConfig) + if err != nil { + // As we are building the input to json.Marshal, this should never happen. + panic(err) + } + + return &runtime.RawExtension{ + Raw: raw, + } +} + +// WithZone sets the availabilityZone for the OpenStack machine config builder. +func (m OpenStackProviderSpecBuilder) WithZone(az string) OpenStackProviderSpecBuilder { + m.availabilityZone = az + return m +} + +// WithRootVolume sets the rootVolume for the OpenStack machine config builder. +func (m OpenStackProviderSpecBuilder) WithRootVolume(rootVolume *machinev1alpha1.RootVolume) OpenStackProviderSpecBuilder { + m.rootVolume = rootVolume + return m +} + +// WithFlavor sets the flavor for the OpenStack machine config builder. +func (m OpenStackProviderSpecBuilder) WithFlavor(flavor string) OpenStackProviderSpecBuilder { + m.flavor = flavor + return m +} + +// WithServerGroupName sets the server group name for the OpenStack machine config builder. +func (m OpenStackProviderSpecBuilder) WithServerGroupName(name string) OpenStackProviderSpecBuilder { + m.serverGroupName = name + return m +} diff --git a/vendor/k8s.io/klog/v2/format.go b/vendor/k8s.io/klog/v2/format.go new file mode 100644 index 000000000..63995ca6d --- /dev/null +++ b/vendor/k8s.io/klog/v2/format.go @@ -0,0 +1,65 @@ +/* +Copyright 2023 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 klog + +import ( + "encoding/json" + "fmt" + "strings" + + "github.com/go-logr/logr" +) + +// Format wraps a value of an arbitrary type and implement fmt.Stringer and +// logr.Marshaler for them. Stringer returns pretty-printed JSON. MarshalLog +// returns the original value with a type that has no special methods, in +// particular no MarshalLog or MarshalJSON. +// +// Wrapping values like that is useful when the value has a broken +// implementation of these special functions (for example, a type which +// inherits String from TypeMeta, but then doesn't re-implement String) or the +// implementation produces output that is less readable or unstructured (for +// example, the generated String functions for Kubernetes API types). +func Format(obj interface{}) interface{} { + return formatAny{Object: obj} +} + +type formatAny struct { + Object interface{} +} + +func (f formatAny) String() string { + var buffer strings.Builder + encoder := json.NewEncoder(&buffer) + encoder.SetIndent("", " ") + if err := encoder.Encode(&f.Object); err != nil { + return fmt.Sprintf("error marshaling %T to JSON: %v", f, err) + } + return buffer.String() +} + +func (f formatAny) MarshalLog() interface{} { + // Returning a pointer to a pointer ensures that zapr doesn't find a + // fmt.Stringer or logr.Marshaler when it checks the type of the + // value. It then falls back to reflection, which dumps the value being + // pointed to (JSON doesn't have pointers). + ptr := &f.Object + return &ptr +} + +var _ fmt.Stringer = formatAny{} +var _ logr.Marshaler = formatAny{} diff --git a/vendor/k8s.io/klog/v2/internal/serialize/keyvalues.go b/vendor/k8s.io/klog/v2/internal/serialize/keyvalues.go index 1dc81a15f..bcdf5f8ee 100644 --- a/vendor/k8s.io/klog/v2/internal/serialize/keyvalues.go +++ b/vendor/k8s.io/klog/v2/internal/serialize/keyvalues.go @@ -18,6 +18,7 @@ package serialize import ( "bytes" + "encoding/json" "fmt" "strconv" @@ -196,11 +197,11 @@ func (f Formatter) KVFormat(b *bytes.Buffer, k, v interface{}) { case textWriter: writeTextWriterValue(b, v) case fmt.Stringer: - writeStringValue(b, true, StringerToString(v)) + writeStringValue(b, StringerToString(v)) case string: - writeStringValue(b, true, v) + writeStringValue(b, v) case error: - writeStringValue(b, true, ErrorToString(v)) + writeStringValue(b, ErrorToString(v)) case logr.Marshaler: value := MarshalerToValue(v) // A marshaler that returns a string is useful for @@ -215,9 +216,9 @@ func (f Formatter) KVFormat(b *bytes.Buffer, k, v interface{}) { // value directly. switch value := value.(type) { case string: - writeStringValue(b, true, value) + writeStringValue(b, value) default: - writeStringValue(b, false, f.AnyToString(value)) + f.formatAny(b, value) } case []byte: // In https://github.com/kubernetes/klog/pull/237 it was decided @@ -234,7 +235,7 @@ func (f Formatter) KVFormat(b *bytes.Buffer, k, v interface{}) { b.WriteByte('=') b.WriteString(fmt.Sprintf("%+q", v)) default: - writeStringValue(b, false, f.AnyToString(v)) + f.formatAny(b, v) } } @@ -242,12 +243,25 @@ func KVFormat(b *bytes.Buffer, k, v interface{}) { Formatter{}.KVFormat(b, k, v) } -// AnyToString is the historic fallback formatter. -func (f Formatter) AnyToString(v interface{}) string { +// formatAny is the fallback formatter for a value. It supports a hook (for +// example, for YAML encoding) and itself uses JSON encoding. +func (f Formatter) formatAny(b *bytes.Buffer, v interface{}) { + b.WriteRune('=') if f.AnyToStringHook != nil { - return f.AnyToStringHook(v) + b.WriteString(f.AnyToStringHook(v)) + return + } + encoder := json.NewEncoder(b) + l := b.Len() + if err := encoder.Encode(v); err != nil { + // This shouldn't happen. We discard whatever the encoder + // wrote and instead dump an error string. + b.Truncate(l) + b.WriteString(fmt.Sprintf(`""`, err)) + return } - return fmt.Sprintf("%+v", v) + // Remove trailing newline. + b.Truncate(b.Len() - 1) } // StringerToString converts a Stringer to a string, @@ -287,7 +301,7 @@ func ErrorToString(err error) (ret string) { } func writeTextWriterValue(b *bytes.Buffer, v textWriter) { - b.WriteRune('=') + b.WriteByte('=') defer func() { if err := recover(); err != nil { fmt.Fprintf(b, `""`, err) @@ -296,18 +310,13 @@ func writeTextWriterValue(b *bytes.Buffer, v textWriter) { v.WriteText(b) } -func writeStringValue(b *bytes.Buffer, quote bool, v string) { +func writeStringValue(b *bytes.Buffer, v string) { data := []byte(v) index := bytes.IndexByte(data, '\n') if index == -1 { b.WriteByte('=') - if quote { - // Simple string, quote quotation marks and non-printable characters. - b.WriteString(strconv.Quote(v)) - return - } - // Non-string with no line breaks. - b.WriteString(v) + // Simple string, quote quotation marks and non-printable characters. + b.WriteString(strconv.Quote(v)) return } diff --git a/vendor/k8s.io/klog/v2/k8s_references.go b/vendor/k8s.io/klog/v2/k8s_references.go index ecd3f8b69..786af74bf 100644 --- a/vendor/k8s.io/klog/v2/k8s_references.go +++ b/vendor/k8s.io/klog/v2/k8s_references.go @@ -178,14 +178,14 @@ func (ks kobjSlice) process() (objs []interface{}, err string) { return objectRefs, "" } -var nilToken = []byte("") +var nilToken = []byte("null") func (ks kobjSlice) WriteText(out *bytes.Buffer) { s := reflect.ValueOf(ks.arg) switch s.Kind() { case reflect.Invalid: - // nil parameter, print as empty slice. - out.WriteString("[]") + // nil parameter, print as null. + out.Write(nilToken) return case reflect.Slice: // Okay, handle below. @@ -197,15 +197,15 @@ func (ks kobjSlice) WriteText(out *bytes.Buffer) { defer out.Write([]byte{']'}) for i := 0; i < s.Len(); i++ { if i > 0 { - out.Write([]byte{' '}) + out.Write([]byte{','}) } item := s.Index(i).Interface() if item == nil { out.Write(nilToken) } else if v, ok := item.(KMetadata); ok { - KObj(v).writeUnquoted(out) + KObj(v).WriteText(out) } else { - fmt.Fprintf(out, "", item) + fmt.Fprintf(out, `""`, item) return } } diff --git a/vendor/k8s.io/klog/v2/klog.go b/vendor/k8s.io/klog/v2/klog.go index 466eeaf26..152f8a6bd 100644 --- a/vendor/k8s.io/klog/v2/klog.go +++ b/vendor/k8s.io/klog/v2/klog.go @@ -1228,6 +1228,19 @@ func CopyStandardLogTo(name string) { stdLog.SetOutput(logBridge(sev)) } +// NewStandardLogger returns a Logger that writes to the klog logs for the +// named and lower severities. +// +// Valid names are "INFO", "WARNING", "ERROR", and "FATAL". If the name is not +// recognized, NewStandardLogger panics. +func NewStandardLogger(name string) *stdLog.Logger { + sev, ok := severity.ByName(name) + if !ok { + panic(fmt.Sprintf("klog.NewStandardLogger(%q): unknown severity", name)) + } + return stdLog.New(logBridge(sev), "", stdLog.Lshortfile) +} + // logBridge provides the Write method that enables CopyStandardLogTo to connect // Go's standard logs to the logs provided by this package. type logBridge severity.Severity diff --git a/vendor/modules.txt b/vendor/modules.txt index 32963471a..b727c764a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -531,6 +531,7 @@ github.com/onsi/gomega/types github.com/openshift/api/config/v1 github.com/openshift/api/config/v1alpha1 github.com/openshift/api/machine/v1 +github.com/openshift/api/machine/v1alpha1 github.com/openshift/api/machine/v1beta1 # github.com/openshift/client-go v0.0.0-20230503144108-75015d2347cb ## explicit; go 1.20 @@ -541,7 +542,7 @@ github.com/openshift/client-go/config/clientset/versioned/typed/config/v1 github.com/openshift/client-go/machine/applyconfigurations/internal github.com/openshift/client-go/machine/applyconfigurations/machine/v1 github.com/openshift/client-go/machine/applyconfigurations/machine/v1beta1 -# github.com/openshift/cluster-api-actuator-pkg/testutils v0.0.0-20230428103603-98e6d5c4def7 +# github.com/openshift/cluster-api-actuator-pkg/testutils v0.0.0-20230622171654-75c6bcfa831c ## explicit; go 1.19 github.com/openshift/cluster-api-actuator-pkg/testutils github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder @@ -1265,7 +1266,7 @@ k8s.io/client-go/util/workqueue k8s.io/component-base/config k8s.io/component-base/config/options k8s.io/component-base/config/v1alpha1 -# k8s.io/klog/v2 v2.90.1 +# k8s.io/klog/v2 v2.100.1 ## explicit; go 1.13 k8s.io/klog/v2 k8s.io/klog/v2/internal/buffer From 101d475463ae267124f4c394bd22ca16ce5998f3 Mon Sep 17 00:00:00 2001 From: Joel Speed Date: Tue, 20 Jun 2023 18:25:22 +0100 Subject: [PATCH 2/3] Ensure mapping and machines are cached together --- .../controlplanemachineset/updates.go | 5 +- .../controlplanemachineset/updates_test.go | 36 +-- .../zz_generated_machine_provider_mock.go | 11 +- .../openshift/machine/v1beta1/mapping.go | 39 +--- .../openshift/machine/v1beta1/mapping_test.go | 217 ++++++++---------- .../openshift/machine/v1beta1/provider.go | 97 +++++--- .../machine/v1beta1/provider_test.go | 84 ++----- pkg/machineproviders/types.go | 2 +- 8 files changed, 222 insertions(+), 269 deletions(-) diff --git a/pkg/controllers/controlplanemachineset/updates.go b/pkg/controllers/controlplanemachineset/updates.go index 241e32193..1dacc19c6 100644 --- a/pkg/controllers/controlplanemachineset/updates.go +++ b/pkg/controllers/controlplanemachineset/updates.go @@ -560,7 +560,10 @@ func (r *ControlPlaneMachineSetReconciler) createMachineWithSurge(ctx context.Co // already has an existing, up to date, replacement machine. func (r *ControlPlaneMachineSetReconciler) checkForExistingReplacement(ctx context.Context, logger logr.Logger, machineProvider machineproviders.MachineProvider, idx int32) (bool, error) { // Define an uncached machine provider. - uncachedMachineProvider := machineProvider.WithClient(r.UncachedClient) + uncachedMachineProvider, err := machineProvider.WithClient(ctx, logger, r.UncachedClient) + if err != nil { + return false, fmt.Errorf("could not get uncached machine provider: %w", err) + } mInfos, err := uncachedMachineProvider.GetMachineInfos(ctx, logger) if err != nil { diff --git a/pkg/controllers/controlplanemachineset/updates_test.go b/pkg/controllers/controlplanemachineset/updates_test.go index 33e7c739e..f38e70a07 100644 --- a/pkg/controllers/controlplanemachineset/updates_test.go +++ b/pkg/controllers/controlplanemachineset/updates_test.go @@ -162,7 +162,7 @@ var _ = Describe("reconcileMachineUpdates", func() { 2: {updatedMachineBuilder.WithIndex(2).WithMachineName("machine-2").WithNodeName("node-2").Build()}, }, setupMock: func(machineInfos map[int32][]machineproviders.MachineInfo) { - mockMachineProvider.EXPECT().WithClient(gomock.Any()).Return(mockMachineProvider).AnyTimes() + mockMachineProvider.EXPECT().WithClient(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockMachineProvider, nil).AnyTimes() mockMachineProvider.EXPECT().GetMachineInfos(gomock.Any(), gomock.Any()).Return(machineInfosMaptoSlice(machineInfos), nil).AnyTimes() mockMachineProvider.EXPECT().CreateMachine(gomock.Any(), gomock.Any(), int32(1)).Return(nil).Times(1) mockMachineProvider.EXPECT().DeleteMachine(gomock.Any(), gomock.Any(), gomock.Any()).Times(0) @@ -201,7 +201,7 @@ var _ = Describe("reconcileMachineUpdates", func() { 2: {updatedMachineBuilder.WithIndex(2).WithMachineName("machine-2").WithNodeName("node-2").Build()}, }, setupMock: func(machineInfos map[int32][]machineproviders.MachineInfo) { - mockMachineProvider.EXPECT().WithClient(gomock.Any()).Return(mockMachineProvider).AnyTimes() + mockMachineProvider.EXPECT().WithClient(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockMachineProvider, nil).AnyTimes() mockMachineProvider.EXPECT().GetMachineInfos(gomock.Any(), gomock.Any()).Return(machineInfosMaptoSlice( func(mI map[int32][]machineproviders.MachineInfo) map[int32][]machineproviders.MachineInfo { mICopy := make(map[int32][]machineproviders.MachineInfo) @@ -241,7 +241,7 @@ var _ = Describe("reconcileMachineUpdates", func() { 2: {updatedMachineBuilder.WithIndex(2).WithMachineName("machine-2").WithNodeName("node-2").Build()}, }, setupMock: func(machineInfos map[int32][]machineproviders.MachineInfo) { - mockMachineProvider.EXPECT().WithClient(gomock.Any()).Return(mockMachineProvider).AnyTimes() + mockMachineProvider.EXPECT().WithClient(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockMachineProvider, nil).AnyTimes() mockMachineProvider.EXPECT().GetMachineInfos(gomock.Any(), gomock.Any()).Return(machineInfosMaptoSlice(machineInfos), nil).AnyTimes() mockMachineProvider.EXPECT().CreateMachine(gomock.Any(), gomock.Any(), int32(1)).Return(transientError).Times(1) mockMachineProvider.EXPECT().DeleteMachine(gomock.Any(), gomock.Any(), gomock.Any()).Times(0) @@ -410,7 +410,7 @@ var _ = Describe("reconcileMachineUpdates", func() { }, setupMock: func(machineInfos map[int32][]machineproviders.MachineInfo) { // Note, in this case it should only create a single machine. - mockMachineProvider.EXPECT().WithClient(gomock.Any()).Return(mockMachineProvider).AnyTimes() + mockMachineProvider.EXPECT().WithClient(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockMachineProvider, nil).AnyTimes() mockMachineProvider.EXPECT().GetMachineInfos(gomock.Any(), gomock.Any()).Return(machineInfosMaptoSlice(machineInfos), nil).AnyTimes() mockMachineProvider.EXPECT().CreateMachine(gomock.Any(), gomock.Any(), int32(0)).Return(nil).Times(1) mockMachineProvider.EXPECT().DeleteMachine(gomock.Any(), gomock.Any(), gomock.Any()).Times(0) @@ -633,7 +633,7 @@ var _ = Describe("reconcileMachineUpdates", func() { 2: {}, }, setupMock: func(machineInfos map[int32][]machineproviders.MachineInfo) { - mockMachineProvider.EXPECT().WithClient(gomock.Any()).Return(mockMachineProvider).AnyTimes() + mockMachineProvider.EXPECT().WithClient(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockMachineProvider, nil).AnyTimes() mockMachineProvider.EXPECT().GetMachineInfos(gomock.Any(), gomock.Any()).Return(machineInfosMaptoSlice(machineInfos), nil).AnyTimes() mockMachineProvider.EXPECT().CreateMachine(gomock.Any(), gomock.Any(), int32(2)).Return(nil).Times(1) mockMachineProvider.EXPECT().DeleteMachine(gomock.Any(), gomock.Any(), gomock.Any()).Times(0) @@ -688,7 +688,7 @@ var _ = Describe("reconcileMachineUpdates", func() { 2: {}, }, setupMock: func(machineInfos map[int32][]machineproviders.MachineInfo) { - mockMachineProvider.EXPECT().WithClient(gomock.Any()).Return(mockMachineProvider).AnyTimes() + mockMachineProvider.EXPECT().WithClient(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockMachineProvider, nil).AnyTimes() mockMachineProvider.EXPECT().GetMachineInfos(gomock.Any(), gomock.Any()).Return(machineInfosMaptoSlice(machineInfos), nil).AnyTimes() // The missing index should take priority over the index in need of an update. mockMachineProvider.EXPECT().CreateMachine(gomock.Any(), gomock.Any(), int32(1)).Return(nil).Times(1) @@ -741,7 +741,7 @@ var _ = Describe("reconcileMachineUpdates", func() { 2: {pendingMachineBuilder.WithIndex(2).WithMachineName("machine-replacement-2").Build()}, }, setupMock: func(machineInfos map[int32][]machineproviders.MachineInfo) { - mockMachineProvider.EXPECT().WithClient(gomock.Any()).Return(mockMachineProvider).AnyTimes() + mockMachineProvider.EXPECT().WithClient(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockMachineProvider, nil).AnyTimes() mockMachineProvider.EXPECT().GetMachineInfos(gomock.Any(), gomock.Any()).Return(machineInfosMaptoSlice(machineInfos), nil).AnyTimes() mockMachineProvider.EXPECT().CreateMachine(gomock.Any(), gomock.Any(), gomock.Any()).Times(1) mockMachineProvider.EXPECT().DeleteMachine(gomock.Any(), gomock.Any(), gomock.Any()).Times(0) @@ -1209,7 +1209,7 @@ var _ = Describe("reconcileMachineUpdates", func() { 2: {updatedMachineBuilder.WithIndex(2).WithMachineName("machine-2").WithNodeName("node-2").Build()}, }, setupMock: func(machineInfos map[int32][]machineproviders.MachineInfo) { - mockMachineProvider.EXPECT().WithClient(gomock.Any()).Return(mockMachineProvider).AnyTimes() + mockMachineProvider.EXPECT().WithClient(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockMachineProvider, nil).AnyTimes() mockMachineProvider.EXPECT().GetMachineInfos(gomock.Any(), gomock.Any()).Return(machineInfosMaptoSlice(machineInfos), nil).AnyTimes() mockMachineProvider.EXPECT().CreateMachine(gomock.Any(), gomock.Any(), int32(1)).Times(1) mockMachineProvider.EXPECT().DeleteMachine(gomock.Any(), gomock.Any(), gomock.Any()).Times(0) @@ -1389,7 +1389,7 @@ var _ = Describe("reconcileMachineUpdates", func() { 2: {updatedMachineBuilder.WithIndex(2).WithMachineName("machine-2").WithNodeName("node-2").Build()}, }, setupMock: func(machineInfos map[int32][]machineproviders.MachineInfo) { - mockMachineProvider.EXPECT().WithClient(gomock.Any()).Return(mockMachineProvider).AnyTimes() + mockMachineProvider.EXPECT().WithClient(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockMachineProvider, nil).AnyTimes() mockMachineProvider.EXPECT().GetMachineInfos(gomock.Any(), gomock.Any()).Return(machineInfosMaptoSlice( func(mI map[int32][]machineproviders.MachineInfo) map[int32][]machineproviders.MachineInfo { mICopy := make(map[int32][]machineproviders.MachineInfo) @@ -1430,7 +1430,7 @@ var _ = Describe("reconcileMachineUpdates", func() { 2: {updatedMachineBuilder.WithIndex(2).WithMachineName("machine-2").WithNodeName("node-2").Build()}, }, setupMock: func(machineInfos map[int32][]machineproviders.MachineInfo) { - mockMachineProvider.EXPECT().WithClient(gomock.Any()).Return(mockMachineProvider).AnyTimes() + mockMachineProvider.EXPECT().WithClient(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockMachineProvider, nil).AnyTimes() mockMachineProvider.EXPECT().GetMachineInfos(gomock.Any(), gomock.Any()).Return(machineInfosMaptoSlice(machineInfos), nil).AnyTimes() mockMachineProvider.EXPECT().CreateMachine(gomock.Any(), gomock.Any(), int32(1)).Return(nil).Times(1) mockMachineProvider.EXPECT().DeleteMachine(gomock.Any(), gomock.Any(), gomock.Any()).Times(0) @@ -1460,7 +1460,7 @@ var _ = Describe("reconcileMachineUpdates", func() { 5: {updatedMachineBuilder.WithIndex(5).WithMachineName("machine-5").WithNodeName("node-5").Build()}, }, setupMock: func(machineInfos map[int32][]machineproviders.MachineInfo) { - mockMachineProvider.EXPECT().WithClient(gomock.Any()).Return(mockMachineProvider).AnyTimes() + mockMachineProvider.EXPECT().WithClient(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockMachineProvider, nil).AnyTimes() mockMachineProvider.EXPECT().GetMachineInfos(gomock.Any(), gomock.Any()).Return(machineInfosMaptoSlice(machineInfos), nil).AnyTimes() mockMachineProvider.EXPECT().CreateMachine(gomock.Any(), gomock.Any(), int32(4)).Return(nil).Times(1) mockMachineProvider.EXPECT().DeleteMachine(gomock.Any(), gomock.Any(), gomock.Any()).Times(0) @@ -1490,7 +1490,7 @@ var _ = Describe("reconcileMachineUpdates", func() { 2: {updatedMachineBuilder.WithIndex(2).WithMachineName("machine-2").WithNodeName("node-2").Build()}, }, setupMock: func(machineInfos map[int32][]machineproviders.MachineInfo) { - mockMachineProvider.EXPECT().WithClient(gomock.Any()).Return(mockMachineProvider).AnyTimes() + mockMachineProvider.EXPECT().WithClient(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockMachineProvider, nil).AnyTimes() mockMachineProvider.EXPECT().GetMachineInfos(gomock.Any(), gomock.Any()).Return(machineInfosMaptoSlice(machineInfos), nil).AnyTimes() mockMachineProvider.EXPECT().CreateMachine(gomock.Any(), gomock.Any(), int32(1)).Return(transientError).Times(1) mockMachineProvider.EXPECT().DeleteMachine(gomock.Any(), gomock.Any(), gomock.Any()).Times(0) @@ -1624,7 +1624,7 @@ var _ = Describe("reconcileMachineUpdates", func() { 2: {updatedMachineBuilder.WithIndex(2).WithMachineName("machine-2").WithNodeName("node-2").Build()}, }, setupMock: func(machineInfos map[int32][]machineproviders.MachineInfo) { - mockMachineProvider.EXPECT().WithClient(gomock.Any()).Return(mockMachineProvider).AnyTimes() + mockMachineProvider.EXPECT().WithClient(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockMachineProvider, nil).AnyTimes() mockMachineProvider.EXPECT().GetMachineInfos(gomock.Any(), gomock.Any()).Return(machineInfosMaptoSlice(machineInfos), nil).AnyTimes() mockMachineProvider.EXPECT().CreateMachine(gomock.Any(), gomock.Any(), int32(1)).Return(transientError).Times(1) mockMachineProvider.EXPECT().DeleteMachine(gomock.Any(), gomock.Any(), gomock.Any()).Times(0) @@ -1666,7 +1666,7 @@ var _ = Describe("reconcileMachineUpdates", func() { 2: {updatedMachineBuilder.WithIndex(2).WithMachineName("machine-2").WithNodeName("node-2").Build()}, }, setupMock: func(machineInfos map[int32][]machineproviders.MachineInfo) { - mockMachineProvider.EXPECT().WithClient(gomock.Any()).Return(mockMachineProvider).AnyTimes() + mockMachineProvider.EXPECT().WithClient(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockMachineProvider, nil).AnyTimes() mockMachineProvider.EXPECT().GetMachineInfos(gomock.Any(), gomock.Any()).Return(machineInfosMaptoSlice(machineInfos), nil).AnyTimes() mockMachineProvider.EXPECT().CreateMachine(gomock.Any(), gomock.Any(), int32(1)).Return(nil).Times(1) mockMachineProvider.EXPECT().DeleteMachine(gomock.Any(), gomock.Any(), gomock.Any()).Times(0) @@ -1710,7 +1710,7 @@ var _ = Describe("reconcileMachineUpdates", func() { 2: {updatedMachineBuilder.WithIndex(2).WithMachineName("machine-2").WithNodeName("node-2").Build()}, }, setupMock: func(machineInfos map[int32][]machineproviders.MachineInfo) { - mockMachineProvider.EXPECT().WithClient(gomock.Any()).Return(mockMachineProvider).AnyTimes() + mockMachineProvider.EXPECT().WithClient(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockMachineProvider, nil).AnyTimes() mockMachineProvider.EXPECT().GetMachineInfos(gomock.Any(), gomock.Any()).Return(machineInfosMaptoSlice(machineInfos), nil).AnyTimes() mockMachineProvider.EXPECT().CreateMachine(gomock.Any(), gomock.Any(), int32(0)).Return(nil).Times(1) mockMachineProvider.EXPECT().CreateMachine(gomock.Any(), gomock.Any(), int32(1)).Return(nil).Times(1) @@ -1960,7 +1960,7 @@ var _ = Describe("reconcileMachineUpdates", func() { 2: {}, }, setupMock: func(machineInfos map[int32][]machineproviders.MachineInfo) { - mockMachineProvider.EXPECT().WithClient(gomock.Any()).Return(mockMachineProvider).AnyTimes() + mockMachineProvider.EXPECT().WithClient(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockMachineProvider, nil).AnyTimes() mockMachineProvider.EXPECT().GetMachineInfos(gomock.Any(), gomock.Any()).Return(machineInfosMaptoSlice(machineInfos), nil).AnyTimes() mockMachineProvider.EXPECT().CreateMachine(gomock.Any(), gomock.Any(), int32(2)).Return(nil).Times(1) mockMachineProvider.EXPECT().DeleteMachine(gomock.Any(), gomock.Any(), gomock.Any()).Times(0) @@ -2015,7 +2015,7 @@ var _ = Describe("reconcileMachineUpdates", func() { 2: {}, }, setupMock: func(machineInfos map[int32][]machineproviders.MachineInfo) { - mockMachineProvider.EXPECT().WithClient(gomock.Any()).Return(mockMachineProvider).AnyTimes() + mockMachineProvider.EXPECT().WithClient(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockMachineProvider, nil).AnyTimes() mockMachineProvider.EXPECT().GetMachineInfos(gomock.Any(), gomock.Any()).Return(machineInfosMaptoSlice(machineInfos), nil).AnyTimes() mockMachineProvider.EXPECT().CreateMachine(gomock.Any(), gomock.Any(), int32(2)).Return(nil).Times(1) mockMachineProvider.EXPECT().DeleteMachine(gomock.Any(), gomock.Any(), gomock.Any()).Times(0) @@ -2092,7 +2092,7 @@ var _ = Describe("reconcileMachineUpdates", func() { 2: {updatedMachineBuilder.WithIndex(2).WithMachineName("machine-2").WithNodeName("node-2").WithMachineDeletionTimestamp(metav1.Now()).Build()}, }, setupMock: func(machineInfos map[int32][]machineproviders.MachineInfo) { - mockMachineProvider.EXPECT().WithClient(gomock.Any()).Return(mockMachineProvider).AnyTimes() + mockMachineProvider.EXPECT().WithClient(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockMachineProvider, nil).AnyTimes() mockMachineProvider.EXPECT().GetMachineInfos(gomock.Any(), gomock.Any()).Return(machineInfosMaptoSlice(machineInfos), nil).AnyTimes() mockMachineProvider.EXPECT().CreateMachine(gomock.Any(), gomock.Any(), int32(2)).Times(1) mockMachineProvider.EXPECT().DeleteMachine(gomock.Any(), gomock.Any(), gomock.Any()).Times(0) diff --git a/pkg/machineproviders/mock/zz_generated_machine_provider_mock.go b/pkg/machineproviders/mock/zz_generated_machine_provider_mock.go index 6287b7217..d11a5e854 100644 --- a/pkg/machineproviders/mock/zz_generated_machine_provider_mock.go +++ b/pkg/machineproviders/mock/zz_generated_machine_provider_mock.go @@ -81,15 +81,16 @@ func (mr *MockMachineProviderMockRecorder) GetMachineInfos(arg0, arg1 interface{ } // WithClient mocks base method. -func (m *MockMachineProvider) WithClient(arg0 client.Client) machineproviders.MachineProvider { +func (m *MockMachineProvider) WithClient(arg0 context.Context, arg1 logr.Logger, arg2 client.Client) (machineproviders.MachineProvider, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "WithClient", arg0) + ret := m.ctrl.Call(m, "WithClient", arg0, arg1, arg2) ret0, _ := ret[0].(machineproviders.MachineProvider) - return ret0 + ret1, _ := ret[1].(error) + return ret0, ret1 } // WithClient indicates an expected call of WithClient. -func (mr *MockMachineProviderMockRecorder) WithClient(arg0 interface{}) *gomock.Call { +func (mr *MockMachineProviderMockRecorder) WithClient(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WithClient", reflect.TypeOf((*MockMachineProvider)(nil).WithClient), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WithClient", reflect.TypeOf((*MockMachineProvider)(nil).WithClient), arg0, arg1, arg2) } diff --git a/pkg/machineproviders/providers/openshift/machine/v1beta1/mapping.go b/pkg/machineproviders/providers/openshift/machine/v1beta1/mapping.go index ce4f7fad5..8833286bd 100644 --- a/pkg/machineproviders/providers/openshift/machine/v1beta1/mapping.go +++ b/pkg/machineproviders/providers/openshift/machine/v1beta1/mapping.go @@ -17,7 +17,6 @@ limitations under the License. package v1beta1 import ( - "context" "errors" "fmt" "math" @@ -26,15 +25,11 @@ import ( "strings" "github.com/go-logr/logr" - machinev1 "github.com/openshift/api/machine/v1" machinev1beta1 "github.com/openshift/api/machine/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/sets" "github.com/openshift/cluster-control-plane-machine-set-operator/pkg/machineproviders/providers/openshift/machine/v1beta1/failuredomain" "github.com/openshift/cluster-control-plane-machine-set-operator/pkg/machineproviders/providers/openshift/machine/v1beta1/providerconfig" - - "sigs.k8s.io/controller-runtime/pkg/client" ) var ( @@ -51,21 +46,21 @@ var ( // to by external code to create new Machines in the same failure domain. It should start with a basic mapping and // then use existing Machine information to map failure domains, if possible, so that the Machine names match the // index of the failure domain in which they currently reside. -func mapMachineIndexesToFailureDomains(ctx context.Context, logger logr.Logger, cl client.Client, cpms *machinev1.ControlPlaneMachineSet, failureDomains []failuredomain.FailureDomain) (map[int32]failuredomain.FailureDomain, error) { +func mapMachineIndexesToFailureDomains(logger logr.Logger, machines []machinev1beta1.Machine, replicas int32, failureDomains []failuredomain.FailureDomain) (map[int32]failuredomain.FailureDomain, error) { if len(failureDomains) == 0 { logger.V(4).Info("No failure domains provided") return nil, errNoFailureDomains } - machineMapping, deletingIndexes, err := createMachineMapping(ctx, logger, cl, cpms) + machineMapping, deletingIndexes, err := createMachineMapping(logger, machines) if err != nil { return nil, fmt.Errorf("could not construct machine mapping: %w", err) } failureDomainsSet := failuredomain.NewSet(failureDomains...) - baseMapping, err := createBaseFailureDomainMapping(cpms, failureDomainsSet.List(), machineMapping) + baseMapping, err := createBaseFailureDomainMapping(replicas, failureDomainsSet.List(), machineMapping) if err != nil { return nil, fmt.Errorf("could not construct base failure domain mapping: %w", err) } @@ -86,10 +81,10 @@ func mapMachineIndexesToFailureDomains(ctx context.Context, logger logr.Logger, // domains. // Create the output based on the longer of the number of Machines or replicas so that when we reconcile the machine // mappings we always have enough candidates which are balanced between the available failure domains. -func createBaseFailureDomainMapping(cpms *machinev1.ControlPlaneMachineSet, failureDomains []failuredomain.FailureDomain, machineMapping map[int32]failuredomain.FailureDomain) (map[int32]failuredomain.FailureDomain, error) { +func createBaseFailureDomainMapping(replicas int32, failureDomains []failuredomain.FailureDomain, machineMapping map[int32]failuredomain.FailureDomain) (map[int32]failuredomain.FailureDomain, error) { out := make(map[int32]failuredomain.FailureDomain) - if cpms.Spec.Replicas == nil || *cpms.Spec.Replicas < 1 { + if replicas < 1 { return nil, errReplicasRequired } @@ -102,8 +97,8 @@ func createBaseFailureDomainMapping(cpms *machinev1.ControlPlaneMachineSet, fail // Create a base mapping which account for the larger of the number of machines or // the desired replica count. - if *cpms.Spec.Replicas > int32(machineIndexCount) { - machineIndexCount = int(*cpms.Spec.Replicas) + if replicas > int32(machineIndexCount) { + machineIndexCount = int(replicas) } if len(failureDomains) == 0 { @@ -128,36 +123,26 @@ func createBaseFailureDomainMapping(cpms *machinev1.ControlPlaneMachineSet, fail // createMachineMapping inspects the state of the Machines on the cluster, selected by the ControlPlaneMachineSet, and // creates a mapping of their indexes (if available) to their failure domain to allow the mapping to be customised // to the state of the cluster. -func createMachineMapping(ctx context.Context, logger logr.Logger, cl client.Client, cpms *machinev1.ControlPlaneMachineSet) (map[int32]failuredomain.FailureDomain, sets.Set[int32], error) { - selector, err := metav1.LabelSelectorAsSelector(&cpms.Spec.Selector) - if err != nil { - return nil, nil, fmt.Errorf("could not convert label selector to selector: %w", err) - } - - machineList := &machinev1beta1.MachineList{} - if err := cl.List(ctx, machineList, &client.ListOptions{LabelSelector: selector}); err != nil { - return nil, nil, fmt.Errorf("failed to list machines: %w", err) - } - - mapping, err := mapIndexesToFailureDomainsForMachines(logger, machineList) +func createMachineMapping(logger logr.Logger, machines []machinev1beta1.Machine) (map[int32]failuredomain.FailureDomain, sets.Set[int32], error) { + mapping, err := mapIndexesToFailureDomainsForMachines(logger, machines) if err != nil { return nil, nil, fmt.Errorf("could not map indexes to failure domains for machines: %w", err) } - deletingIndexes := listDeletingIndexes(machineList.Items) + deletingIndexes := listDeletingIndexes(machines) return mapping, deletingIndexes, nil } // mapIndexesToFailureDomainsForMachines creates an index to failure domain mapping for machine in the list. -func mapIndexesToFailureDomainsForMachines(logger logr.Logger, machineList *machinev1beta1.MachineList) (map[int32]failuredomain.FailureDomain, error) { +func mapIndexesToFailureDomainsForMachines(logger logr.Logger, machines []machinev1beta1.Machine) (map[int32]failuredomain.FailureDomain, error) { out := make(map[int32]failuredomain.FailureDomain) // indexToMachine contains a mapping between the machine domain index in the newest machine // for this particular index. indexToMachine := make(map[int32]machinev1beta1.Machine) - for _, machine := range machineList.Items { + for _, machine := range machines { failureDomain, err := providerconfig.ExtractFailureDomainFromMachine(logger, machine) if err != nil { return nil, fmt.Errorf("could not extract failure domain from machine %s: %w", machine.Name, err) diff --git a/pkg/machineproviders/providers/openshift/machine/v1beta1/mapping_test.go b/pkg/machineproviders/providers/openshift/machine/v1beta1/mapping_test.go index 653450c73..ccb9acb3d 100644 --- a/pkg/machineproviders/providers/openshift/machine/v1beta1/mapping_test.go +++ b/pkg/machineproviders/providers/openshift/machine/v1beta1/mapping_test.go @@ -31,9 +31,8 @@ import ( corev1resourcebuilder "github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/core/v1" machinev1resourcebuilder "github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/machine/v1" machinev1beta1resourcebuilder "github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/machine/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/utils/pointer" - "sigs.k8s.io/controller-runtime/pkg/envtest/komega" ) var _ = Describe("Failure Domain Mapping", func() { @@ -42,6 +41,8 @@ var _ = Describe("Failure Domain Mapping", func() { cpmsBuilder := machinev1resourcebuilder.ControlPlaneMachineSet().WithReplicas(3) machineBuilder := machinev1beta1resourcebuilder.Machine().AsMaster().WithLabel(machinev1beta1.MachineClusterIDLabel, resourcebuilder.TestClusterIDValue) + now := metav1.Now() + usEast1aSubnet := machinev1beta1.AWSResourceReference{ Filters: []machinev1beta1.Filter{ { @@ -213,7 +214,8 @@ var _ = Describe("Failure Domain Mapping", func() { Context("mappingMachineIndexesToFailureDomains", func() { type mappingMachineIndexesTableInput struct { - cpmsBuilder machinev1resourcebuilder.ControlPlaneMachineSetInterface + replicas int32 + selector metav1.LabelSelector failureDomains machinev1.FailureDomains machines []*machinev1beta1.Machine expectedError error @@ -227,26 +229,12 @@ var _ = Describe("Failure Domain Mapping", func() { logger := testutils.NewTestLogger() - cpms := in.cpmsBuilder.Build() - // Make sure all resources use the right namespace. - cpms.SetNamespace(namespaceName) - + machines := []machinev1beta1.Machine{} for _, machine := range in.machines { - machine.SetNamespace(namespaceName) - machine.Finalizers = append(machine.Finalizers, "machine.machine.openshift.io") - status := machine.Status.DeepCopy() - Expect(k8sClient.Create(ctx, machine)).To(Succeed()) - machine.Status = *status - Expect(k8sClient.Status().Update(ctx, machine)).To(Succeed()) - // It is not possible to create machine with deletion timestamp directly. Create one without it first, then delete the machine. - if pointer.StringDeref(status.Phase, "") == "Deleting" { - Expect(k8sClient.Delete(ctx, machine)).To(Succeed()) - } + machines = append(machines, *machine) } - originalCPMS := cpms.DeepCopy() - - mapping, err := mapMachineIndexesToFailureDomains(ctx, logger.Logger(), k8sClient, cpms, failureDomains) + mapping, err := mapMachineIndexesToFailureDomains(logger.Logger(), machines, in.replicas, failureDomains) if in.expectedError != nil { Expect(err).To(MatchError(in.expectedError)) } else { @@ -255,10 +243,10 @@ var _ = Describe("Failure Domain Mapping", func() { Expect(mapping).To(Equal(in.expectedMapping)) Expect(logger.Entries()).To(ConsistOf(in.expectedLogs)) - Expect(cpms).To(Equal(originalCPMS), "The update functions should not modify the ControlPlaneMachineSet in any way") }, Entry("with no failure domains defined, returns an empty mapping", mappingMachineIndexesTableInput{ - cpmsBuilder: cpmsBuilder, + replicas: 3, + selector: cpmsBuilder.Build().Spec.Selector, failureDomains: machinev1.FailureDomains{}, machines: []*machinev1beta1.Machine{ machineBuilder.WithName("machine-0").WithProviderSpecBuilder(usEast1aProviderSpecBuilder).Build(), @@ -275,7 +263,8 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with three failure domains matching three machines in order (a,b,c)", mappingMachineIndexesTableInput{ - cpmsBuilder: cpmsBuilder, + replicas: 3, + selector: cpmsBuilder.Build().Spec.Selector, failureDomains: machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( usEast1aFailureDomainBuilder, usEast1bFailureDomainBuilder, @@ -306,7 +295,8 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with three failure domains matching three machines in a order (b,c,a)", mappingMachineIndexesTableInput{ - cpmsBuilder: cpmsBuilder, + replicas: 3, + selector: cpmsBuilder.Build().Spec.Selector, failureDomains: machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( usEast1aFailureDomainBuilder, usEast1bFailureDomainBuilder, @@ -337,7 +327,8 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with three failure domains matching three machines in a order (b,a,c)", mappingMachineIndexesTableInput{ - cpmsBuilder: cpmsBuilder, + replicas: 3, + selector: cpmsBuilder.Build().Spec.Selector, failureDomains: machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( usEast1aFailureDomainBuilder, usEast1bFailureDomainBuilder, @@ -368,7 +359,8 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with three failure domains matching five machines in order (a,b,c,a,b)", mappingMachineIndexesTableInput{ - cpmsBuilder: cpmsBuilder.WithReplicas(5), + replicas: 5, + selector: cpmsBuilder.Build().Spec.Selector, failureDomains: machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( usEast1aFailureDomainBuilder, usEast1bFailureDomainBuilder, @@ -405,7 +397,7 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with three failure domains matching five machines in order (b,c,a,c,b)", mappingMachineIndexesTableInput{ - cpmsBuilder: cpmsBuilder.WithReplicas(5), + replicas: 5, failureDomains: machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( usEast1aFailureDomainBuilder, usEast1bFailureDomainBuilder, @@ -442,7 +434,7 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with three failure domains matching five machines in order (b,a,c,c,a)", mappingMachineIndexesTableInput{ - cpmsBuilder: cpmsBuilder.WithReplicas(5), + replicas: 5, failureDomains: machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( usEast1aFailureDomainBuilder, usEast1bFailureDomainBuilder, @@ -479,7 +471,8 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with a machine in an unrecognised failure domain (failure domains ordered a,b)", mappingMachineIndexesTableInput{ - cpmsBuilder: cpmsBuilder, + replicas: 3, + selector: cpmsBuilder.Build().Spec.Selector, failureDomains: machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( usEast1aFailureDomainBuilder, usEast1bFailureDomainBuilder, @@ -517,7 +510,8 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with a machine in an unrecognised failure domain (failure domains ordered b,a)", mappingMachineIndexesTableInput{ - cpmsBuilder: cpmsBuilder, + replicas: 3, + selector: cpmsBuilder.Build().Spec.Selector, failureDomains: machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( usEast1bFailureDomainBuilder, usEast1aFailureDomainBuilder, @@ -555,7 +549,8 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with multiple machines in unrecognised failure domains ", mappingMachineIndexesTableInput{ - cpmsBuilder: cpmsBuilder, + replicas: 3, + selector: cpmsBuilder.Build().Spec.Selector, failureDomains: machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( usEast1aFailureDomainBuilder, ).BuildFailureDomains(), @@ -600,7 +595,8 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with multiple machines in the same failure domain", mappingMachineIndexesTableInput{ - cpmsBuilder: cpmsBuilder, + replicas: 3, + selector: cpmsBuilder.Build().Spec.Selector, failureDomains: machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( usEast1aFailureDomainBuilder, usEast1bFailureDomainBuilder, @@ -640,7 +636,8 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with duplicate failure domains at the beginning of the Control Plane Machine Set", mappingMachineIndexesTableInput{ - cpmsBuilder: cpmsBuilder, + replicas: 3, + selector: cpmsBuilder.Build().Spec.Selector, failureDomains: machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( usEast1aFailureDomainBuilder, usEast1aFailureDomainBuilder, @@ -672,7 +669,8 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with duplicate failure domains at the end of the Control Plane Machine Set", mappingMachineIndexesTableInput{ - cpmsBuilder: cpmsBuilder, + replicas: 3, + selector: cpmsBuilder.Build().Spec.Selector, failureDomains: machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( usEast1aFailureDomainBuilder, usEast1bFailureDomainBuilder, @@ -704,7 +702,8 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with duplicate failure domains in the middle of the Control Plane Machine Set", mappingMachineIndexesTableInput{ - cpmsBuilder: cpmsBuilder, + replicas: 3, + selector: cpmsBuilder.Build().Spec.Selector, failureDomains: machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( usEast1aFailureDomainBuilder, usEast1bFailureDomainBuilder, @@ -736,7 +735,8 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with multiple duplicate failure domains in the Control Plane Machine Set", mappingMachineIndexesTableInput{ - cpmsBuilder: cpmsBuilder, + replicas: 3, + selector: cpmsBuilder.Build().Spec.Selector, failureDomains: machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( usEast1aFailureDomainBuilder, usEast1aFailureDomainBuilder, @@ -771,14 +771,15 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("when rebalancing indexes and an index only contains deleted machines", mappingMachineIndexesTableInput{ - cpmsBuilder: cpmsBuilder, + replicas: 3, + selector: cpmsBuilder.Build().Spec.Selector, failureDomains: machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( usEast1aFailureDomainBuilder, usEast1bFailureDomainBuilder, usEast1cFailureDomainBuilder, ).BuildFailureDomains(), machines: []*machinev1beta1.Machine{ - machineBuilder.WithName("machine-0").WithPhase("Deleting").WithProviderSpecBuilder(usEast1aProviderSpecBuilder).Build(), + machineBuilder.WithName("machine-0").WithPhase("Deleting").WithDeletionTimestamp(&now).WithProviderSpecBuilder(usEast1aProviderSpecBuilder).Build(), machineBuilder.WithName("machine-1").WithProviderSpecBuilder(usEast1aProviderSpecBuilder).Build(), machineBuilder.WithName("machine-2").WithProviderSpecBuilder(usEast1aProviderSpecBuilder).Build(), }, @@ -820,7 +821,8 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with a machine name does not indicate its index (a,b,c)", mappingMachineIndexesTableInput{ - cpmsBuilder: cpmsBuilder, + replicas: 3, + selector: cpmsBuilder.Build().Spec.Selector, failureDomains: machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( usEast1aFailureDomainBuilder, usEast1bFailureDomainBuilder, @@ -858,7 +860,8 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with a machine name does not indicate its index (b,c,a)", mappingMachineIndexesTableInput{ - cpmsBuilder: cpmsBuilder, + replicas: 3, + selector: cpmsBuilder.Build().Spec.Selector, failureDomains: machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( usEast1aFailureDomainBuilder, usEast1bFailureDomainBuilder, @@ -896,7 +899,7 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("when the machine mappings are unbalanced, should rebalance the failure domains (c,b,a,c,c)", mappingMachineIndexesTableInput{ - cpmsBuilder: cpmsBuilder.WithReplicas(5), + replicas: 5, failureDomains: machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( usEast1aFailureDomainBuilder, usEast1bFailureDomainBuilder, @@ -942,7 +945,8 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with three failure domains matching three machines indexed from 3 (a,b,c)", mappingMachineIndexesTableInput{ - cpmsBuilder: cpmsBuilder, + replicas: 3, + selector: cpmsBuilder.Build().Spec.Selector, failureDomains: machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( usEast1aFailureDomainBuilder, usEast1bFailureDomainBuilder, @@ -973,7 +977,8 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with three failure domains matching three machines that are not sequentially indexed (a,b,c)", mappingMachineIndexesTableInput{ - cpmsBuilder: cpmsBuilder, + replicas: 3, + selector: cpmsBuilder.Build().Spec.Selector, failureDomains: machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( usEast1aFailureDomainBuilder, usEast1bFailureDomainBuilder, @@ -1004,7 +1009,8 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with three failure domains matching three machines indexed from 3 (a,b,c)", mappingMachineIndexesTableInput{ - cpmsBuilder: cpmsBuilder, + replicas: 3, + selector: cpmsBuilder.Build().Spec.Selector, failureDomains: machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( usEast1aFailureDomainBuilder, usEast1bFailureDomainBuilder, @@ -1035,7 +1041,8 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with three failure domains matching four machines that are not sequentially indexed (b,a,b,c)", mappingMachineIndexesTableInput{ - cpmsBuilder: cpmsBuilder, + replicas: 3, + selector: cpmsBuilder.Build().Spec.Selector, failureDomains: machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( usEast1aFailureDomainBuilder, usEast1bFailureDomainBuilder, @@ -1069,7 +1076,8 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with three failure domains matching five machines that are not sequentially indexed (c,a,a,b,c)", mappingMachineIndexesTableInput{ - cpmsBuilder: cpmsBuilder, + replicas: 3, + selector: cpmsBuilder.Build().Spec.Selector, failureDomains: machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( usEast1aFailureDomainBuilder, usEast1bFailureDomainBuilder, @@ -1106,7 +1114,8 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with three failure domains matching five machines which duplicate indexes", mappingMachineIndexesTableInput{ - cpmsBuilder: cpmsBuilder, + replicas: 3, + selector: cpmsBuilder.Build().Spec.Selector, failureDomains: machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( usEast1aFailureDomainBuilder, usEast1bFailureDomainBuilder, @@ -1139,7 +1148,8 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with three failure domains matching 7 machines which duplicate indexes", mappingMachineIndexesTableInput{ - cpmsBuilder: cpmsBuilder, + replicas: 3, + selector: cpmsBuilder.Build().Spec.Selector, failureDomains: machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( usEast1aFailureDomainBuilder, usEast1bFailureDomainBuilder, @@ -1176,7 +1186,8 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with four failure domains matching three machines, but skipping the first failure domain", mappingMachineIndexesTableInput{ - cpmsBuilder: cpmsBuilder, + replicas: 3, + selector: cpmsBuilder.Build().Spec.Selector, failureDomains: machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( usEast1aFailureDomainBuilder, usEast1bFailureDomainBuilder, @@ -1212,7 +1223,7 @@ var _ = Describe("Failure Domain Mapping", func() { Context("createBaseFailureDomainMapping", func() { type createBaseMappingTableInput struct { - cpmsBuilder machinev1resourcebuilder.ControlPlaneMachineSetInterface + replicas int32 machineMapping map[int32]failuredomain.FailureDomain failureDomains machinev1.FailureDomains expectedMapping map[int32]failuredomain.FailureDomain @@ -1223,8 +1234,7 @@ var _ = Describe("Failure Domain Mapping", func() { failureDomains, err := failuredomain.NewFailureDomains(in.failureDomains) Expect(err).ToNot(HaveOccurred()) - cpms := in.cpmsBuilder.Build() - mapping, err := createBaseFailureDomainMapping(cpms, failureDomains, in.machineMapping) + mapping, err := createBaseFailureDomainMapping(in.replicas, failureDomains, in.machineMapping) if in.expectedError != nil { Expect(err).To(MatchError(in.expectedError)) } else { @@ -1234,7 +1244,7 @@ var _ = Describe("Failure Domain Mapping", func() { Expect(mapping).To(Equal(in.expectedMapping)) }, Entry("with no replicas set", createBaseMappingTableInput{ - cpmsBuilder: cpmsBuilder.WithReplicas(0), + replicas: 0, failureDomains: machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( usEast1aFailureDomainBuilder, usEast1bFailureDomainBuilder, @@ -1243,7 +1253,7 @@ var _ = Describe("Failure Domain Mapping", func() { expectedError: errReplicasRequired, }), Entry("with three replicas and three failure domains (order a,b,c)", createBaseMappingTableInput{ - cpmsBuilder: cpmsBuilder.WithReplicas(3), + replicas: 3, machineMapping: map[int32]failuredomain.FailureDomain{ 0: failuredomain.NewAWSFailureDomain(usEast1aFailureDomainBuilder.Build()), 1: failuredomain.NewAWSFailureDomain(usEast1bFailureDomainBuilder.Build()), @@ -1261,7 +1271,7 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with three replicas and three failure domains (order b,c,a)", createBaseMappingTableInput{ - cpmsBuilder: cpmsBuilder.WithReplicas(3), + replicas: 3, machineMapping: map[int32]failuredomain.FailureDomain{ 0: failuredomain.NewAWSFailureDomain(usEast1bFailureDomainBuilder.Build()), 1: failuredomain.NewAWSFailureDomain(usEast1cFailureDomainBuilder.Build()), @@ -1279,7 +1289,7 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with three replicas and three failure domains (order b,a,c)", createBaseMappingTableInput{ - cpmsBuilder: cpmsBuilder.WithReplicas(3), + replicas: 3, machineMapping: map[int32]failuredomain.FailureDomain{ 0: failuredomain.NewAWSFailureDomain(usEast1bFailureDomainBuilder.Build()), 1: failuredomain.NewAWSFailureDomain(usEast1aFailureDomainBuilder.Build()), @@ -1297,7 +1307,7 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with three replicas and one failure domains", createBaseMappingTableInput{ - cpmsBuilder: cpmsBuilder.WithReplicas(3), + replicas: 3, machineMapping: map[int32]failuredomain.FailureDomain{ 0: failuredomain.NewAWSFailureDomain(usEast1aFailureDomainBuilder.Build()), 1: failuredomain.NewAWSFailureDomain(usEast1aFailureDomainBuilder.Build()), @@ -1313,7 +1323,7 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with three replicas and two failure domains (order a,b)", createBaseMappingTableInput{ - cpmsBuilder: cpmsBuilder.WithReplicas(3), + replicas: 3, machineMapping: map[int32]failuredomain.FailureDomain{ 0: failuredomain.NewAWSFailureDomain(usEast1aFailureDomainBuilder.Build()), 1: failuredomain.NewAWSFailureDomain(usEast1bFailureDomainBuilder.Build()), @@ -1330,7 +1340,7 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with three replicas and two failure domains (order b,a)", createBaseMappingTableInput{ - cpmsBuilder: cpmsBuilder.WithReplicas(3), + replicas: 3, machineMapping: map[int32]failuredomain.FailureDomain{ 0: failuredomain.NewAWSFailureDomain(usEast1bFailureDomainBuilder.Build()), 1: failuredomain.NewAWSFailureDomain(usEast1aFailureDomainBuilder.Build()), @@ -1347,7 +1357,7 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with five replicas and three failure domains (order a,b,c)", createBaseMappingTableInput{ - cpmsBuilder: cpmsBuilder.WithReplicas(5), + replicas: 5, machineMapping: map[int32]failuredomain.FailureDomain{ 0: failuredomain.NewAWSFailureDomain(usEast1aFailureDomainBuilder.Build()), 1: failuredomain.NewAWSFailureDomain(usEast1aFailureDomainBuilder.Build()), @@ -1369,7 +1379,7 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with five replicas and three failure domains (order b,c,a)", createBaseMappingTableInput{ - cpmsBuilder: cpmsBuilder.WithReplicas(5), + replicas: 5, machineMapping: map[int32]failuredomain.FailureDomain{ 0: failuredomain.NewAWSFailureDomain(usEast1aFailureDomainBuilder.Build()), 1: failuredomain.NewAWSFailureDomain(usEast1aFailureDomainBuilder.Build()), @@ -1391,7 +1401,7 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with five replicas and two failure domains (order a,b)", createBaseMappingTableInput{ - cpmsBuilder: cpmsBuilder.WithReplicas(5), + replicas: 5, machineMapping: map[int32]failuredomain.FailureDomain{ 0: failuredomain.NewAWSFailureDomain(usEast1aFailureDomainBuilder.Build()), 1: failuredomain.NewAWSFailureDomain(usEast1aFailureDomainBuilder.Build()), @@ -1412,7 +1422,7 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with five replicas and two failure domains (order b,a)", createBaseMappingTableInput{ - cpmsBuilder: cpmsBuilder.WithReplicas(5), + replicas: 5, machineMapping: map[int32]failuredomain.FailureDomain{ 0: failuredomain.NewAWSFailureDomain(usEast1aFailureDomainBuilder.Build()), 1: failuredomain.NewAWSFailureDomain(usEast1aFailureDomainBuilder.Build()), @@ -1433,7 +1443,7 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with three replicas but a machine count of five", createBaseMappingTableInput{ - cpmsBuilder: cpmsBuilder.WithReplicas(3), + replicas: 3, machineMapping: map[int32]failuredomain.FailureDomain{ 0: failuredomain.NewAWSFailureDomain(usEast1aFailureDomainBuilder.Build()), 1: failuredomain.NewAWSFailureDomain(usEast1aFailureDomainBuilder.Build()), @@ -1455,7 +1465,7 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with four replicas but a machine count of 2", createBaseMappingTableInput{ - cpmsBuilder: cpmsBuilder.WithReplicas(4), + replicas: 4, machineMapping: map[int32]failuredomain.FailureDomain{ 0: failuredomain.NewAWSFailureDomain(usEast1aFailureDomainBuilder.Build()), 1: failuredomain.NewAWSFailureDomain(usEast1bFailureDomainBuilder.Build()), @@ -1473,7 +1483,7 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with 3 replicas but a machine count of 1 (machine a)", createBaseMappingTableInput{ - cpmsBuilder: cpmsBuilder.WithReplicas(3), + replicas: 3, machineMapping: map[int32]failuredomain.FailureDomain{ 0: failuredomain.NewAWSFailureDomain(usEast1aFailureDomainBuilder.Build()), }, @@ -1489,7 +1499,7 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with 3 replicas but a machine count of 1 (machine b)", createBaseMappingTableInput{ - cpmsBuilder: cpmsBuilder.WithReplicas(3), + replicas: 3, machineMapping: map[int32]failuredomain.FailureDomain{ 0: failuredomain.NewAWSFailureDomain(usEast1bFailureDomainBuilder.Build()), }, @@ -1505,7 +1515,7 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with 3 replicas but a machine count of 1 (machine c)", createBaseMappingTableInput{ - cpmsBuilder: cpmsBuilder.WithReplicas(3), + replicas: 3, machineMapping: map[int32]failuredomain.FailureDomain{ 0: failuredomain.NewAWSFailureDomain(usEast1cFailureDomainBuilder.Build()), }, @@ -1521,7 +1531,7 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with five failure domains and three machines, should prioritise machine domains", createBaseMappingTableInput{ - cpmsBuilder: cpmsBuilder.WithReplicas(5), + replicas: 5, machineMapping: map[int32]failuredomain.FailureDomain{ 0: failuredomain.NewAWSFailureDomain(usEast1dFailureDomainBuilder.Build()), 1: failuredomain.NewAWSFailureDomain(usEast1cFailureDomainBuilder.Build()), @@ -1547,9 +1557,8 @@ var _ = Describe("Failure Domain Mapping", func() { Context("createMachineMapping", func() { type machineMappingTableInput struct { - cpmsBuilder machinev1resourcebuilder.ControlPlaneMachineSetInterface + selector metav1.LabelSelector machines []*machinev1beta1.Machine - deleteMachines []int expectedDeletingIndexes sets.Set[int32] expectedError error expectedMapping map[int32]failuredomain.FailureDomain @@ -1559,26 +1568,13 @@ var _ = Describe("Failure Domain Mapping", func() { DescribeTable("maps Machines based on their failure domain", func(in machineMappingTableInput) { logger := testutils.NewTestLogger() - cpms := cpmsBuilder.Build() - // Make sure all resources use the right namespace. - cpms.SetNamespace(namespaceName) + machines := []machinev1beta1.Machine{} for _, machine := range in.machines { - machine.SetNamespace(namespaceName) - Expect(k8sClient.Create(ctx, machine)).To(Succeed()) + machines = append(machines, *machine) } - for _, index := range in.deleteMachines { - Eventually(komega.Update(in.machines[index], func() { - in.machines[index].SetFinalizers([]string{"machine.openshift.io/machine"}) - })).Should(Succeed()) - - Expect(k8sClient.Delete(ctx, in.machines[index])).To(Succeed()) - } - - originalCPMS := cpms.DeepCopy() - - mapping, deletingIndexes, err := createMachineMapping(ctx, logger.Logger(), k8sClient, cpms) + mapping, deletingIndexes, err := createMachineMapping(logger.Logger(), machines) if in.expectedError != nil { Expect(err).To(MatchError(in.expectedError)) } else { @@ -1588,10 +1584,9 @@ var _ = Describe("Failure Domain Mapping", func() { Expect(mapping).To(Equal(in.expectedMapping)) Expect(deletingIndexes).To(Equal(in.expectedDeletingIndexes)) Expect(logger.Entries()).To(ConsistOf(in.expectedLogs)) - Expect(cpms).To(Equal(originalCPMS), "The update functions should not modify the ControlPlaneMachineSet in any way") }, Entry("with machines in three failure domains (order a,b,c)", machineMappingTableInput{ - cpmsBuilder: cpmsBuilder, + selector: cpmsBuilder.Build().Spec.Selector, machines: []*machinev1beta1.Machine{ machineBuilder.WithName("machine-0").WithProviderSpecBuilder(usEast1aProviderSpecBuilder).Build(), machineBuilder.WithName("machine-1").WithProviderSpecBuilder(usEast1bProviderSpecBuilder).Build(), @@ -1606,7 +1601,7 @@ var _ = Describe("Failure Domain Mapping", func() { expectedLogs: []testutils.LogEntry{}, }), Entry("with machines in three failure domains (order b,c,a)", machineMappingTableInput{ - cpmsBuilder: cpmsBuilder, + selector: cpmsBuilder.Build().Spec.Selector, machines: []*machinev1beta1.Machine{ machineBuilder.WithName("machine-0").WithProviderSpecBuilder(usEast1bProviderSpecBuilder).Build(), machineBuilder.WithName("machine-1").WithProviderSpecBuilder(usEast1cProviderSpecBuilder).Build(), @@ -1621,7 +1616,7 @@ var _ = Describe("Failure Domain Mapping", func() { expectedLogs: []testutils.LogEntry{}, }), Entry("with machines with non-index names", machineMappingTableInput{ - cpmsBuilder: cpmsBuilder, + selector: cpmsBuilder.Build().Spec.Selector, machines: []*machinev1beta1.Machine{ machineBuilder.WithName("machine-a").WithProviderSpecBuilder(usEast1aProviderSpecBuilder).Build(), machineBuilder.WithName("machine-1").WithProviderSpecBuilder(usEast1bProviderSpecBuilder).Build(), @@ -1649,7 +1644,7 @@ var _ = Describe("Failure Domain Mapping", func() { }, }), Entry("with multiple machines in a failure domains", machineMappingTableInput{ - cpmsBuilder: cpmsBuilder, + selector: cpmsBuilder.Build().Spec.Selector, machines: []*machinev1beta1.Machine{ machineBuilder.WithName("machine-0").WithProviderSpecBuilder(usEast1aProviderSpecBuilder).Build(), machineBuilder.WithName("machine-1").WithProviderSpecBuilder(usEast1aProviderSpecBuilder).Build(), @@ -1664,7 +1659,7 @@ var _ = Describe("Failure Domain Mapping", func() { expectedLogs: []testutils.LogEntry{}, }), Entry("with multiple machines in the same index in the same failure domain", machineMappingTableInput{ - cpmsBuilder: cpmsBuilder, + selector: cpmsBuilder.Build().Spec.Selector, machines: []*machinev1beta1.Machine{ machineBuilder.WithName("machine-0").WithProviderSpecBuilder(usEast1aProviderSpecBuilder).Build(), machineBuilder.WithName("machine-replacement-0").WithProviderSpecBuilder(usEast1aProviderSpecBuilder).Build(), @@ -1678,7 +1673,7 @@ var _ = Describe("Failure Domain Mapping", func() { expectedLogs: []testutils.LogEntry{}, }), Entry("with multiple machines in the same index in different failure domains", machineMappingTableInput{ - cpmsBuilder: cpmsBuilder, + selector: cpmsBuilder.Build().Spec.Selector, machines: []*machinev1beta1.Machine{ machineBuilder.WithName("machine-0").WithProviderSpecBuilder(usEast1aProviderSpecBuilder).Build(), machineBuilder.WithName("machine-replacement-0").WithProviderSpecBuilder(usEast1bProviderSpecBuilder).Build(), @@ -1702,21 +1697,8 @@ var _ = Describe("Failure Domain Mapping", func() { }, }, }), - Entry("with machines not matched by the selector", machineMappingTableInput{ - cpmsBuilder: cpmsBuilder, - machines: []*machinev1beta1.Machine{ - machineBuilder.WithName("machine-0").WithProviderSpecBuilder(usEast1aProviderSpecBuilder).Build(), - machinev1beta1resourcebuilder.Machine().AsWorker().WithName("machine-1").WithProviderSpecBuilder(usEast1cProviderSpecBuilder).Build(), - machinev1beta1resourcebuilder.Machine().AsWorker().WithName("machine-2").WithProviderSpecBuilder(usEast1bProviderSpecBuilder).Build(), - }, - expectedDeletingIndexes: sets.New[int32](), - expectedMapping: map[int32]failuredomain.FailureDomain{ - 0: failuredomain.NewAWSFailureDomain(usEast1aFailureDomainBuilder.Build()), - }, - expectedLogs: []testutils.LogEntry{}, - }), Entry("with machines in three failure domains indexed from 3 (order a,b,c)", machineMappingTableInput{ - cpmsBuilder: cpmsBuilder, + selector: cpmsBuilder.Build().Spec.Selector, machines: []*machinev1beta1.Machine{ machineBuilder.WithName("machine-3").WithProviderSpecBuilder(usEast1aProviderSpecBuilder).Build(), machineBuilder.WithName("machine-4").WithProviderSpecBuilder(usEast1bProviderSpecBuilder).Build(), @@ -1731,7 +1713,7 @@ var _ = Describe("Failure Domain Mapping", func() { expectedLogs: []testutils.LogEntry{}, }), Entry("with machines in three failure domains not sequentially indexed (order a,b,c)", machineMappingTableInput{ - cpmsBuilder: cpmsBuilder, + selector: cpmsBuilder.Build().Spec.Selector, machines: []*machinev1beta1.Machine{ machineBuilder.WithName("machine-0").WithProviderSpecBuilder(usEast1aProviderSpecBuilder).Build(), machineBuilder.WithName("machine-2").WithProviderSpecBuilder(usEast1bProviderSpecBuilder).Build(), @@ -1746,13 +1728,12 @@ var _ = Describe("Failure Domain Mapping", func() { expectedLogs: []testutils.LogEntry{}, }), Entry("with an index that only contains deleted machines", machineMappingTableInput{ - cpmsBuilder: cpmsBuilder, + selector: cpmsBuilder.Build().Spec.Selector, machines: []*machinev1beta1.Machine{ - machineBuilder.WithName("machine-0").WithProviderSpecBuilder(usEast1aProviderSpecBuilder).Build(), + machineBuilder.WithName("machine-0").WithDeletionTimestamp(&now).WithProviderSpecBuilder(usEast1aProviderSpecBuilder).Build(), machineBuilder.WithName("machine-1").WithProviderSpecBuilder(usEast1bProviderSpecBuilder).Build(), machineBuilder.WithName("machine-2").WithProviderSpecBuilder(usEast1cProviderSpecBuilder).Build(), }, - deleteMachines: []int{0}, expectedDeletingIndexes: sets.New[int32](0), expectedMapping: map[int32]failuredomain.FailureDomain{ 0: failuredomain.NewAWSFailureDomain(usEast1aFailureDomainBuilder.Build()), @@ -1762,13 +1743,12 @@ var _ = Describe("Failure Domain Mapping", func() { expectedLogs: []testutils.LogEntry{}, }), Entry("with multiple indexes that only contain deleted machines", machineMappingTableInput{ - cpmsBuilder: cpmsBuilder, + selector: cpmsBuilder.Build().Spec.Selector, machines: []*machinev1beta1.Machine{ - machineBuilder.WithName("machine-0").WithProviderSpecBuilder(usEast1aProviderSpecBuilder).Build(), + machineBuilder.WithName("machine-0").WithDeletionTimestamp(&now).WithProviderSpecBuilder(usEast1aProviderSpecBuilder).Build(), machineBuilder.WithName("machine-1").WithProviderSpecBuilder(usEast1bProviderSpecBuilder).Build(), - machineBuilder.WithName("machine-2").WithProviderSpecBuilder(usEast1cProviderSpecBuilder).Build(), + machineBuilder.WithName("machine-2").WithDeletionTimestamp(&now).WithProviderSpecBuilder(usEast1cProviderSpecBuilder).Build(), }, - deleteMachines: []int{0, 2}, expectedDeletingIndexes: sets.New[int32](0, 2), expectedMapping: map[int32]failuredomain.FailureDomain{ 0: failuredomain.NewAWSFailureDomain(usEast1aFailureDomainBuilder.Build()), @@ -1778,14 +1758,13 @@ var _ = Describe("Failure Domain Mapping", func() { expectedLogs: []testutils.LogEntry{}, }), Entry("with an index that contains a deleted machine and a non-deleted machine", machineMappingTableInput{ - cpmsBuilder: cpmsBuilder, + selector: cpmsBuilder.Build().Spec.Selector, machines: []*machinev1beta1.Machine{ - machineBuilder.WithName("machine-0").WithProviderSpecBuilder(usEast1aProviderSpecBuilder).Build(), + machineBuilder.WithName("machine-0").WithDeletionTimestamp(&now).WithProviderSpecBuilder(usEast1aProviderSpecBuilder).Build(), machineBuilder.WithName("machine-replacement-0").WithProviderSpecBuilder(usEast1aProviderSpecBuilder).Build(), machineBuilder.WithName("machine-1").WithProviderSpecBuilder(usEast1bProviderSpecBuilder).Build(), machineBuilder.WithName("machine-2").WithProviderSpecBuilder(usEast1cProviderSpecBuilder).Build(), }, - deleteMachines: []int{0}, expectedDeletingIndexes: sets.New[int32](), expectedMapping: map[int32]failuredomain.FailureDomain{ 0: failuredomain.NewAWSFailureDomain(usEast1aFailureDomainBuilder.Build()), diff --git a/pkg/machineproviders/providers/openshift/machine/v1beta1/provider.go b/pkg/machineproviders/providers/openshift/machine/v1beta1/provider.go index a4e7b9c45..1b5b2456e 100644 --- a/pkg/machineproviders/providers/openshift/machine/v1beta1/provider.go +++ b/pkg/machineproviders/providers/openshift/machine/v1beta1/provider.go @@ -29,6 +29,7 @@ import ( corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" apimachineryruntime "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/rand" @@ -110,9 +111,11 @@ func NewMachineProvider(ctx context.Context, logger logr.Logger, cl client.Clien return nil, fmt.Errorf("error constructing failure domain config: %w", err) } - indexToFailureDomain, err := mapMachineIndexesToFailureDomains(ctx, logger, cl, cpms, failureDomains) - if err != nil && !errors.Is(err, errNoFailureDomains) { - return nil, fmt.Errorf("error mapping machine indexes: %w", err) + replicas := pointer.Int32Deref(cpms.Spec.Replicas, 0) + + selector, err := metav1.LabelSelectorAsSelector(&cpms.Spec.Selector) + if err != nil { + return nil, fmt.Errorf("could not convert label selector to selector: %w", err) } machineAPIScheme := apimachineryruntime.NewScheme() @@ -124,16 +127,23 @@ func NewMachineProvider(ctx context.Context, logger logr.Logger, cl client.Clien return nil, fmt.Errorf("unable to add machine.openshift.io/v1beta1 scheme: %w", err) } - return &openshiftMachineProvider{ - client: cl, - indexToFailureDomain: indexToFailureDomain, - machineSelector: cpms.Spec.Selector, - machineTemplate: *cpms.Spec.Template.OpenShiftMachineV1Beta1Machine, - ownerMetadata: cpms.ObjectMeta, - providerConfig: providerConfig, - namespace: cpms.Namespace, - machineAPIScheme: machineAPIScheme, - }, nil + o := &openshiftMachineProvider{ + client: cl, + failureDomains: failureDomains, + machineSelector: selector, + machineTemplate: *cpms.Spec.Template.OpenShiftMachineV1Beta1Machine, + ownerMetadata: cpms.ObjectMeta, + providerConfig: providerConfig, + replicas: replicas, + namespace: cpms.Namespace, + machineAPIScheme: machineAPIScheme, + } + + if err := o.updateMachineCache(ctx, logger); err != nil { + return nil, fmt.Errorf("error updating machine cache: %w", err) + } + + return o, nil } // openshiftMachineProvider holds the implementation of the MachineProvider interface. @@ -147,9 +157,20 @@ type openshiftMachineProvider struct { // We use a built in type to avoid leaking implementation specific details. indexToFailureDomain map[int32]failuredomain.FailureDomain + // failureDomains is the list of failure domains collected from the CPMS spec when + // the machine provider was constructed. + failureDomains []failuredomain.FailureDomain + + // machines is the list of machines collected from the API when the cache was built. + // This should be tied to the lifecycle of indexToFailureDomain since the domain mapping + // logic is affected by the contents of these machines. + // Should the machine list ever be refreshed (e.g. by changing client), then the mapping + // must also be refreshed. + machines []machinev1beta1.Machine + // machineSelector is used to identify which Machines should be considered by // the machine provider when constructing machine information. - machineSelector metav1.LabelSelector + machineSelector labels.Selector // machineTemplate is used to create new Machines. machineTemplate machinev1.OpenShiftMachineV1Beta1MachineTemplate @@ -161,6 +182,8 @@ type openshiftMachineProvider struct { // providerConfig stores the providerConfig for creating new Machines. providerConfig providerconfig.ProviderConfig + replicas int32 + // namespace store the namespace where new machines will be created. namespace string @@ -168,15 +191,41 @@ type openshiftMachineProvider struct { machineAPIScheme *apimachineryruntime.Scheme } +// updateMachineCache fetches the current list of Machines and calculates from these the appropriate index +// to failure domain mapping. The machine list and index to failure domain must be updated in lock-step since +// the mapping relies on the content of the machines. +func (m *openshiftMachineProvider) updateMachineCache(ctx context.Context, logger logr.Logger) error { + machineList := &machinev1beta1.MachineList{} + if err := m.client.List(ctx, machineList, &client.ListOptions{LabelSelector: m.machineSelector}); err != nil { + return fmt.Errorf("failed to list machines: %w", err) + } + + // Since the mapping depends on the state of the machines, we must re-map the failure domains if the machines have changed. + indexToFailureDomain, err := mapMachineIndexesToFailureDomains(logger, machineList.Items, m.replicas, m.failureDomains) + if err != nil && !errors.Is(err, errNoFailureDomains) { + return fmt.Errorf("error mapping machine indexes: %w", err) + } + + m.machines = machineList.Items + m.indexToFailureDomain = indexToFailureDomain + + return nil +} + // WithClient sets the desired client to the Machine Provider. -func (m *openshiftMachineProvider) WithClient(client client.Client) machineproviders.MachineProvider { +func (m *openshiftMachineProvider) WithClient(ctx context.Context, logger logr.Logger, cl client.Client) (machineproviders.MachineProvider, error) { // Take a shallow copy, this should be sufficient for the usage of the provider. o := &openshiftMachineProvider{} *o = *m - o.client = client + o.client = cl + + // Make sure to update the cached machine data now that we have a new client. + if err := o.updateMachineCache(ctx, logger); err != nil { + return nil, fmt.Errorf("error updating machine cache: %w", err) + } - return o + return o, nil } // GetMachineInfos inspects the current state of the Machines matched by the selector @@ -190,17 +239,7 @@ func (m *openshiftMachineProvider) WithClient(client client.Client) machineprovi func (m *openshiftMachineProvider) GetMachineInfos(ctx context.Context, logger logr.Logger) ([]machineproviders.MachineInfo, error) { machineInfos := []machineproviders.MachineInfo{} - selector, err := metav1.LabelSelectorAsSelector(&m.machineSelector) - if err != nil { - return nil, fmt.Errorf("could not convert label selector to selector: %w", err) - } - - machineList := &machinev1beta1.MachineList{} - if err := m.client.List(ctx, machineList, &client.ListOptions{LabelSelector: selector}); err != nil { - return nil, fmt.Errorf("failed to list machines: %w", err) - } - - for _, machine := range machineList.Items { + for _, machine := range m.machines { machineInfo, err := m.generateMachineInfo(ctx, logger, machine) if err != nil { return nil, fmt.Errorf("could not generate machine info for machine %s: %w", machine.Name, err) @@ -218,7 +257,7 @@ func (m *openshiftMachineProvider) GetMachineInfos(ctx context.Context, logger l logger.V(4).Info( "Gathered Machine Info", - "machineName", machineList.Items[i].Name, + "machineName", m.machines[i].Name, "nodeName", nodeName, "index", machineInfo.Index, "ready", machineInfo.Ready, diff --git a/pkg/machineproviders/providers/openshift/machine/v1beta1/provider_test.go b/pkg/machineproviders/providers/openshift/machine/v1beta1/provider_test.go index 0b12de7c7..631e14253 100644 --- a/pkg/machineproviders/providers/openshift/machine/v1beta1/provider_test.go +++ b/pkg/machineproviders/providers/openshift/machine/v1beta1/provider_test.go @@ -179,15 +179,9 @@ var _ = Describe("MachineProvider", func() { } DescribeTable("builds machine info based on the cluster state", func(in getMachineInfosTableInput) { + machines := []machinev1beta1.Machine{} for _, machine := range in.machines { - machine.SetNamespace(namespaceName) - - status := machine.Status.DeepCopy() - - Expect(k8sClient.Create(ctx, machine)).To(Succeed()) - - machine.Status = *status - Expect(k8sClient.Status().Update(ctx, machine)).To(Succeed()) + machines = append(machines, *machine) } for _, node := range in.nodes { @@ -199,12 +193,6 @@ var _ = Describe("MachineProvider", func() { Expect(k8sClient.Status().Update(ctx, node)).To(Succeed()) } - // Inject namespace in the expected machine infos since it doesn't happen during - // initial building. - for i := 0; i < len(in.expectedMachineInfos); i++ { - in.expectedMachineInfos[i].MachineRef.ObjectMeta.SetNamespace(namespaceName) - } - providerSpec := providerSpecBuilder if len(in.failureDomains) == 0 { // When no failure domain information is provided, we assume all machines are in us-east-1a. @@ -222,10 +210,14 @@ var _ = Describe("MachineProvider", func() { providerConfig, err := providerconfig.NewProviderConfigFromMachineTemplate(logger.Logger(), *template) Expect(err).ToNot(HaveOccurred()) + selector, err := metav1.LabelSelectorAsSelector(&cpms.Spec.Selector) + Expect(err).ToNot(HaveOccurred()) + provider := &openshiftMachineProvider{ client: k8sClient, indexToFailureDomain: in.failureDomains, - machineSelector: cpms.Spec.Selector, + machines: machines, + machineSelector: selector, machineTemplate: *template, providerConfig: providerConfig, namespace: namespaceName, @@ -1068,58 +1060,6 @@ var _ = Describe("MachineProvider", func() { }, }, }), - Entry("with additional Machines, not matched by the selector, ignores them", getMachineInfosTableInput{ - machines: []*machinev1beta1.Machine{ - masterMachineBuilder.WithName(masterMachineName("0")).WithProviderSpecBuilder(providerSpecBuilder.WithAvailabilityZone("us-east-1a").WithSubnet(usEast1aSubnetbeta1)). - WithPhase("Running").WithNodeRef(corev1.ObjectReference{Name: "node-0"}).Build(), - masterMachineBuilder.WithName(masterMachineName("1")).WithProviderSpecBuilder(providerSpecBuilder.WithAvailabilityZone("us-east-1b").WithSubnet(usEast1bSubnetbeta1)). - WithPhase("Running").WithNodeRef(corev1.ObjectReference{Name: "node-1"}).Build(), - machinev1beta1resourcebuilder.Machine().AsWorker().WithNamespace(namespaceName).WithName("worker-abcde").WithProviderSpecBuilder(providerSpecBuilder.WithAvailabilityZone("us-east-1c").WithSubnet(usEast1cSubnetbeta1)). - WithPhase("Running").WithNodeRef(corev1.ObjectReference{Name: "node-2"}).Build(), - }, - nodes: []*corev1.Node{ - masterNodeBuilder.WithName("node-0").Build(), - masterNodeBuilder.WithName("node-1").Build(), - masterNodeBuilder.WithName("node-2").Build(), - }, - failureDomains: map[int32]failuredomain.FailureDomain{ - 0: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1a").WithSubnet(usEast1aSubnet).Build()), - 1: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1b").WithSubnet(usEast1bSubnet).Build()), - 2: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1c").WithSubnet(usEast1cSubnet).Build()), - }, - expectedMachineInfos: []machineproviders.MachineInfo{ - readyMachineInfoBuilder.WithIndex(0).WithMachineName(masterMachineName("0")).WithNodeName("node-0").Build(), - readyMachineInfoBuilder.WithIndex(1).WithMachineName(masterMachineName("1")).WithNodeName("node-1").Build(), - }, - expectedLogs: []testutils.LogEntry{ - { - Level: 4, - KeysAndValues: []interface{}{ - "machineName", masterMachineName("0"), - "nodeName", "node-0", - "index", int32(0), - "ready", true, - "needsUpdate", false, - "diff", nilDiff, - "errorMessage", "", - }, - Message: "Gathered Machine Info", - }, - { - Level: 4, - KeysAndValues: []interface{}{ - "machineName", masterMachineName("1"), - "nodeName", "node-1", - "index", int32(1), - "ready", true, - "needsUpdate", false, - "diff", nilDiff, - "errorMessage", "", - }, - Message: "Gathered Machine Info", - }, - }, - }), Entry("with a Machine whose failure domain does not match the mapping, should update the Machine", getMachineInfosTableInput{ machines: []*machinev1beta1.Machine{ masterMachineBuilder.WithName(masterMachineName("0")).WithProviderSpecBuilder(providerSpecBuilder.WithAvailabilityZone("us-east-1a").WithSubnet(usEast1aSubnetbeta1)). @@ -1560,6 +1500,9 @@ var _ = Describe("MachineProvider", func() { providerConfig, err := providerconfig.NewProviderConfigFromMachineTemplate(logger.Logger(), *template.OpenShiftMachineV1Beta1Machine) Expect(err).ToNot(HaveOccurred()) + selector, err := metav1.LabelSelectorAsSelector(&machinev1resourcebuilder.ControlPlaneMachineSet().Build().Spec.Selector) + Expect(err).ToNot(HaveOccurred()) + provider = &openshiftMachineProvider{ client: k8sClient, indexToFailureDomain: map[int32]failuredomain.FailureDomain{ @@ -1567,7 +1510,7 @@ var _ = Describe("MachineProvider", func() { 1: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1b").WithSubnet(usEast1bSubnet).Build()), 2: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1c").WithSubnet(usEast1cSubnet).Build()), }, - machineSelector: machinev1resourcebuilder.ControlPlaneMachineSet().Build().Spec.Selector, + machineSelector: selector, machineTemplate: *template.OpenShiftMachineV1Beta1Machine, ownerMetadata: metav1.ObjectMeta{ Name: ownerName, @@ -1669,10 +1612,13 @@ var _ = Describe("MachineProvider", func() { providerConfig, err := providerconfig.NewProviderConfigFromMachineTemplate(logger.Logger(), *template) Expect(err).ToNot(HaveOccurred()) + selector, err := metav1.LabelSelectorAsSelector(&cpms.Spec.Selector) + Expect(err).ToNot(HaveOccurred()) + machineProvider = &openshiftMachineProvider{ client: k8sClient, indexToFailureDomain: map[int32]failuredomain.FailureDomain{}, - machineSelector: cpms.Spec.Selector, + machineSelector: selector, machineTemplate: *template, ownerMetadata: metav1.ObjectMeta{ UID: types.UID(ownerUID), diff --git a/pkg/machineproviders/types.go b/pkg/machineproviders/types.go index d55b9ffcf..5596f0ac9 100644 --- a/pkg/machineproviders/types.go +++ b/pkg/machineproviders/types.go @@ -79,7 +79,7 @@ type MachineProvider interface { // WithClient is used to set API client for the Machine Provider. // It should not mutate the state of the existing provider but return // a copy of the provider with the new client. - WithClient(client client.Client) MachineProvider + WithClient(context.Context, logr.Logger, client.Client) (MachineProvider, error) // CreateMachine is used to instruct the Machine Provider to create a new Machine. The only input is the index for // the new Machine. During construction of the MachineProvider, it should map indexes to failure domains so that it From aee66ea0a0f5b084c244f86616616188b96398af Mon Sep 17 00:00:00 2001 From: Joel Speed Date: Wed, 21 Jun 2023 17:11:34 +0100 Subject: [PATCH 3/3] Add test to ensure data is only refreshed when the client is updated --- .../machine/v1beta1/provider_test.go | 258 ++++++++++++++---- 1 file changed, 210 insertions(+), 48 deletions(-) diff --git a/pkg/machineproviders/providers/openshift/machine/v1beta1/provider_test.go b/pkg/machineproviders/providers/openshift/machine/v1beta1/provider_test.go index 631e14253..d237d210a 100644 --- a/pkg/machineproviders/providers/openshift/machine/v1beta1/provider_test.go +++ b/pkg/machineproviders/providers/openshift/machine/v1beta1/provider_test.go @@ -89,6 +89,21 @@ var _ = Describe("MachineProvider", func() { }, } + usEast1aFailureDomainBuilder := machinev1resourcebuilder.AWSFailureDomain(). + WithAvailabilityZone("us-east-1a"). + WithSubnet(usEast1aSubnet) + usEast1aFailureDomain := usEast1aFailureDomainBuilder.Build() + + usEast1bFailureDomainBuilder := machinev1resourcebuilder.AWSFailureDomain(). + WithAvailabilityZone("us-east-1b"). + WithSubnet(usEast1bSubnet) + usEast1bFailureDomain := usEast1bFailureDomainBuilder.Build() + + usEast1cFailureDomainBuilder := machinev1resourcebuilder.AWSFailureDomain(). + WithAvailabilityZone("us-east-1c"). + WithSubnet(usEast1cSubnet) + usEast1cFailureDomain := usEast1cFailureDomainBuilder.Build() + usEast1aSubnetbeta1 := machinev1beta1.AWSResourceReference{ Filters: []machinev1beta1.Filter{ { @@ -122,6 +137,25 @@ var _ = Describe("MachineProvider", func() { }, } + usEast1dSubnetbeta1 := machinev1beta1.AWSResourceReference{ + Filters: []machinev1beta1.Filter{ + { + Name: "tag:Name", + Values: []string{ + "subnet-us-east-1d", + }, + }, + }, + } + + tmplBuilder := machinev1resourcebuilder.OpenShiftMachineV1Beta1Template(). + WithFailureDomainsBuilder(machinev1resourcebuilder.AWSFailureDomains().WithFailureDomainBuilders( + usEast1aFailureDomainBuilder, + usEast1bFailureDomainBuilder, + usEast1cFailureDomainBuilder, + )). + WithProviderSpecBuilder(machinev1beta1resourcebuilder.AWSProviderSpec()) + BeforeEach(OncePerOrdered, func() { By("Setting up a namespace for the test") ns := corev1resourcebuilder.Namespace().WithGenerateName("control-plane-machine-set-controller-").Build() @@ -138,6 +172,134 @@ var _ = Describe("MachineProvider", func() { ) }) + Context("NewProvider", func() { + var cpms *machinev1.ControlPlaneMachineSet + + masterMachineName := func(suffix string) string { + return fmt.Sprintf("%s-master-%s", resourcebuilder.TestClusterIDValue, suffix) + } + + BeforeEach(func() { + cpms = machinev1resourcebuilder.ControlPlaneMachineSet().WithNamespace(namespaceName).WithMachineTemplateBuilder(tmplBuilder).Build() + }, OncePerOrdered) + + Context("with a collection of unbalanced Machines", Ordered, func() { + var provider machineproviders.MachineProvider + var machineProvider *openshiftMachineProvider + providerSpecBuilder := machinev1beta1resourcebuilder.AWSProviderSpec() + masterMachineBuilder := machinev1beta1resourcebuilder.Machine().AsMaster().WithLabel(machinev1beta1.MachineClusterIDLabel, resourcebuilder.TestClusterIDValue).WithNamespace(namespaceName) + workerMachineBuilder := machinev1beta1resourcebuilder.Machine().AsWorker().WithLabel(machinev1beta1.MachineClusterIDLabel, resourcebuilder.TestClusterIDValue).WithNamespace(namespaceName) + + BeforeAll(func() { + machines := []*machinev1beta1.Machine{ + masterMachineBuilder.WithName(masterMachineName("0")).WithProviderSpecBuilder(providerSpecBuilder.WithAvailabilityZone("us-east-1a").WithSubnet(usEast1aSubnetbeta1)). + WithPhase("Running").WithNodeRef(corev1.ObjectReference{Name: "node-0"}).Build(), + masterMachineBuilder.WithName(masterMachineName("1")).WithProviderSpecBuilder(providerSpecBuilder.WithAvailabilityZone("us-east-1a").WithSubnet(usEast1aSubnetbeta1)). + WithPhase("Running").WithNodeRef(corev1.ObjectReference{Name: "node-1"}).Build(), + masterMachineBuilder.WithName(masterMachineName("2")).WithProviderSpecBuilder(providerSpecBuilder.WithAvailabilityZone("us-east-1a").WithSubnet(usEast1aSubnetbeta1)). + WithPhase("Running").WithNodeRef(corev1.ObjectReference{Name: "node-2"}).Build(), + workerMachineBuilder.WithName("worker-1").WithProviderSpecBuilder(providerSpecBuilder.WithAvailabilityZone("us-east-1d").WithSubnet(usEast1dSubnetbeta1)). + WithPhase("Running").WithNodeRef(corev1.ObjectReference{Name: "node-3"}).Build(), + } + + for _, machine := range machines { + machine.SetNamespace(namespaceName) + Expect(k8sClient.Create(ctx, machine)).To(Succeed()) + } + }) + + It("should build a provider from data in the cluster", func() { + var err error + provider, err = NewMachineProvider(ctx, logger.Logger(), k8sClient, cpms) + Expect(err).ToNot(HaveOccurred()) + Expect(provider).ToNot(BeNil()) + + Expect(provider).To(BeAssignableToTypeOf(&openshiftMachineProvider{})) + machineProvider, _ = provider.(*openshiftMachineProvider) + }) + + It("should correctly set the replicas", func() { + // This expectation is backwards so that gomega can dereference the pointer. + Expect(cpms.Spec.Replicas).To(HaveValue(Equal(machineProvider.replicas))) + }) + + It("should have cached a list of machines", func() { + Expect(machineProvider.machines).To(HaveLen(3)) + }) + + It("should have calculated the failure domains mapping", func() { + Expect(machineProvider.indexToFailureDomain).To(Equal( + map[int32]failuredomain.FailureDomain{ + 0: failuredomain.NewAWSFailureDomain(usEast1aFailureDomain), + 1: failuredomain.NewAWSFailureDomain(usEast1bFailureDomain), + 2: failuredomain.NewAWSFailureDomain(usEast1cFailureDomain), + }, + )) + }) + + Context("when a machine is deleted", func() { + BeforeAll(func() { + master0Machine := masterMachineBuilder.WithName(masterMachineName("0")).WithNamespace(namespaceName).Build() + Eventually(komega.Update(master0Machine, func() { + master0Machine.Finalizers = append(master0Machine.Finalizers, "machine.machine.openshift.io") + })).Should(Succeed()) + + Expect(k8sClient.Delete(ctx, master0Machine)).To(Succeed()) + }) + + It("should not know the machine is deleted", func() { + Consistently(func() ([]machineproviders.MachineInfo, error) { + info, err := provider.GetMachineInfos(ctx, logger.Logger()) + if err != nil { + return nil, fmt.Errorf("could not get machine info: %w", err) + } + + return info, nil + }).Should(ContainElement( + HaveField("MachineRef.ObjectMeta", SatisfyAll( + HaveField("Name", Equal(masterMachineName("0"))), + HaveField("DeletionTimestamp", BeNil()), + )), + )) + }) + + Context("and the machine data is refreshed", func() { + var refreshedProvider machineproviders.MachineProvider + var refreshedMachineProvider *openshiftMachineProvider + + BeforeAll(func() { + var err error + refreshedProvider, err = provider.WithClient(ctx, logger.Logger(), k8sClient) + Expect(err).ToNot(HaveOccurred()) + + Expect(refreshedProvider).To(BeAssignableToTypeOf(&openshiftMachineProvider{})) + refreshedMachineProvider, _ = refreshedProvider.(*openshiftMachineProvider) + }) + + It("should remap the failure domains based on the new machines", func() { + Expect(refreshedMachineProvider.indexToFailureDomain).To(Equal( + map[int32]failuredomain.FailureDomain{ + 0: failuredomain.NewAWSFailureDomain(usEast1bFailureDomain), + 1: failuredomain.NewAWSFailureDomain(usEast1aFailureDomain), + 2: failuredomain.NewAWSFailureDomain(usEast1cFailureDomain), + }, + )) + }) + + It("should know about the deleted machine", func() { + Expect(refreshedProvider.GetMachineInfos(ctx, logger.Logger())).To(ContainElement( + HaveField("MachineRef.ObjectMeta", SatisfyAll( + HaveField("Name", Equal(masterMachineName("0"))), + HaveField("DeletionTimestamp", Not(BeNil())), + )), + )) + }) + }) + }) + }) + + }) + Context("GetMachineInfos", func() { providerSpecBuilder := machinev1beta1resourcebuilder.AWSProviderSpec() masterMachineBuilder := machinev1beta1resourcebuilder.Machine().AsMaster().WithLabel(machinev1beta1.MachineClusterIDLabel, resourcebuilder.TestClusterIDValue).WithNamespace(namespaceName) @@ -265,9 +427,9 @@ var _ = Describe("MachineProvider", func() { WithPhase("Provisioned").Build(), }, failureDomains: map[int32]failuredomain.FailureDomain{ - 0: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1a").WithSubnet(usEast1aSubnet).Build()), - 1: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1b").WithSubnet(usEast1bSubnet).Build()), - 2: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1c").WithSubnet(usEast1cSubnet).Build()), + 0: failuredomain.NewAWSFailureDomain(usEast1aFailureDomain), + 1: failuredomain.NewAWSFailureDomain(usEast1bFailureDomain), + 2: failuredomain.NewAWSFailureDomain(usEast1cFailureDomain), }, expectedMachineInfos: []machineproviders.MachineInfo{ unreadyMachineInfoBuilder.WithIndex(0).WithMachineName(masterMachineName("0")).Build(), @@ -332,9 +494,9 @@ var _ = Describe("MachineProvider", func() { masterNodeBuilder.WithName("node-2").Build(), }, failureDomains: map[int32]failuredomain.FailureDomain{ - 0: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1a").WithSubnet(usEast1aSubnet).Build()), - 1: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1b").WithSubnet(usEast1bSubnet).Build()), - 2: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1c").WithSubnet(usEast1cSubnet).Build()), + 0: failuredomain.NewAWSFailureDomain(usEast1aFailureDomain), + 1: failuredomain.NewAWSFailureDomain(usEast1bFailureDomain), + 2: failuredomain.NewAWSFailureDomain(usEast1cFailureDomain), }, expectedMachineInfos: []machineproviders.MachineInfo{ readyMachineInfoBuilder.WithIndex(0).WithMachineName(masterMachineName("0")).WithNodeName("node-0").Build(), @@ -398,9 +560,9 @@ var _ = Describe("MachineProvider", func() { masterNodeBuilder.WithName("node-2").Build(), }, failureDomains: map[int32]failuredomain.FailureDomain{ - 0: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1a").WithSubnet(usEast1aSubnet).Build()), - 1: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1b").WithSubnet(usEast1bSubnet).Build()), - 2: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1c").WithSubnet(usEast1cSubnet).Build()), + 0: failuredomain.NewAWSFailureDomain(usEast1aFailureDomain), + 1: failuredomain.NewAWSFailureDomain(usEast1bFailureDomain), + 2: failuredomain.NewAWSFailureDomain(usEast1cFailureDomain), }, expectedMachineInfos: []machineproviders.MachineInfo{ readyMachineInfoBuilder.WithIndex(0).WithMachineName(masterMachineName("0")).WithNodeName("node-0").Build(), @@ -463,9 +625,9 @@ var _ = Describe("MachineProvider", func() { masterNodeBuilder.WithName("node-1").Build(), }, failureDomains: map[int32]failuredomain.FailureDomain{ - 0: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1a").WithSubnet(usEast1aSubnet).Build()), - 1: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1b").WithSubnet(usEast1bSubnet).Build()), - 2: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1c").WithSubnet(usEast1cSubnet).Build()), + 0: failuredomain.NewAWSFailureDomain(usEast1aFailureDomain), + 1: failuredomain.NewAWSFailureDomain(usEast1bFailureDomain), + 2: failuredomain.NewAWSFailureDomain(usEast1cFailureDomain), }, expectedMachineInfos: []machineproviders.MachineInfo{ readyMachineInfoBuilder.WithIndex(0).WithMachineName(masterMachineName("0")).WithNodeName("node-0").Build(), @@ -529,9 +691,9 @@ var _ = Describe("MachineProvider", func() { masterNodeBuilder.WithName("node-2").Build(), }, failureDomains: map[int32]failuredomain.FailureDomain{ - 0: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1a").WithSubnet(usEast1aSubnet).Build()), - 1: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1b").WithSubnet(usEast1bSubnet).Build()), - 2: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1c").WithSubnet(usEast1cSubnet).Build()), + 0: failuredomain.NewAWSFailureDomain(usEast1aFailureDomain), + 1: failuredomain.NewAWSFailureDomain(usEast1bFailureDomain), + 2: failuredomain.NewAWSFailureDomain(usEast1cFailureDomain), }, expectedMachineInfos: []machineproviders.MachineInfo{ readyMachineInfoBuilder.WithIndex(0).WithMachineName(masterMachineName("abcde-0")).WithNodeName("node-0").Build(), @@ -595,9 +757,9 @@ var _ = Describe("MachineProvider", func() { masterNodeBuilder.WithName("node-2").Build(), }, failureDomains: map[int32]failuredomain.FailureDomain{ - 0: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1a").WithSubnet(usEast1aSubnet).Build()), - 1: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1b").WithSubnet(usEast1bSubnet).Build()), - 2: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1c").WithSubnet(usEast1cSubnet).Build()), + 0: failuredomain.NewAWSFailureDomain(usEast1aFailureDomain), + 1: failuredomain.NewAWSFailureDomain(usEast1bFailureDomain), + 2: failuredomain.NewAWSFailureDomain(usEast1cFailureDomain), }, expectedMachineInfos: []machineproviders.MachineInfo{ readyMachineInfoBuilder.WithIndex(0).WithMachineName(masterMachineName("0")).WithNodeName("node-0").Build(), @@ -662,9 +824,9 @@ var _ = Describe("MachineProvider", func() { masterNodeBuilder.WithName("node-2").Build(), }, failureDomains: map[int32]failuredomain.FailureDomain{ - 0: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1a").WithSubnet(usEast1aSubnet).Build()), - 1: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1b").WithSubnet(usEast1bSubnet).Build()), - 2: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1c").WithSubnet(usEast1cSubnet).Build()), + 0: failuredomain.NewAWSFailureDomain(usEast1aFailureDomain), + 1: failuredomain.NewAWSFailureDomain(usEast1bFailureDomain), + 2: failuredomain.NewAWSFailureDomain(usEast1cFailureDomain), }, expectedMachineInfos: []machineproviders.MachineInfo{ readyMachineInfoBuilder.WithIndex(0).WithMachineName(masterMachineName("0")).WithNodeName("node-0"). @@ -740,9 +902,9 @@ var _ = Describe("MachineProvider", func() { masterNodeBuilder.WithName("node-replacement-2").Build(), }, failureDomains: map[int32]failuredomain.FailureDomain{ - 0: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1a").WithSubnet(usEast1aSubnet).Build()), - 1: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1b").WithSubnet(usEast1bSubnet).Build()), - 2: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1c").WithSubnet(usEast1cSubnet).Build()), + 0: failuredomain.NewAWSFailureDomain(usEast1aFailureDomain), + 1: failuredomain.NewAWSFailureDomain(usEast1bFailureDomain), + 2: failuredomain.NewAWSFailureDomain(usEast1cFailureDomain), }, expectedMachineInfos: []machineproviders.MachineInfo{ readyMachineInfoBuilder.WithIndex(0).WithMachineName(masterMachineName("0")).WithNodeName("node-0").Build(), @@ -826,9 +988,9 @@ var _ = Describe("MachineProvider", func() { failureDomains: map[int32]failuredomain.FailureDomain{ // The failure domain mapping logic is trusted as the source of truth for the failure domain. // It is responsible for mapping the machine indexes to failure domains. - 0: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1b").WithSubnet(usEast1bSubnet).Build()), - 1: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1c").WithSubnet(usEast1cSubnet).Build()), - 2: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1a").WithSubnet(usEast1aSubnet).Build()), + 0: failuredomain.NewAWSFailureDomain(usEast1bFailureDomain), + 1: failuredomain.NewAWSFailureDomain(usEast1cFailureDomain), + 2: failuredomain.NewAWSFailureDomain(usEast1aFailureDomain), }, expectedMachineInfos: []machineproviders.MachineInfo{ readyMachineInfoBuilder.WithIndex(0).WithMachineName(masterMachineName("0")).WithNodeName("node-0").WithNeedsUpdate(true).WithDiff( @@ -916,9 +1078,9 @@ var _ = Describe("MachineProvider", func() { masterNodeBuilder.WithName("node-2").Build(), }, failureDomains: map[int32]failuredomain.FailureDomain{ - 0: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1b").WithSubnet(usEast1bSubnet).Build()), - 1: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1c").WithSubnet(usEast1cSubnet).Build()), - 2: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1a").WithSubnet(usEast1aSubnet).Build()), + 0: failuredomain.NewAWSFailureDomain(usEast1bFailureDomain), + 1: failuredomain.NewAWSFailureDomain(usEast1cFailureDomain), + 2: failuredomain.NewAWSFailureDomain(usEast1aFailureDomain), }, expectedMachineInfos: []machineproviders.MachineInfo{ readyMachineInfoBuilder.WithIndex(0).WithMachineName(resourcebuilder.TestClusterIDValue + "-machine-0").WithNodeName("node-0").Build(), @@ -982,9 +1144,9 @@ var _ = Describe("MachineProvider", func() { masterNodeBuilder.WithName("node-2").Build(), }, failureDomains: map[int32]failuredomain.FailureDomain{ - 0: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1b").WithSubnet(usEast1bSubnet).Build()), - 1: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1c").WithSubnet(usEast1cSubnet).Build()), - 2: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1a").WithSubnet(usEast1aSubnet).Build()), + 0: failuredomain.NewAWSFailureDomain(usEast1bFailureDomain), + 1: failuredomain.NewAWSFailureDomain(usEast1cFailureDomain), + 2: failuredomain.NewAWSFailureDomain(usEast1aFailureDomain), }, expectedError: errCouldNotDetermineMachineIndex, expectedMachineInfos: []machineproviders.MachineInfo{}, @@ -1009,9 +1171,9 @@ var _ = Describe("MachineProvider", func() { masterNodeBuilder.WithName("node-2").Build(), }, failureDomains: map[int32]failuredomain.FailureDomain{ - 0: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1a").WithSubnet(usEast1aSubnet).Build()), - 1: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1b").WithSubnet(usEast1bSubnet).Build()), - 2: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1c").WithSubnet(usEast1cSubnet).Build()), + 0: failuredomain.NewAWSFailureDomain(usEast1aFailureDomain), + 1: failuredomain.NewAWSFailureDomain(usEast1bFailureDomain), + 2: failuredomain.NewAWSFailureDomain(usEast1cFailureDomain), }, expectedMachineInfos: []machineproviders.MachineInfo{ unreadyMachineInfoBuilder.WithIndex(0).WithMachineName(masterMachineName("0")).WithReady(false).WithErrorMessage("Node missing").WithNodeName("node-0").Build(), @@ -1075,9 +1237,9 @@ var _ = Describe("MachineProvider", func() { masterNodeBuilder.WithName("node-2").Build(), }, failureDomains: map[int32]failuredomain.FailureDomain{ - 0: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1a").WithSubnet(usEast1aSubnet).Build()), - 1: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1b").WithSubnet(usEast1bSubnet).Build()), - 2: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1c").WithSubnet(usEast1cSubnet).Build()), + 0: failuredomain.NewAWSFailureDomain(usEast1aFailureDomain), + 1: failuredomain.NewAWSFailureDomain(usEast1bFailureDomain), + 2: failuredomain.NewAWSFailureDomain(usEast1cFailureDomain), }, expectedMachineInfos: []machineproviders.MachineInfo{ readyMachineInfoBuilder.WithIndex(0).WithMachineName(masterMachineName("0")).WithNodeName("node-0").Build(), @@ -1275,9 +1437,9 @@ var _ = Describe("MachineProvider", func() { masterNodeBuilder.WithName("node-5").Build(), }, failureDomains: map[int32]failuredomain.FailureDomain{ - 3: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1a").WithSubnet(usEast1aSubnet).Build()), - 4: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1b").WithSubnet(usEast1bSubnet).Build()), - 5: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1c").WithSubnet(usEast1cSubnet).Build()), + 3: failuredomain.NewAWSFailureDomain(usEast1aFailureDomain), + 4: failuredomain.NewAWSFailureDomain(usEast1bFailureDomain), + 5: failuredomain.NewAWSFailureDomain(usEast1cFailureDomain), }, expectedMachineInfos: []machineproviders.MachineInfo{ readyMachineInfoBuilder.WithIndex(3).WithMachineName(masterMachineName("3")).WithNodeName("node-3").Build(), @@ -1341,9 +1503,9 @@ var _ = Describe("MachineProvider", func() { masterNodeBuilder.WithName("node-4").Build(), }, failureDomains: map[int32]failuredomain.FailureDomain{ - 0: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1a").WithSubnet(usEast1aSubnet).Build()), - 2: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1b").WithSubnet(usEast1bSubnet).Build()), - 4: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1c").WithSubnet(usEast1cSubnet).Build()), + 0: failuredomain.NewAWSFailureDomain(usEast1aFailureDomain), + 2: failuredomain.NewAWSFailureDomain(usEast1bFailureDomain), + 4: failuredomain.NewAWSFailureDomain(usEast1cFailureDomain), }, expectedMachineInfos: []machineproviders.MachineInfo{ readyMachineInfoBuilder.WithIndex(0).WithMachineName(masterMachineName("0")).WithNodeName("node-0").Build(), @@ -1506,9 +1668,9 @@ var _ = Describe("MachineProvider", func() { provider = &openshiftMachineProvider{ client: k8sClient, indexToFailureDomain: map[int32]failuredomain.FailureDomain{ - 0: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1a").WithSubnet(usEast1aSubnet).Build()), - 1: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1b").WithSubnet(usEast1bSubnet).Build()), - 2: failuredomain.NewAWSFailureDomain(machinev1resourcebuilder.AWSFailureDomain().WithAvailabilityZone("us-east-1c").WithSubnet(usEast1cSubnet).Build()), + 0: failuredomain.NewAWSFailureDomain(usEast1aFailureDomain), + 1: failuredomain.NewAWSFailureDomain(usEast1bFailureDomain), + 2: failuredomain.NewAWSFailureDomain(usEast1cFailureDomain), }, machineSelector: selector, machineTemplate: *template.OpenShiftMachineV1Beta1Machine,