diff --git a/README.md b/README.md index 652c469a..becde386 100644 --- a/README.md +++ b/README.md @@ -181,15 +181,15 @@ Create a base RHEL data volume prior to deploying OpenStack. This will be used - macPrefix: fa:16:3b name: datacentre2 # optional: configure static mapping for the networks per nodes. If there is none, a random gets created - staticReservations: - controller-0: - reservations: - datacentre: fa:16:3a:aa:aa:aa - datacentre2: fa:16:3b:aa:aa:aa - compute-0: - reservations: - datacentre: fa:16:3a:bb:bb:bb - datacentre2: fa:16:3b:bb:bb:bb + reservations: + controller-0: + macReservations: + datacentre: fa:16:3a:aa:aa:aa + datacentre2: fa:16:3b:aa:aa:aa + compute-0: + macReservations: + datacentre: fa:16:3a:bb:bb:bb + datacentre2: fa:16:3b:bb:bb:bb ``` If you write the above YAML into a file called networkconfig.yaml you can create the OpenStackNetConfig via this command: @@ -842,7 +842,6 @@ oc patch osbms computehci --type=merge --patch '{"spec":{"count":1}}' ``` As a result: -* the corresponding OSIPSet for the node gets deleted * the IPreservation entry in the OSNet resources gets flagged as deleted ```bash @@ -915,7 +914,6 @@ oc patch osctlplane overcloud --type=merge --patch '{"spec":{"virtualMachineRole ``` As a result: -* the corresponding OSIPSet for the node got deleted * the IPreservation entry in the OSNet resources is flagged as deleted This results in the following behavior @@ -1559,7 +1557,7 @@ If required it is possible to change CPU/RAM of an openstackvmset configured via * change/patch the virtualMachineRole within the virtualMachineRoles list of the openstackcontrolplane CR -E.g. to change the controller virtualMachineRole to have 8 cores and 21GB of RAM: +E.g. to change the controller virtualMachineRole to have 8 cores and 22GB of RAM: ```bash oc patch -n openstack osctlplane overcloud --type='json' -p='[{"op": "add", "path": "/spec/virtualMachineRoles/controller/cores", "value": 8 }]' diff --git a/api/v1beta1/common_types.go b/api/v1beta1/common_types.go index 9f9e1aa2..b79b2183 100644 --- a/api/v1beta1/common_types.go +++ b/api/v1beta1/common_types.go @@ -254,7 +254,7 @@ func (conditions ConditionList) InitCondition() *Condition { } } - return cond + return cond.DeepCopy() } // GetCurrentCondition - Get current condition with status == corev1.ConditionTrue diff --git a/api/v1beta1/openstackephemeralheat_types.go b/api/v1beta1/openstackephemeralheat_types.go index 3d1d8b85..8040fba2 100644 --- a/api/v1beta1/openstackephemeralheat_types.go +++ b/api/v1beta1/openstackephemeralheat_types.go @@ -41,8 +41,36 @@ type OpenStackEphemeralHeatSpec struct { type OpenStackEphemeralHeatStatus struct { // Active hash Active bool `json:"active"` + + // Conditions - conditions to display in the OpenShift GUI, which reflect CurrentState + Conditions ConditionList `json:"conditions,omitempty" optional:"true"` } +const ( + // + // condition reasons + // + + // EphemeralHeatCondGenPassSecretError - error generating password secret + EphemeralHeatCondGenPassSecretError ConditionReason = "EphemeralHeatCondGenPassSecretError" + // EphemeralHeatCondWaitOnPassSecret - waiting for the generated password secret to populate + EphemeralHeatCondWaitOnPassSecret ConditionReason = "EphemeralHeatCondWaitOnPassSecret" + // EphemeralHeatCondMariaDBError - error creating/updating MariaDB pod or service + EphemeralHeatCondMariaDBError ConditionReason = "EphemeralHeatCondMariaDBError" + // EphemeralHeatCondWaitOnMariaDB - waiting for MariaDB pod to be ready + EphemeralHeatCondWaitOnMariaDB ConditionReason = "EphemeralHeatCondWaitOnMariaDB" + // EphemeralHeatCondRabbitMQError - error creating/updating RabbitMQ pod or service + EphemeralHeatCondRabbitMQError ConditionReason = "EphemeralHeatCondRabbitMQError" + // EphemeralHeatCondWaitOnRabbitMQ - waiting for RabbitMQ pod to be ready + EphemeralHeatCondWaitOnRabbitMQ ConditionReason = "EphemeralHeatCondWaitOnRabbitMQ" + // EphemeralHeatCondHeatError - error creating/updating Heat pod or service + EphemeralHeatCondHeatError ConditionReason = "EphemeralHeatCondHeatError" + // EphemeralHeatCondWaitOnHeat - waiting for Heat pod to be ready + EphemeralHeatCondWaitOnHeat ConditionReason = "EphemeralHeatCondWaitOnHeat" + // EphemeralHeatReady - Heat is available for use + EphemeralHeatReady ConditionReason = "EphemeralHeatReady" +) + // +kubebuilder:object:root=true // +kubebuilder:subresource:status // +kubebuilder:resource:shortName=osephemeralheat;osephemeralheats diff --git a/api/v1beta1/openstacknetconfig_types.go b/api/v1beta1/openstacknetconfig_types.go index a44fb3cc..fa71ce0a 100644 --- a/api/v1beta1/openstacknetconfig_types.go +++ b/api/v1beta1/openstacknetconfig_types.go @@ -104,12 +104,6 @@ type Network struct { // +kubebuilder:default=true // VIP create virtual ip on the network VIP bool `json:"vip"` - - /* - // +kubebuilder:validation:Optional - // StaticReservations, manual/static IP address reservations per node - StaticReservations map[string]OpenStackMACNodeReservation `json:"staticReservations"` - */ } // OpenStackNetConfigSpec defines the desired state of OpenStackNetConfig @@ -151,6 +145,21 @@ type OpenStackNetConfigSpec struct { // but the role itself is not deleted. The reservations of all nodes in the role get deleted when the full node // role is being deleted. (default: true) PreserveReservations *bool `json:"preserveReservations"` + + // +kubebuilder:validation:Optional + // Reservations, manual/static MAC/IP address reservations per node + Reservations map[string]OpenStackNetStaticNodeReservations `json:"reservations"` +} + +// OpenStackNetStaticNodeReservations defines the static reservations of the nodes +type OpenStackNetStaticNodeReservations struct { + // +kubebuilder:validation:Optional + // IPReservations, manual/static IP address reservations per network + IPReservations map[string]string `json:"ipReservations"` + + // +kubebuilder:validation:Optional + // MACReservations, manual/static MAC address reservations per physnet + MACReservations map[string]string `json:"macReservations"` } // OVNBridgeMacMappingConfig defines the desired state of OpenStackMACAddress @@ -158,10 +167,6 @@ type OVNBridgeMacMappingConfig struct { // +kubebuilder:validation:MinItems=1 // PhysNetworks - physical networks list to create MAC addresses per physnet per node to create OVNStaticBridgeMacMappings PhysNetworks []Physnet `json:"physNetworks"` - - // +kubebuilder:validation:Optional - // StaticReservations, manual/static MAC address reservations per node - StaticReservations map[string]OpenStackMACNodeReservation `json:"staticReservations"` } // OpenStackNetConfigStatus defines the observed state of OpenStackNetConfig diff --git a/api/v1beta1/openstacknetconfig_webhook.go b/api/v1beta1/openstacknetconfig_webhook.go index 48619517..6c52d2fc 100644 --- a/api/v1beta1/openstacknetconfig_webhook.go +++ b/api/v1beta1/openstacknetconfig_webhook.go @@ -17,12 +17,14 @@ limitations under the License. package v1beta1 import ( + "context" "fmt" "net" nmstate "github.com/openstack-k8s-operators/osp-director-operator/pkg/nmstate" "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/webhook" ) @@ -32,6 +34,11 @@ var openstacknetconfiglog = logf.Log.WithName("openstacknetconfig-resource") // SetupWebhookWithManager - register this webhook with the controller manager func (r *OpenStackNetConfig) SetupWebhookWithManager(mgr ctrl.Manager) error { + + if webhookClient == nil { + webhookClient = mgr.GetClient() + } + return ctrl.NewWebhookManagedBy(mgr). For(r). Complete() @@ -78,8 +85,20 @@ func (r *OpenStackNetConfig) Default() { }, } } - if r.Spec.OVNBridgeMacMappings.StaticReservations == nil { - r.Spec.OVNBridgeMacMappings.StaticReservations = map[string]OpenStackMACNodeReservation{} + + if r.Spec.Reservations == nil { + r.Spec.Reservations = map[string]OpenStackNetStaticNodeReservations{} + } else { + for node, res := range r.Spec.Reservations { + if res.IPReservations == nil { + res.IPReservations = map[string]string{} + } + if res.MACReservations == nil { + res.MACReservations = map[string]string{} + } + + r.Spec.Reservations[node] = res + } } if r.Spec.PreserveReservations == nil { @@ -126,6 +145,14 @@ func (r *OpenStackNetConfig) ValidateCreate() error { return err } + // + // Validate static IP address reservations + // + err = r.validateStaticIPReservations() + if err != nil { + return err + } + // // Validate static MAC address reservations // @@ -149,6 +176,14 @@ func (r *OpenStackNetConfig) ValidateUpdate(old runtime.Object) error { return err } + // + // Validate static IP address reservations + // + err = r.validateStaticIPReservations() + if err != nil { + return err + } + // // Validate static MAC address reservations // @@ -222,8 +257,8 @@ func (r *OpenStackNetConfig) validateStaticMacReservations(old runtime.Object) e // fill an empty reservations map to check for uniq MAC reservations reservations := map[string]OpenStackMACNodeReservation{} - for node, res := range r.Spec.OVNBridgeMacMappings.StaticReservations { - for physnet, mac := range res.Reservations { + for node, res := range r.Spec.Reservations { + for physnet, mac := range res.MACReservations { // // check if the MAC address has a valid format // @@ -247,14 +282,113 @@ func (r *OpenStackNetConfig) validateStaticMacReservations(old runtime.Object) e if oldInstance, ok = old.(*OpenStackNetConfig); !ok { return fmt.Errorf("runtime object is not an OpenStackNetConfig") } - if currentMAC, ok := oldInstance.Spec.OVNBridgeMacMappings.StaticReservations[node].Reservations[physnet]; ok && currentMAC != mac { + if currentMAC, ok := oldInstance.Spec.Reservations[node].MACReservations[physnet]; ok && currentMAC != mac { return fmt.Errorf("MAC address %s of node %s must not change - new MAC address %s", currentMAC, node, mac) } } } // if all tests pass add to reservations - reservations[node] = res + reservations[node] = OpenStackMACNodeReservation{ + Reservations: res.MACReservations, + } } + + return nil +} + +// validateStaticIPReservations - validate static IP address reservations +func (r *OpenStackNetConfig) validateStaticIPReservations() error { + // fill an empty reservations map to check for uniq IP reservations + reservations := map[string]string{} + + // + // Create nested map with per net, ip -> node name reservations + // + osNetList := &OpenStackNetList{} + + listOpts := []client.ListOption{ + client.InNamespace(r.Namespace), + } + + if err := webhookClient.List(context.TODO(), osNetList, listOpts...); err != nil { + return err + } + + netReservations := map[string]map[string]string{} + for _, osNet := range osNetList.Items { + if netReservations[osNet.Spec.NameLower] == nil { + netReservations[osNet.Spec.NameLower] = map[string]string{} + } + for node, res := range osNet.Status.Reservations { + netReservations[osNet.Spec.NameLower][res.IP] = node + } + } + + // + // verify all the Spec.Reservations provided + // + for node, res := range r.Spec.Reservations { + for netName, resIP := range res.IPReservations { + // + // check if the IP address has a valid format + // + ip := net.ParseIP(resIP) + if ip == nil { + return fmt.Errorf("IP address %s of node %s has an invalid format", resIP, node) + } + + // + // check if IP matches osnet spec + // + for _, osNet := range r.Spec.Networks { + for _, subnet := range osNet.Subnets { + if subnet.Name == netName { + var ipnet *net.IPNet + if subnet.IPv4.Cidr != "" { + _, ipnet, _ = net.ParseCIDR(subnet.IPv4.Cidr) + } else { + _, ipnet, _ = net.ParseCIDR(subnet.IPv6.Cidr) + } + + if !ipnet.Contains(ip) { + return fmt.Errorf("IP address %s of node %s conflicts with subnet %s definition %s", + resIP, + node, + netName, + ipnet.Network(), + ) + } + } + } + } + + // + // check for duplicate reservations on static reservations + // + if resNode, ok := reservations[resIP]; ok && resNode != node { + return fmt.Errorf("IP address %s of node %s is not uniq. Already used by %s", + resIP, + node, + resNode, + ) + } + + // + // check for duplicate reservations on all active reservations + // + if resNode, ok := netReservations[netName][resIP]; ok && resNode != node { + return fmt.Errorf("IP address %s of node %s is not uniq. Already used by %s", + resIP, + node, + resNode, + ) + } + + // if all tests pass add to reservations + reservations[resIP] = node + } + } + return nil } diff --git a/api/v1beta1/openstackprovisionserver_types.go b/api/v1beta1/openstackprovisionserver_types.go index 16753b1f..f938ace3 100644 --- a/api/v1beta1/openstackprovisionserver_types.go +++ b/api/v1beta1/openstackprovisionserver_types.go @@ -69,17 +69,29 @@ const ( ProvisionServerCondTypeError ProvisioningState = "Error" // - // condition reasones + // condition reasons // // OpenStackProvisionServerCondReasonListError - osprovserver list objects error OpenStackProvisionServerCondReasonListError ConditionReason = "OpenStackProvisionServerListError" + // OpenStackProvisionServerCondReasonGetError - osprovserver list objects error + OpenStackProvisionServerCondReasonGetError ConditionReason = "OpenStackProvisionServerCondReasonGetError" // OpenStackProvisionServerCondReasonNotFound - osprovserver object not found OpenStackProvisionServerCondReasonNotFound ConditionReason = "OpenStackProvisionServerNotFound" - // OpenStackProvisionServerCondReasonNotReady - osprovserver not yet ready - OpenStackProvisionServerCondReasonNotReady ConditionReason = "OpenStackProvisionServerNotReady" - // OpenStackProvisionServerCondReasonReady - osprovserver ready - OpenStackProvisionServerCondReasonReady ConditionReason = "OpenStackProvisionServerReady" + // OpenStackProvisionServerCondReasonInterfaceAcquireError - osprovserver hit an error while finding provisioning interface name + OpenStackProvisionServerCondReasonInterfaceAcquireError ConditionReason = "OpenStackProvisionServerCondReasonInterfaceAcquireError" + // OpenStackProvisionServerCondReasonInterfaceNotFound - osprovserver unable to find provisioning interface name + OpenStackProvisionServerCondReasonInterfaceNotFound ConditionReason = "OpenStackProvisionServerCondReasonInterfaceNotFound" + // OpenStackProvisionServerCondReasonDeploymentError - osprovserver associated deployment failed to create/update + OpenStackProvisionServerCondReasonDeploymentError ConditionReason = "OpenStackProvisionServerCondReasonDeploymentError" + // OpenStackProvisionServerCondReasonDeploymentCreated - osprovserver associated deployment has been created/update + OpenStackProvisionServerCondReasonDeploymentCreated ConditionReason = "OpenStackProvisionServerCondReasonDeploymentCreated" + // OpenStackProvisionServerCondReasonProvisioning - osprovserver associated pod is provisioning + OpenStackProvisionServerCondReasonProvisioning ConditionReason = "OpenStackProvisionServerCondReasonProvisioning" + // OpenStackProvisionServerCondReasonLocalImageURLParseError - osprovserver was unable to parse its received local image URL + OpenStackProvisionServerCondReasonLocalImageURLParseError ConditionReason = "OpenStackProvisionServerCondReasonLocalImageURLParseError" + // OpenStackProvisionServerCondReasonProvisioned - osprovserver associated pod is provisioned + OpenStackProvisionServerCondReasonProvisioned ConditionReason = "OpenStackProvisionServerCondReasonProvisioned" // OpenStackProvisionServerCondReasonCreateError - error creating osprov server object OpenStackProvisionServerCondReasonCreateError ConditionReason = "OpenStackProvisionServerCreateError" // OpenStackProvisionServerCondReasonCreated - osprov server object created diff --git a/api/v1beta1/openstackvmset_types.go b/api/v1beta1/openstackvmset_types.go index f3645212..9c8fc287 100644 --- a/api/v1beta1/openstackvmset_types.go +++ b/api/v1beta1/openstackvmset_types.go @@ -159,7 +159,7 @@ const ( // VMSetCondReasonVirtualMachineDeprovisioning - virtual machine deprovisioning in progress VMSetCondReasonVirtualMachineDeprovisioning ConditionReason = "VirtualMachineDeprovisioning" // VMSetCondReasonVirtualMachineProvisioned - virtual machines provisioned - VMSetCondReasonVirtualMachineProvisioned ConditionReason = "VirtualMachineProvisioed" + VMSetCondReasonVirtualMachineProvisioned ConditionReason = "VirtualMachineProvisioned" // VMSetCondReasonVirtualMachineCountZero - no virtual machines requested VMSetCondReasonVirtualMachineCountZero ConditionReason = "VirtualMachineCountZero" diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 213f0f5a..2bab2ca1 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -446,13 +446,6 @@ func (in *OVNBridgeMacMappingConfig) DeepCopyInto(out *OVNBridgeMacMappingConfig *out = make([]Physnet, len(*in)) copy(*out, *in) } - if in.StaticReservations != nil { - in, out := &in.StaticReservations, &out.StaticReservations - *out = make(map[string]OpenStackMACNodeReservation, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OVNBridgeMacMappingConfig. @@ -1287,7 +1280,7 @@ func (in *OpenStackEphemeralHeat) DeepCopyInto(out *OpenStackEphemeralHeat) { out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) out.Spec = in.Spec - out.Status = in.Status + in.Status.DeepCopyInto(&out.Status) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackEphemeralHeat. @@ -1373,6 +1366,13 @@ func (in *OpenStackEphemeralHeatSpec) DeepCopy() *OpenStackEphemeralHeatSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OpenStackEphemeralHeatStatus) DeepCopyInto(out *OpenStackEphemeralHeatStatus) { *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(ConditionList, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackEphemeralHeatStatus. @@ -1804,6 +1804,13 @@ func (in *OpenStackNetConfigSpec) DeepCopyInto(out *OpenStackNetConfigSpec) { *out = new(bool) **out = **in } + if in.Reservations != nil { + in, out := &in.Reservations, &out.Reservations + *out = make(map[string]OpenStackNetStaticNodeReservations, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackNetConfigSpec. @@ -1945,6 +1952,35 @@ func (in *OpenStackNetSpec) DeepCopy() *OpenStackNetSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenStackNetStaticNodeReservations) DeepCopyInto(out *OpenStackNetStaticNodeReservations) { + *out = *in + if in.IPReservations != nil { + in, out := &in.IPReservations, &out.IPReservations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.MACReservations != nil { + in, out := &in.MACReservations, &out.MACReservations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackNetStaticNodeReservations. +func (in *OpenStackNetStaticNodeReservations) DeepCopy() *OpenStackNetStaticNodeReservations { + if in == nil { + return nil + } + out := new(OpenStackNetStaticNodeReservations) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OpenStackNetStatus) DeepCopyInto(out *OpenStackNetStatus) { *out = *in diff --git a/config/crd/bases/osp-director.openstack.org_openstackbackups.yaml b/config/crd/bases/osp-director.openstack.org_openstackbackups.yaml index 6ad79c50..acfdfe08 100644 --- a/config/crd/bases/osp-director.openstack.org_openstackbackups.yaml +++ b/config/crd/bases/osp-director.openstack.org_openstackbackups.yaml @@ -1955,28 +1955,6 @@ spec: type: object minItems: 1 type: array - staticReservations: - additionalProperties: - description: OpenStackMACNodeReservation defines - the observed state of the MAC addresses - per PhysNetworks - properties: - deleted: - description: Deleted - node and therefore - MAC reservation are flagged as deleted - type: boolean - reservations: - additionalProperties: - type: string - description: Reservations MAC reservations - per PhysNetwork - type: object - required: - - reservations - type: object - description: StaticReservations, manual/static - MAC address reservations per node - type: object required: - physNetworks type: object @@ -1989,6 +1967,27 @@ spec: in the role get deleted when the full node role is being deleted. (default: true)' type: boolean + reservations: + additionalProperties: + description: OpenStackNetStaticNodeReservations + defines the static reservations of the nodes + properties: + ipReservations: + additionalProperties: + type: string + description: IPReservations, manual/static + IP address reservations per network + type: object + macReservations: + additionalProperties: + type: string + description: MACReservations, manual/static + MAC address reservations per physnet + type: object + type: object + description: Reservations, manual/static MAC/IP + address reservations per node + type: object required: - attachConfigurations - networks diff --git a/config/crd/bases/osp-director.openstack.org_openstackephemeralheats.yaml b/config/crd/bases/osp-director.openstack.org_openstackephemeralheats.yaml index c6dbb2d7..9806e958 100644 --- a/config/crd/bases/osp-director.openstack.org_openstackephemeralheats.yaml +++ b/config/crd/bases/osp-director.openstack.org_openstackephemeralheats.yaml @@ -78,6 +78,36 @@ spec: active: description: Active hash type: boolean + conditions: + description: Conditions - conditions to display in the OpenShift GUI, + which reflect CurrentState + items: + description: Condition - A particular overall condition of a certain + resource + properties: + lastHearbeatTime: + format: date-time + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + description: ConditionReason - Why a particular condition is + true, false or unknown + type: string + status: + type: string + type: + description: ConditionType - A summarizing name for a given + condition + type: string + required: + - status + - type + type: object + type: array required: - active type: object diff --git a/config/crd/bases/osp-director.openstack.org_openstacknetconfigs.yaml b/config/crd/bases/osp-director.openstack.org_openstacknetconfigs.yaml index b21be4d4..2170cd5e 100644 --- a/config/crd/bases/osp-director.openstack.org_openstacknetconfigs.yaml +++ b/config/crd/bases/osp-director.openstack.org_openstacknetconfigs.yaml @@ -323,26 +323,6 @@ spec: type: object minItems: 1 type: array - staticReservations: - additionalProperties: - description: OpenStackMACNodeReservation defines the observed - state of the MAC addresses per PhysNetworks - properties: - deleted: - description: Deleted - node and therefore MAC reservation - are flagged as deleted - type: boolean - reservations: - additionalProperties: - type: string - description: Reservations MAC reservations per PhysNetwork - type: object - required: - - reservations - type: object - description: StaticReservations, manual/static MAC address reservations - per node - type: object required: - physNetworks type: object @@ -354,6 +334,27 @@ spec: role get deleted when the full node role is being deleted. (default: true)' type: boolean + reservations: + additionalProperties: + description: OpenStackNetStaticNodeReservations defines the static + reservations of the nodes + properties: + ipReservations: + additionalProperties: + type: string + description: IPReservations, manual/static IP address reservations + per network + type: object + macReservations: + additionalProperties: + type: string + description: MACReservations, manual/static MAC address reservations + per physnet + type: object + type: object + description: Reservations, manual/static MAC/IP address reservations + per node + type: object required: - attachConfigurations - networks diff --git a/config/samples/osp-director_v1beta1_openstacknetconfig.yaml b/config/samples/osp-director_v1beta1_openstacknetconfig.yaml index 446104d2..e2c36a49 100644 --- a/config/samples/osp-director_v1beta1_openstacknetconfig.yaml +++ b/config/samples/osp-director_v1beta1_openstacknetconfig.yaml @@ -110,17 +110,56 @@ spec: name: datacentre - macPrefix: fa:16:3b name: datacentre2 - staticReservations: - controller-0: - reservations: - datacentre: fa:16:3a:aa:aa:aa - datacentre2: fa:16:3b:aa:aa:aa - controller-1: - reservations: - datacentre: fa:16:3a:aa:aa:bb - datacentre2: fa:16:3b:aa:aa:bb - compute-0: - reservations: - datacentre: fa:16:3a:bb:bb:bb - datacentre2: fa:16:3b:bb:bb:bb preserveReservations: true + reservations: + compute-0: + ipReservations: + ctlplane: 192.168.25.40 + internal_api: 172.17.0.40 + storage: 172.18.0.40 + tenant: 172.20.0.40 + macReservations: + datacentre: fa:16:3a:bb:bb:bb + datacentre2: fa:16:3b:bb:bb:bb + controller-0: + ipReservations: + ctlplane: 192.168.25.20 + external: 10.0.0.20 + internal_api: 172.17.0.20 + storage: 172.18.0.20 + storage_mgmt: 172.19.0.20 + tenant: 172.20.0.20 + macReservations: + datacentre: fa:16:3a:aa:aa:aa + datacentre2: fa:16:3b:aa:aa:aa + controller-1: + ipReservations: + ctlplane: 192.168.25.21 + external: 10.0.0.21 + internal_api: 172.17.0.21 + storage: 172.18.0.21 + storage_mgmt: 172.19.0.21 + tenant: 172.20.0.21 + macReservations: + datacentre: fa:16:3a:aa:aa:bb + datacentre2: fa:16:3b:aa:aa:bb + controller-2: + ipReservations: + ctlplane: 192.168.25.22 + external: 10.0.0.22 + internal_api: 172.17.0.22 + storage: 172.18.0.22 + storage_mgmt: 172.19.0.22 + tenant: 172.20.0.22 + controlplane: + ipReservations: + ctlplane: 192.168.25.10 + external: 10.0.0.10 + internal_api: 172.17.0.10 + storage: 172.18.0.10 + storage_mgmt: 172.19.0.10 + openstackclient-0: + ipReservations: + ctlplane: 192.168.25.251 + external: 10.0.0.251 + internal_api: 172.17.0.251 diff --git a/config/samples/osp-director_v1beta1_openstacknetconfig_single_net.yaml b/config/samples/osp-director_v1beta1_openstacknetconfig_single_net.yaml index 6973ed77..044b4279 100644 --- a/config/samples/osp-director_v1beta1_openstacknetconfig_single_net.yaml +++ b/config/samples/osp-director_v1beta1_openstacknetconfig_single_net.yaml @@ -32,3 +32,10 @@ spec: cidr: 192.168.25.0/24 gateway: 192.168.25.1 attachConfiguration: br-osp + reservations: + controlplane: + ipReservations: + ctlplane: 192.168.25.10 + openstackclient-0: + ipReservations: + ctlplane: 192.168.25.251 diff --git a/config/samples/osp-director_v1beta1_openstacknetconfig_single_net_ipv6.yaml b/config/samples/osp-director_v1beta1_openstacknetconfig_single_net_ipv6.yaml new file mode 100644 index 00000000..9b3e6a04 --- /dev/null +++ b/config/samples/osp-director_v1beta1_openstacknetconfig_single_net_ipv6.yaml @@ -0,0 +1,41 @@ +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNetConfig +metadata: + name: openstacknetconfig +spec: + attachConfigurations: + br-osp: + nodeNetworkConfigurationPolicy: + nodeSelector: + node-role.kubernetes.io/worker: "" + desiredState: + interfaces: + - bridge: + options: + stp: + enabled: false + port: + - name: enp7s0 + description: Linux bridge with enp7s0 as a port + name: br-osp + state: up + type: linux-bridge + mtu: 1500 + networks: + - name: Control + nameLower: ctlplane + subnets: + - name: ctlplane + ipv6: + cidr: 2001:db8:fd00:2000::/64 + gateway: 2001:db8:fd00:2000::1 + allocationEnd: 2001:db8:fd00:2000:ffff:ffff:ffff:fffe + allocationStart: 2001:db8:fd00:2000::100 + attachConfiguration: br-osp + reservations: + controlplane: + ipReservations: + ctlplane: 2001:db8:fd00:2000::10 + openstackclient-0: + ipReservations: + ctlplane: 2001:db8:fd00:2000::251 diff --git a/controllers/openstackbaremetalset_controller.go b/controllers/openstackbaremetalset_controller.go index 66b16419..b02cb133 100644 --- a/controllers/openstackbaremetalset_controller.go +++ b/controllers/openstackbaremetalset_controller.go @@ -232,11 +232,17 @@ func (r *OpenStackBaremetalSetReconciler) Reconcile(ctx context.Context, req ctr } var ctrlResult reconcile.Result + currentLabels := instance.DeepCopy().Labels // // add osnetcfg CR label reference which is used in the in the osnetcfg // controller to watch this resource and reconcile // - ctrlResult, err = openstacknetconfig.AddOSNetConfigRefLabel(r, instance, cond, instance.Spec.Networks[0]) + instance.Labels, ctrlResult, err = openstacknetconfig.AddOSNetConfigRefLabel( + r, + instance, + cond, + instance.Spec.Networks[0], + ) if (err != nil) || (ctrlResult != ctrl.Result{}) { return ctrlResult, err } @@ -244,9 +250,25 @@ func (r *OpenStackBaremetalSetReconciler) Reconcile(ctx context.Context, req ctr // // add labels of all networks used by this CR // - err = openstacknet.AddOSNetNameLowerLabels(r, instance, cond, instance.Spec.Networks) - if err != nil { - return ctrl.Result{}, err + instance.Labels = openstacknet.AddOSNetNameLowerLabels(r, instance, cond, instance.Spec.Networks) + + // + // update instance to sync labels if changed + // + if !equality.Semantic.DeepEqual( + currentLabels, + instance.Labels, + ) { + err = r.Client.Update(context.TODO(), instance) + if err != nil { + cond.Message = fmt.Sprintf("Failed to update %s %s", instance.Kind, instance.Name) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.CommonCondReasonAddOSNetLabelError) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeError) + + err = common.WrapErrorForObject(cond.Message, instance, err) + + return ctrl.Result{}, err + } } // @@ -335,6 +357,7 @@ func (r *OpenStackBaremetalSetReconciler) Reconcile(ctx context.Context, req ctr // for hostname, hostStatus := range instance.Status.BaremetalHosts { err = openstacknetconfig.WaitOnIPsCreated( + r, instance, cond, osnetcfg, @@ -343,7 +366,7 @@ func (r *OpenStackBaremetalSetReconciler) Reconcile(ctx context.Context, req ctr &hostStatus, ) if err != nil { - return ctrl.Result{RequeueAfter: 10 * time.Second}, err + return ctrl.Result{RequeueAfter: 10 * time.Second}, nil } // Can not set (like in vmset, osclient, osctlplane) HostRef for BMS to hostname as it references the used BMH host @@ -539,8 +562,8 @@ func (r *OpenStackBaremetalSetReconciler) provisionServerCreateOrUpdate( timeout := 10 cond.Message = fmt.Sprintf("%s %s not found reconcile again in %d seconds", provisionServer.Kind, instance.Spec.ProvisionServerName, timeout) - cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.BaremetalSetCondTypeWaiting) - cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.OpenStackProvisionServerCondReasonNotFound) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.OpenStackProvisionServerCondReasonNotFound) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.BaremetalSetCondTypeWaiting) return provisionServer, ctrl.Result{RequeueAfter: time.Duration(timeout) * time.Second}, nil } else if err != nil { @@ -562,8 +585,8 @@ func (r *OpenStackBaremetalSetReconciler) provisionServerCreateOrUpdate( timeout, ) - cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.BaremetalSetCondTypeWaiting) - cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.OpenStackProvisionServerCondReasonNotReady) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.OpenStackProvisionServerCondReasonProvisioning) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.BaremetalSetCondTypeWaiting) return provisionServer, ctrl.Result{RequeueAfter: time.Duration(timeout) * time.Second}, nil } @@ -576,7 +599,7 @@ func (r *OpenStackBaremetalSetReconciler) provisionServerCreateOrUpdate( ) cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.BaremetalSetCondTypeProvisioning) - cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.OpenStackProvisionServerCondReasonReady) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.OpenStackProvisionServerCondReasonProvisioned) return provisionServer, ctrl.Result{}, nil } @@ -1380,8 +1403,8 @@ func (r *OpenStackBaremetalSetReconciler) getPasswordSecret( if k8s_errors.IsNotFound(err) { timeout := 30 cond.Message = fmt.Sprintf("PasswordSecret %s not found but specified in CR, next reconcile in %d s", instance.Spec.PasswordSecret, timeout) - cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.BaremetalSetCondTypeWaiting) - cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.ControlPlaneReasonTripleoPasswordsSecretNotFound) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.CommonCondReasonSecretMissing) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.BaremetalSetCondTypeWaiting) return passwordSecret, ctrl.Result{RequeueAfter: time.Duration(timeout) * time.Second}, nil } @@ -1428,10 +1451,6 @@ func (r *OpenStackBaremetalSetReconciler) createNewHostnames( return newHostnames, err } - if instance.Status.BaremetalHosts == nil { - instance.Status.BaremetalHosts = map[string]ospdirectorv1beta1.HostStatus{} - } - if hostnameDetails.Hostname != "" { if _, ok := instance.Status.BaremetalHosts[hostnameDetails.Hostname]; !ok { instance.Status.BaremetalHosts[hostnameDetails.Hostname] = ospdirectorv1beta1.HostStatus{ diff --git a/controllers/openstackclient_controller.go b/controllers/openstackclient_controller.go index d88a1929..8f04c056 100644 --- a/controllers/openstackclient_controller.go +++ b/controllers/openstackclient_controller.go @@ -152,7 +152,13 @@ func (r *OpenStackClientReconciler) Reconcile(ctx context.Context, req ctrl.Requ // controller to watch this resource and reconcile // var ctrlResult ctrl.Result - ctrlResult, err = openstacknetconfig.AddOSNetConfigRefLabel(r, instance, cond, instance.Spec.Networks[0]) + currentLabels := instance.DeepCopy().Labels + instance.Labels, ctrlResult, err = openstacknetconfig.AddOSNetConfigRefLabel( + r, + instance, + cond, + instance.Spec.Networks[0], + ) if (err != nil) || (ctrlResult != ctrl.Result{}) { return ctrlResult, err } @@ -160,9 +166,25 @@ func (r *OpenStackClientReconciler) Reconcile(ctx context.Context, req ctrl.Requ // // add labels of all networks used by this CR // - err = openstacknet.AddOSNetNameLowerLabels(r, instance, cond, instance.Spec.Networks) - if err != nil { - return ctrl.Result{}, err + instance.Labels = openstacknet.AddOSNetNameLowerLabels(r, instance, cond, instance.Spec.Networks) + + // + // update instance to sync labels if changed + // + if !equality.Semantic.DeepEqual( + currentLabels, + instance.Labels, + ) { + err = r.Client.Update(context.TODO(), instance) + if err != nil { + cond.Message = fmt.Sprintf("Failed to update %s %s", instance.Kind, instance.Name) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.CommonCondReasonAddOSNetLabelError) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeError) + + err = common.WrapErrorForObject(cond.Message, instance, err) + + return ctrl.Result{}, err + } } envVars := make(map[string]common.EnvSetter) @@ -275,6 +297,7 @@ func (r *OpenStackClientReconciler) Reconcile(ctx context.Context, req ctrl.Requ // for hostname, hostStatus := range instance.Status.OpenStackClientNetStatus { err = openstacknetconfig.WaitOnIPsCreated( + r, instance, cond, osnetcfg, @@ -283,7 +306,7 @@ func (r *OpenStackClientReconciler) Reconcile(ctx context.Context, req ctrl.Requ &hostStatus, ) if err != nil { - return ctrl.Result{RequeueAfter: 10 * time.Second}, err + return ctrl.Result{RequeueAfter: 10 * time.Second}, nil } hostStatus.HostRef = hostname @@ -742,10 +765,6 @@ func (r *OpenStackClientReconciler) createNewHostnames( return newHostnames, err } - if instance.Status.OpenStackClientNetStatus == nil { - instance.Status.OpenStackClientNetStatus = map[string]ospdirectorv1beta1.HostStatus{} - } - if hostnameDetails.Hostname != "" { if _, ok := instance.Status.OpenStackClientNetStatus[hostnameDetails.Hostname]; !ok { instance.Status.OpenStackClientNetStatus[hostnameDetails.Hostname] = ospdirectorv1beta1.HostStatus{ diff --git a/controllers/openstackcontrolplane_controller.go b/controllers/openstackcontrolplane_controller.go index 7e3a0499..6ef8730c 100644 --- a/controllers/openstackcontrolplane_controller.go +++ b/controllers/openstackcontrolplane_controller.go @@ -256,11 +256,17 @@ func (r *OpenStackControlPlaneReconciler) Reconcile(ctx context.Context, req ctr return ctrl.Result{}, err } + currentLabels := instance.DeepCopy().Labels // // add osnetcfg CR label reference which is used in the in the osnetcfg // controller to watch this resource and reconcile // - ctrlResult, err = openstacknetconfig.AddOSNetConfigRefLabel(r, instance, cond, vipNetworksList[0]) + instance.Labels, ctrlResult, err = openstacknetconfig.AddOSNetConfigRefLabel( + r, + instance, + cond, + vipNetworksList[0], + ) if (err != nil) || (ctrlResult != ctrl.Result{}) { return ctrlResult, err } @@ -268,9 +274,25 @@ func (r *OpenStackControlPlaneReconciler) Reconcile(ctx context.Context, req ctr // // add labels of all networks used by this CR // - err = openstacknet.AddOSNetNameLowerLabels(r, instance, cond, vipNetworksList) - if err != nil { - return ctrl.Result{}, err + instance.Labels = openstacknet.AddOSNetNameLowerLabels(r, instance, cond, vipNetworksList) + + // + // update instance to sync labels if changed + // + if !equality.Semantic.DeepEqual( + currentLabels, + instance.Labels, + ) { + err = r.Client.Update(context.TODO(), instance) + if err != nil { + cond.Message = fmt.Sprintf("Failed to update %s %s", instance.Kind, instance.Name) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.CommonCondReasonAddOSNetLabelError) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeError) + + err = common.WrapErrorForObject(cond.Message, instance, err) + + return ctrl.Result{}, err + } } // @@ -295,6 +317,7 @@ func (r *OpenStackControlPlaneReconciler) Reconcile(ctx context.Context, req ctr // for hostname, hostStatus := range instance.Status.VIPStatus { err = openstacknetconfig.WaitOnIPsCreated( + r, instance, cond, osnetcfg, @@ -303,7 +326,7 @@ func (r *OpenStackControlPlaneReconciler) Reconcile(ctx context.Context, req ctr &hostStatus, ) if err != nil { - return ctrl.Result{RequeueAfter: 10 * time.Second}, err + return ctrl.Result{RequeueAfter: 10 * time.Second}, nil } hostStatus.HostRef = hostname @@ -764,10 +787,6 @@ func (r *OpenStackControlPlaneReconciler) createNewHostnames( return newVMs, err } - if instance.Status.VIPStatus == nil { - instance.Status.VIPStatus = map[string]ospdirectorv1beta1.HostStatus{} - } - if hostnameDetails.Hostname != "" { if _, ok := instance.Status.VIPStatus[hostnameDetails.Hostname]; !ok { instance.Status.VIPStatus[hostnameDetails.Hostname] = ospdirectorv1beta1.HostStatus{ diff --git a/controllers/openstackephemeralheat_controller.go b/controllers/openstackephemeralheat_controller.go index 37754854..0d612d0f 100644 --- a/controllers/openstackephemeralheat_controller.go +++ b/controllers/openstackephemeralheat_controller.go @@ -24,7 +24,9 @@ import ( "github.com/go-logr/logr" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/equality" k8s_errors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" k8s_rand "k8s.io/apimachinery/pkg/util/rand" "k8s.io/client-go/kubernetes" @@ -97,6 +99,42 @@ func (r *OpenStackEphemeralHeatReconciler) Reconcile(ctx context.Context, req ct return ctrl.Result{}, err } + // + // initialize condition + // + cond := instance.Status.Conditions.InitCondition() + + // + // Used in comparisons below to determine whether a status update is actually needed + // + currentStatus := instance.Status.DeepCopy() + statusChanged := func() bool { + return !equality.Semantic.DeepEqual( + r.getNormalizedStatus(&instance.Status), + r.getNormalizedStatus(currentStatus), + ) + } + + defer func(cond *ospdirectorv1beta1.Condition) { + // + // Update object conditions + // + instance.Status.Conditions.UpdateCurrentCondition( + cond.Type, + cond.Reason, + cond.Message, + ) + + if statusChanged() { + if updateErr := r.Client.Status().Update(context.Background(), instance); updateErr != nil { + common.LogErrorForObject(r, updateErr, "Update status", instance) + } + } + + // log current status message to operator log + common.LogForObject(r, cond.Message, instance) + }(cond) + // examine DeletionTimestamp to determine if object is under deletion if instance.ObjectMeta.DeletionTimestamp.IsZero() { // The object is not being deleted, so if it does not have our finalizer, @@ -132,23 +170,128 @@ func (r *OpenStackEphemeralHeatReconciler) Reconcile(ctx context.Context, req ct return ctrl.Result{}, nil } + // Generate a random password secret + passwordSecret, res, err := r.generatePasswordSecret(instance, cond) + + if (res != ctrl.Result{}) || err != nil { + return res, err + } + + // Generate the config maps for the various services + err = r.generateServiceConfigMaps(instance, passwordSecret, cond) + + if err != nil { + return ctrl.Result{}, err + } + + // MariaDB pod and service + res, err = r.ensureMariaDB(instance, cond) + + if (res != ctrl.Result{}) || err != nil { + return res, err + } + + // RabbitMQ pod and service + res, err = r.ensureRabbitMQ(instance, cond) + + if (res != ctrl.Result{}) || err != nil { + return res, err + } + + // Heat API (this creates the Heat Database and runs DBsync) + res, err = r.ensureHeat(instance, cond) + + if (res != ctrl.Result{}) || err != nil { + return res, err + } + + // If we get here, everything should be ready + instance.Status.Active = true + cond.Message = fmt.Sprintf("%s %s is available", instance.Kind, instance.Name) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.EphemeralHeatReady) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeProvisioned) + + return ctrl.Result{}, nil +} + +// SetupWithManager sets up the controller with the Manager. +func (r *OpenStackEphemeralHeatReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&ospdirectorv1beta1.OpenStackEphemeralHeat{}). + Owns(&corev1.Pod{}). + Owns(&corev1.ConfigMap{}). + Owns(&corev1.Service{}). + Owns(&appsv1.ReplicaSet{}). + Complete(r) +} + +func (r *OpenStackEphemeralHeatReconciler) getNormalizedStatus(status *ospdirectorv1beta1.OpenStackEphemeralHeatStatus) *ospdirectorv1beta1.OpenStackEphemeralHeatStatus { + // + // set LastHeartbeatTime and LastTransitionTime to a default value as those + // need to be ignored to compare if conditions changed. + // + s := status.DeepCopy() + for idx := range s.Conditions { + s.Conditions[idx].LastHeartbeatTime = metav1.Time{} + s.Conditions[idx].LastTransitionTime = metav1.Time{} + } + + return s +} + +// Generate a password secret for this OpenStackEphemeralHeat if not already present +func (r *OpenStackEphemeralHeatReconciler) generatePasswordSecret( + instance *ospdirectorv1beta1.OpenStackEphemeralHeat, + cond *ospdirectorv1beta1.Condition, +) (*corev1.Secret, ctrl.Result, error) { cmLabels := common.GetLabels(instance, openstackephemeralheat.AppLabel, map[string]string{}) + // only generate the password secret once passwordSecret, _, err := common.GetSecret(r, "ephemeral-heat-"+instance.Name, instance.Namespace) - if err != nil && k8s_errors.IsNotFound(err) { - passwordSecret = openstackephemeralheat.PasswordSecret("ephemeral-heat-"+instance.Name, instance.Namespace, cmLabels, k8s_rand.String(10)) - _, op, err := common.CreateOrUpdateSecret(r, instance, passwordSecret) - if err != nil { - return ctrl.Result{}, err - } - if op != controllerutil.OperationResultNone { - r.Log.Info(fmt.Sprintf("Secret %s successfully reconciled - operation: %s", instance.Name, string(op))) + if err != nil { + if k8s_errors.IsNotFound(err) { + passwordSecret = openstackephemeralheat.PasswordSecret("ephemeral-heat-"+instance.Name, instance.Namespace, cmLabels, k8s_rand.String(10)) + _, op, err := common.CreateOrUpdateSecret(r, instance, passwordSecret) + if err != nil { + cond.Message = fmt.Sprintf("Error creating password secret for %s %s", instance.Kind, instance.Name) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.CommonCondReasonSecretError) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeError) + err = common.WrapErrorForObject(cond.Message, instance, err) + + return nil, ctrl.Result{}, err + } + + common.LogForObject( + r, + fmt.Sprintf("Secret %s successfully reconciled - operation: %s", passwordSecret.Name, string(op)), + instance, + ) + + cond.Message = "Waiting for password secret to populate" + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.EphemeralHeatCondWaitOnPassSecret) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeWaiting) + + return nil, ctrl.Result{RequeueAfter: time.Second * 3}, nil } - } else if err != nil { - return ctrl.Result{}, err + + cond.Message = fmt.Sprintf("Error acquiring password secret for %s %s", instance.Kind, instance.Name) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.CommonCondReasonSecretError) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeError) + err = common.WrapErrorForObject(cond.Message, instance, err) + + return nil, ctrl.Result{}, err } + return passwordSecret, ctrl.Result{}, nil +} + +func (r *OpenStackEphemeralHeatReconciler) generateServiceConfigMaps( + instance *ospdirectorv1beta1.OpenStackEphemeralHeat, + passwordSecret *corev1.Secret, + cond *ospdirectorv1beta1.Condition, +) error { + cmLabels := common.GetLabels(instance, openstackephemeralheat.AppLabel, map[string]string{}) envVars := make(map[string]common.EnvSetter) templateParameters := make(map[string]interface{}) templateParameters["MariaDBHost"] = "mariadb-" + instance.Name @@ -168,13 +311,28 @@ func (r *OpenStackEphemeralHeatReconciler) Reconcile(ctx context.Context, req ct Labels: cmLabels, }, } - err = common.EnsureConfigMaps(r, instance, cms, &envVars) + + err := common.EnsureConfigMaps(r, instance, cms, &envVars) + if err != nil { - return ctrl.Result{}, nil + cond.Message = fmt.Sprintf("Error creating/updating service config maps for %s %s", instance.Kind, instance.Name) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.CommonCondReasonConfigMapError) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeError) + err = common.WrapErrorForObject(cond.Message, instance, err) + + return err } + return nil +} + +func (r *OpenStackEphemeralHeatReconciler) ensureMariaDB( + instance *ospdirectorv1beta1.OpenStackEphemeralHeat, + cond *ospdirectorv1beta1.Condition, +) (ctrl.Result, error) { // MariaDB Pod mariadbPod := openstackephemeralheat.MariadbPod(instance) + op, err := controllerutil.CreateOrUpdate(context.TODO(), r.Client, mariadbPod, func() error { err := controllerutil.SetControllerReference(instance, mariadbPod, r.Scheme) if err != nil { @@ -182,20 +340,35 @@ func (r *OpenStackEphemeralHeatReconciler) Reconcile(ctx context.Context, req ct } return nil }) + if err != nil { + cond.Message = fmt.Sprintf("Error creating/updating MariaDB pod for %s %s", instance.Kind, instance.Name) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.EphemeralHeatCondMariaDBError) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeError) + err = common.WrapErrorForObject(cond.Message, instance, err) + return ctrl.Result{}, err } + if op != controllerutil.OperationResultNone { - r.Log.Info(fmt.Sprintf("MariaDB Pod %s created or updated - operation: %s", instance.Name, string(op))) - return ctrl.Result{RequeueAfter: time.Second * 1}, err + common.LogForObject( + r, + fmt.Sprintf("MariaDB pod %s successfully reconciled - operation: %s", mariadbPod.Name, string(op)), + instance, + ) } - if len(mariadbPod.Status.ContainerStatuses) > 0 && !mariadbPod.Status.ContainerStatuses[0].Ready { - r.Log.Info(fmt.Sprintf("Waiting on MariaDB to start for: %s", instance.Name)) - return ctrl.Result{RequeueAfter: time.Second * 3}, err + + if len(mariadbPod.Status.ContainerStatuses) < 1 || !mariadbPod.Status.ContainerStatuses[0].Ready { + cond.Message = fmt.Sprintf("Waiting on MariaDB to start for: %s", instance.Name) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.EphemeralHeatCondWaitOnMariaDB) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeWaiting) + + return ctrl.Result{RequeueAfter: time.Second * 3}, nil } // MariaDB Service mariadbService := openstackephemeralheat.MariadbService(instance, r.Scheme) + op, err = controllerutil.CreateOrUpdate(context.TODO(), r.Client, mariadbService, func() error { err := controllerutil.SetControllerReference(instance, mariadbService, r.Scheme) if err != nil { @@ -203,89 +376,169 @@ func (r *OpenStackEphemeralHeatReconciler) Reconcile(ctx context.Context, req ct } return nil }) + if err != nil { + cond.Message = fmt.Sprintf("Error creating/updating MariaDB service for %s %s", instance.Kind, instance.Name) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.EphemeralHeatCondMariaDBError) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeError) + err = common.WrapErrorForObject(cond.Message, instance, err) + return ctrl.Result{}, err } + if op != controllerutil.OperationResultNone { - r.Log.Info(fmt.Sprintf("MariaDB Service %s created or updated - operation: %s", instance.Name, string(op))) + common.LogForObject( + r, + fmt.Sprintf("MariaDB service %s successfully reconciled - operation: %s", mariadbPod.Name, string(op)), + instance, + ) } + return ctrl.Result{}, nil +} + +func (r *OpenStackEphemeralHeatReconciler) ensureRabbitMQ( + instance *ospdirectorv1beta1.OpenStackEphemeralHeat, + cond *ospdirectorv1beta1.Condition, +) (ctrl.Result, error) { // RabbitMQ Pod rabbitmqPod := openstackephemeralheat.RabbitmqPod(instance) - op, err = controllerutil.CreateOrUpdate(context.TODO(), r.Client, rabbitmqPod, func() error { + + op, err := controllerutil.CreateOrUpdate(context.TODO(), r.Client, rabbitmqPod, func() error { err := controllerutil.SetControllerReference(instance, rabbitmqPod, r.Scheme) if err != nil { return err } return nil }) + if err != nil { + cond.Message = fmt.Sprintf("Error creating/updating RabbitMQ pod for %s %s", instance.Kind, instance.Name) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.EphemeralHeatCondRabbitMQError) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeError) + err = common.WrapErrorForObject(cond.Message, instance, err) + return ctrl.Result{}, err } + if op != controllerutil.OperationResultNone { - r.Log.Info(fmt.Sprintf("RabbitMQ Pod %s created or updated - operation: %s", instance.Name, string(op))) - return ctrl.Result{RequeueAfter: time.Second * 1}, err + common.LogForObject( + r, + fmt.Sprintf("RabbitMQ pod %s successfully reconciled - operation: %s", rabbitmqPod.Name, string(op)), + instance, + ) } - if len(rabbitmqPod.Status.ContainerStatuses) > 0 && !rabbitmqPod.Status.ContainerStatuses[0].Ready { - r.Log.Info(fmt.Sprintf("Waiting on Rabbitmq pod to start for: %s", instance.Name)) - return ctrl.Result{RequeueAfter: time.Second * 3}, err + + if len(rabbitmqPod.Status.ContainerStatuses) < 1 || !rabbitmqPod.Status.ContainerStatuses[0].Ready { + cond.Message = fmt.Sprintf("Waiting on RabbitMQ to start for: %s", instance.Name) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.EphemeralHeatCondWaitOnRabbitMQ) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeWaiting) + + return ctrl.Result{RequeueAfter: time.Second * 3}, nil } // RabbitMQ Service - rabbitMQService := openstackephemeralheat.RabbitmqService(instance, r.Scheme) - op, err = controllerutil.CreateOrUpdate(context.TODO(), r.Client, rabbitMQService, func() error { - err := controllerutil.SetControllerReference(instance, rabbitMQService, r.Scheme) + rabbitmqService := openstackephemeralheat.RabbitmqService(instance, r.Scheme) + + op, err = controllerutil.CreateOrUpdate(context.TODO(), r.Client, rabbitmqService, func() error { + err := controllerutil.SetControllerReference(instance, rabbitmqService, r.Scheme) if err != nil { return err } return nil }) + if err != nil { + cond.Message = fmt.Sprintf("Error creating/updating RabbitMQ service for %s %s", instance.Kind, instance.Name) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.EphemeralHeatCondRabbitMQError) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeError) + err = common.WrapErrorForObject(cond.Message, instance, err) + return ctrl.Result{}, err } + if op != controllerutil.OperationResultNone { - r.Log.Info(fmt.Sprintf("Rabbitmq Service %s created or updated - operation: %s", instance.Name, string(op))) + common.LogForObject( + r, + fmt.Sprintf("RabbitMQ service %s successfully reconciled - operation: %s", rabbitmqPod.Name, string(op)), + instance, + ) } - // Heat API (this creates the Heat Database and runs DBsync) - heatAPIPod := openstackephemeralheat.HeatAPIPod(instance) - op, err = controllerutil.CreateOrUpdate(context.TODO(), r.Client, heatAPIPod, func() error { - err := controllerutil.SetControllerReference(instance, heatAPIPod, r.Scheme) + return ctrl.Result{}, nil +} + +func (r *OpenStackEphemeralHeatReconciler) ensureHeat( + instance *ospdirectorv1beta1.OpenStackEphemeralHeat, + cond *ospdirectorv1beta1.Condition, +) (ctrl.Result, error) { + // Heat Pod + heatPod := openstackephemeralheat.HeatAPIPod(instance) + + op, err := controllerutil.CreateOrUpdate(context.TODO(), r.Client, heatPod, func() error { + err := controllerutil.SetControllerReference(instance, heatPod, r.Scheme) if err != nil { return err } return nil }) + if err != nil { + cond.Message = fmt.Sprintf("Error creating/updating Heat pod for %s %s", instance.Kind, instance.Name) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.EphemeralHeatCondHeatError) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeError) + err = common.WrapErrorForObject(cond.Message, instance, err) + return ctrl.Result{}, err } + if op != controllerutil.OperationResultNone { - r.Log.Info(fmt.Sprintf("Heat API Pod %s created or updated - operation: %s", instance.Name, string(op))) - return ctrl.Result{RequeueAfter: time.Second * 5}, err // heat init containers take time to launch + common.LogForObject( + r, + fmt.Sprintf("Heat pod %s successfully reconciled - operation: %s", heatPod.Name, string(op)), + instance, + ) } - if len(heatAPIPod.Status.ContainerStatuses) > 0 && !heatAPIPod.Status.ContainerStatuses[0].Ready { - r.Log.Info(fmt.Sprintf("Waiting on Heat API pod to start for: %s", instance.Name)) - return ctrl.Result{RequeueAfter: time.Second * 3}, err + + if len(heatPod.Status.ContainerStatuses) < 1 || !heatPod.Status.ContainerStatuses[0].Ready { + cond.Message = fmt.Sprintf("Waiting on Heat to start for: %s", instance.Name) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.EphemeralHeatCondWaitOnHeat) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeWaiting) + + return ctrl.Result{RequeueAfter: time.Second * 3}, nil } // Heat Service - heatAPIService := openstackephemeralheat.HeatAPIService(instance, r.Scheme) - op, err = controllerutil.CreateOrUpdate(context.TODO(), r.Client, heatAPIService, func() error { - err := controllerutil.SetControllerReference(instance, heatAPIService, r.Scheme) + heatService := openstackephemeralheat.HeatAPIService(instance, r.Scheme) + + op, err = controllerutil.CreateOrUpdate(context.TODO(), r.Client, heatService, func() error { + err := controllerutil.SetControllerReference(instance, heatService, r.Scheme) if err != nil { return err } return nil }) + if err != nil { + cond.Message = fmt.Sprintf("Error creating/updating Heat service for %s %s", instance.Kind, instance.Name) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.EphemeralHeatCondHeatError) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeError) + err = common.WrapErrorForObject(cond.Message, instance, err) + return ctrl.Result{}, err } + if op != controllerutil.OperationResultNone { - r.Log.Info(fmt.Sprintf("Heat API Service %s created or updated - operation: %s", instance.Name, string(op))) + common.LogForObject( + r, + fmt.Sprintf("Heat service %s successfully reconciled - operation: %s", heatPod.Name, string(op)), + instance, + ) } // Heat Engine Replicaset heatEngineReplicaset := openstackephemeralheat.HeatEngineReplicaSet(instance) + op, err = controllerutil.CreateOrUpdate(context.TODO(), r.Client, heatEngineReplicaset, func() error { err := controllerutil.SetControllerReference(instance, heatEngineReplicaset, r.Scheme) if err != nil { @@ -293,44 +546,33 @@ func (r *OpenStackEphemeralHeatReconciler) Reconcile(ctx context.Context, req ct } return nil }) + if err != nil { + cond.Message = fmt.Sprintf("Error creating/updating Heat replicaset for %s %s", instance.Kind, instance.Name) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.EphemeralHeatCondHeatError) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeError) + err = common.WrapErrorForObject(cond.Message, instance, err) + return ctrl.Result{}, err } + if op != controllerutil.OperationResultNone { - r.Log.Info(fmt.Sprintf("Heat Engine Replicaset %s created or updated - operation: %s", instance.Name, string(op))) - return ctrl.Result{RequeueAfter: time.Second * 1}, err - } - if heatEngineReplicaset.Status.AvailableReplicas < instance.Spec.HeatEngineReplicas { - r.Log.Info(fmt.Sprintf("Waiting on Heat Engine Replicas to start for: %s", instance.Name)) - return ctrl.Result{RequeueAfter: time.Second * 5}, err + common.LogForObject( + r, + fmt.Sprintf("Heat Engine replicaset %s successfully reconciled - operation: %s", heatEngineReplicaset.Name, string(op)), + instance, + ) } - if err := r.setActive(instance, true); err != nil { - return ctrl.Result{}, err - } - - return ctrl.Result{}, nil -} + if heatEngineReplicaset.Status.AvailableReplicas < instance.Spec.HeatEngineReplicas { + cond.Message = fmt.Sprintf("Waiting on Heat Engine Replicas to start for: %s", instance.Name) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.EphemeralHeatCondWaitOnHeat) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeWaiting) -func (r *OpenStackEphemeralHeatReconciler) setActive(instance *ospdirectorv1beta1.OpenStackEphemeralHeat, active bool) error { - if instance.Status.Active != active { - instance.Status.Active = active - if err := r.Client.Status().Update(context.TODO(), instance); err != nil { - return err - } + return ctrl.Result{RequeueAfter: time.Second * 5}, nil } - return nil -} -// SetupWithManager sets up the controller with the Manager. -func (r *OpenStackEphemeralHeatReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&ospdirectorv1beta1.OpenStackEphemeralHeat{}). - Owns(&corev1.Pod{}). - Owns(&corev1.ConfigMap{}). - Owns(&corev1.Service{}). - Owns(&appsv1.ReplicaSet{}). - Complete(r) + return ctrl.Result{}, nil } func (r *OpenStackEphemeralHeatReconciler) resourceCleanup(instance *ospdirectorv1beta1.OpenStackEphemeralHeat) error { diff --git a/controllers/openstacknetconfig_controller.go b/controllers/openstacknetconfig_controller.go index 1a0b33ba..49f706a8 100644 --- a/controllers/openstacknetconfig_controller.go +++ b/controllers/openstacknetconfig_controller.go @@ -396,7 +396,7 @@ func (r *OpenStackNetConfigReconciler) SetupWithManager(mgr ctrl.Manager) error LabelWatcher := handler.EnqueueRequestsFromMapFunc(func(o client.Object) []reconcile.Request { labels := o.GetLabels() // - // verify object has ConfigGeneratorInputLabel + // verify object has OpenStackNetConfigReconcileLabel // reconcileCR, ok := labels[openstacknetconfig.OpenStackNetConfigReconcileLabel] if !ok { @@ -1060,8 +1060,8 @@ func (r *OpenStackNetConfigReconciler) ensureMACReservation( // // if there is a static reservation configured for the physnet AND is not "", use it // - if res, ok := instance.Spec.OVNBridgeMacMappings.StaticReservations[hostname]; ok && res.Reservations[physnet.Name] != "" { - nodeMACReservation.Reservations[physnet.Name] = res.Reservations[physnet.Name] + if res, ok := instance.Spec.Reservations[hostname]; ok && res.MACReservations[physnet.Name] != "" { + nodeMACReservation.Reservations[physnet.Name] = res.MACReservations[physnet.Name] continue } @@ -1119,8 +1119,16 @@ func (r *OpenStackNetConfigReconciler) allMACReservations( ) map[string]ospdirectorv1beta1.OpenStackMACNodeReservation { reservations := macAddress.Status.MACReservations - for node, res := range instance.Spec.OVNBridgeMacMappings.StaticReservations { - reservations[node] = res + for node, res := range instance.Spec.Reservations { + if currentRes, ok := reservations[node]; !ok { + reservations[node] = ospdirectorv1beta1.OpenStackMACNodeReservation{ + Reservations: res.MACReservations, + } + } else { + currentRes.Reservations = res.MACReservations + reservations[node] = currentRes + + } } return reservations @@ -1326,6 +1334,29 @@ func (r *OpenStackNetConfigReconciler) ensureIPs( reservations := []ospdirectorv1beta1.IPReservation{} + // + // Get static IP reservations from CR for this osNet + // + currentReservations := osNet.Status.Reservations + staticReservations := []ospdirectorv1beta1.IPReservation{} + if len(instance.Spec.Reservations) > 0 { + for nodeName, nodeReservations := range instance.Spec.Reservations { + if nodeNetIPReservation, ok := nodeReservations.IPReservations[osNet.Spec.NameLower]; ok { + currentReservations[nodeName] = ospdirectorv1beta1.NodeIPReservation{ + IP: nodeNetIPReservation, + } + staticReservations = append( + staticReservations, + ospdirectorv1beta1.IPReservation{ + IP: nodeNetIPReservation, + Hostname: nodeName, + VIP: vip, + }, + ) + } + } + } + _, cidr, err := net.ParseCIDR(osNet.Spec.Cidr) if err != nil { cond.Message = fmt.Sprintf("Failed to parse CIDR %s", osNet.Spec.Cidr) @@ -1346,7 +1377,7 @@ func (r *OpenStackNetConfigReconciler) ensureIPs( // // Do we already have a reservation for this hostname on the network? // - if reservation, ok := osNet.Status.Reservations[hostname]; ok { + if reservation, ok := currentReservations[hostname]; ok { nodeReservation := ospdirectorv1beta1.IPReservation{ IP: reservation.IP, @@ -1385,11 +1416,15 @@ func (r *OpenStackNetConfigReconciler) ensureIPs( RangeStart: start, RangeEnd: end, RoleReservelist: reservations, - Reservelist: openstacknet.GetAllIPReservations(osNet, reservations), - ExcludeRanges: []string{}, - Hostname: hostname, - VIP: vip, - Deleted: false, + Reservelist: openstacknet.GetAllIPReservations( + osNet, + reservations, + staticReservations, + ), + ExcludeRanges: []string{}, + Hostname: hostname, + VIP: vip, + Deleted: false, }) if err != nil { cond.Message = fmt.Sprintf("Failed to do ip reservation: %s", hostname) diff --git a/controllers/openstackprovisionserver_controller.go b/controllers/openstackprovisionserver_controller.go index d69401f0..91ddbde4 100644 --- a/controllers/openstackprovisionserver_controller.go +++ b/controllers/openstackprovisionserver_controller.go @@ -20,15 +20,15 @@ import ( "context" "fmt" "net/url" - "reflect" "strconv" "strings" "time" "github.com/go-logr/logr" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" - "k8s.io/utils/diff" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/config" @@ -39,10 +39,9 @@ import ( provisionserver "github.com/openstack-k8s-operators/osp-director-operator/pkg/provisionserver" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/equality" k8s_errors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/dynamic" ) var ( @@ -113,6 +112,45 @@ func (r *OpenStackProvisionServerReconciler) Reconcile(ctx context.Context, req return ctrl.Result{}, err } + // + // initialize condition + // + cond := &ospdirectorv1beta1.Condition{} + + // + // Used in comparisons below to determine whether a status update is actually needed + // + currentStatus := instance.Status.DeepCopy() + statusChanged := func() bool { + return !equality.Semantic.DeepEqual( + r.getNormalizedStatus(&instance.Status), + r.getNormalizedStatus(currentStatus), + ) + } + + defer func(cond *ospdirectorv1beta1.Condition) { + // + // Update object conditions + // + instance.Status.Conditions.UpdateCurrentCondition( + cond.Type, + cond.Reason, + cond.Message, + ) + + instance.Status.ProvisioningStatus.Reason = cond.Message + instance.Status.ProvisioningStatus.State = ospdirectorv1beta1.ProvisioningState(cond.Type) + + if statusChanged() { + if updateErr := r.Client.Status().Update(context.Background(), instance); updateErr != nil { + common.LogErrorForObject(r, updateErr, "Update status", instance) + } + } + + // log current status message to operator log + common.LogForObject(r, cond.Message, instance) + }(cond) + // If we determine that a backup is overriding this reconcile, requeue after a longer delay overrideReconcile, err := common.OpenStackBackupOverridesReconcile(r.Client, instance) @@ -125,9 +163,6 @@ func (r *OpenStackProvisionServerReconciler) Reconcile(ctx context.Context, req return ctrl.Result{RequeueAfter: time.Duration(20) * time.Second}, err } - // get a copy of the CR ProvisioningStatus - actualProvisioningState := instance.Status.DeepCopy().ProvisioningStatus - // config maps envVars := make(map[string]common.EnvSetter) cmLabels := common.GetLabels(instance, provisionserver.AppLabel, map[string]string{}) @@ -156,46 +191,23 @@ func (r *OpenStackProvisionServerReconciler) Reconcile(ctx context.Context, req // Get the provisioning interface of the cluster worker nodes from either Metal3 // or from the instance spec itself if it was provided there - provInterfaceName := instance.Spec.Interface - - if provInterfaceName != "" { - r.Log.Info(fmt.Sprintf("Provisioning interface supplied by %s spec", instance.Name)) - } else { - r.Log.Info("Provisioning interface name not yet discovered, checking Metal3...") - - provInterfaceName, err = r.getProvisioningInterface(instance) - - if err != nil { - msg := fmt.Sprintf("Unable to acquire provisioning interface: %v", err) - actualProvisioningState.State = ospdirectorv1beta1.ProvisionServerCondTypeError - actualProvisioningState.Reason = msg - _ = r.setProvisioningStatus(instance, actualProvisioningState) - return ctrl.Result{}, err - } + provInterfaceName, err := r.getProvisioningInterfaceName(instance, cond) - if provInterfaceName == "" { - err := fmt.Errorf("Metal3 provisioning interface configuration not found") - actualProvisioningState.State = ospdirectorv1beta1.ProvisionServerCondTypeError - actualProvisioningState.Reason = err.Error() - _ = r.setProvisioningStatus(instance, actualProvisioningState) - return ctrl.Result{}, err - } + if err != nil { + return ctrl.Result{}, err } // Create or update the Deployment object - op, err := r.deploymentCreateOrUpdate(instance, provInterfaceName) + err = r.deploymentCreateOrUpdate(instance, cond, provInterfaceName) if err != nil { return ctrl.Result{}, err } - if op != controllerutil.OperationResultNone { - r.Log.Info(fmt.Sprintf("Deployment %s successfully reconciled - operation: %s", instance.Name, string(op))) - } - // Calculate overall provisioning status - actualProvisioningState.State = ospdirectorv1beta1.ProvisionServerCondTypeProvisioning - actualProvisioningState.Reason = fmt.Sprintf("ProvisionServer %s is currently provisioning", instance.Name) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.ProvisionServerCondTypeProvisioning) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.OpenStackProvisionServerCondReasonProvisioning) + cond.Message = "Provisioning of OpenStackProvisionServer in progress" // Provision IP Discovery Agent sets status' ProvisionIP if instance.Status.ProvisionIP != "" { @@ -204,7 +216,11 @@ func (r *OpenStackProvisionServerReconciler) Reconcile(ctx context.Context, req curURL, err := url.Parse(instance.Status.LocalImageURL) if err != nil { - r.Log.Error(err, "Failed to parse existing LocalImageURL for OpenStackProvisionServer %s: %s", instance.Name, instance.Status.LocalImageURL) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.ProvisionServerCondTypeError) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.OpenStackProvisionServerCondReasonLocalImageURLParseError) + cond.Message = fmt.Sprintf("Failed to parse existing LocalImageURL: %s", instance.Status.LocalImageURL) + err = common.WrapErrorForObject(cond.Message, instance, err) + return ctrl.Result{}, err } @@ -212,14 +228,7 @@ func (r *OpenStackProvisionServerReconciler) Reconcile(ctx context.Context, req if instance.Status.LocalImageURL == "" || curURL.Hostname() != instance.Status.ProvisionIP { // Update status with LocalImageURL, given ProvisionIP status value instance.Status.LocalImageURL = r.getLocalImageURL(instance) - err = r.Client.Status().Update(context.TODO(), instance) - - if err != nil { - r.Log.Error(err, "Failed to update CR status %v") - return ctrl.Result{}, err - } - - r.Log.Info(fmt.Sprintf("OpenStackProvisionServer %s status' LocalImageURL updated: %s", instance.Name, instance.Status.LocalImageURL)) + common.LogForObject(r, fmt.Sprintf("OpenStackProvisionServer LocalImageURL changed: %s", instance.Status.LocalImageURL), instance) } // Now check the associated pod's status @@ -227,26 +236,55 @@ func (r *OpenStackProvisionServerReconciler) Reconcile(ctx context.Context, req LabelSelector: fmt.Sprintf("deployment=%s-provisionserver-deployment", instance.Name), }) - if err != nil && !k8s_errors.IsNotFound(err) { - actualProvisioningState.State = ospdirectorv1beta1.ProvisionServerCondTypeError - actualProvisioningState.Reason = err.Error() - _ = r.setProvisioningStatus(instance, actualProvisioningState) + if err != nil { + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.ProvisionServerCondTypeError) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.OpenStackProvisionServerCondReasonListError) + cond.Message = "Failed to list pods" + err = common.WrapErrorForObject(cond.Message, instance, err) + return ctrl.Result{}, err - } else if err == nil { - // There should only be one pod. If there is more than one, we have other problems... - for _, pod := range podList.Items { - if pod.Status.Phase == corev1.PodRunning { - actualProvisioningState.State = ospdirectorv1beta1.ProvisionServerCondTypeProvisioned - actualProvisioningState.Reason = fmt.Sprintf("ProvisionServer %s has been provisioned", instance.Name) - break - } + } + + podListLen := len(podList.Items) + + if podListLen > 1 { + common.LogForObject(r, fmt.Sprintf("WARNING: Multiple pods (%d) found for OpenStackProvisionServer %s!", podListLen, instance.Name), instance) + } else if podListLen < 1 { + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.ProvisionServerCondTypeWaiting) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.OpenStackProvisionServerCondReasonListError) + cond.Message = "Pod not yet available" + err = common.WrapErrorForObject(cond.Message, instance, err) + + return ctrl.Result{RequeueAfter: time.Duration(10) * time.Second}, err + } + + // There should only be one pod. If there is more than one, we have other problems... + for _, pod := range podList.Items { + if pod.Status.Phase == corev1.PodRunning { + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.ProvisionServerCondTypeProvisioned) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.OpenStackProvisionServerCondReasonProvisioned) + cond.Message = "OpenStackProvisionServer has been provisioned" + break } } } - err = r.setProvisioningStatus(instance, actualProvisioningState) + return ctrl.Result{}, nil +} + +func (r *OpenStackProvisionServerReconciler) getNormalizedStatus(status *ospdirectorv1beta1.OpenStackProvisionServerStatus) *ospdirectorv1beta1.OpenStackProvisionServerStatus { - return ctrl.Result{}, err + // + // set LastHeartbeatTime and LastTransitionTime to a default value as those + // need to be ignored to compare if conditions changed. + // + s := status.DeepCopy() + for idx := range s.Conditions { + s.Conditions[idx].LastHeartbeatTime = metav1.Time{} + s.Conditions[idx].LastTransitionTime = metav1.Time{} + } + + return s } // SetupWithManager - prepare controller for use with operator manager @@ -260,7 +298,51 @@ func (r *OpenStackProvisionServerReconciler) SetupWithManager(mgr ctrl.Manager) Complete(r) } -func (r *OpenStackProvisionServerReconciler) deploymentCreateOrUpdate(instance *ospdirectorv1beta1.OpenStackProvisionServer, provInterfaceName string) (controllerutil.OperationResult, error) { +func (r *OpenStackProvisionServerReconciler) getProvisioningInterfaceName( + instance *ospdirectorv1beta1.OpenStackProvisionServer, + cond *ospdirectorv1beta1.Condition, +) (string, error) { + // Get the provisioning interface of the cluster worker nodes from either Metal3 + // or from the instance spec itself if it was provided there + var err error + provInterfaceName := instance.Spec.Interface + + if provInterfaceName != "" { + r.Log.Info(fmt.Sprintf("Provisioning interface supplied by %s spec", instance.Name)) + } else { + r.Log.Info("Provisioning interface name not yet discovered, checking Metal3...") + + provInterfaceName, err = r.getProvisioningInterface(instance) + + if err != nil { + cond.Message = "Unable to acquire provisioning interface!" + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.OpenStackProvisionServerCondReasonInterfaceAcquireError) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeError) + + err = common.WrapErrorForObject(cond.Message, instance, err) + + return "", err + } + + if provInterfaceName == "" { + cond.Message = "Metal3 provisioning interface configuration not found!" + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.OpenStackProvisionServerCondReasonInterfaceNotFound) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeError) + + err = common.WrapErrorForObject(cond.Message, instance, err) + + return "", err + } + } + + return provInterfaceName, nil +} + +func (r *OpenStackProvisionServerReconciler) deploymentCreateOrUpdate( + instance *ospdirectorv1beta1.OpenStackProvisionServer, + cond *ospdirectorv1beta1.Condition, + provInterfaceName string, +) error { trueValue := true // Get volumes @@ -384,7 +466,22 @@ func (r *OpenStackProvisionServerReconciler) deploymentCreateOrUpdate(instance * return nil }) - return op, err + if err != nil { + cond.Message = fmt.Sprintf("Failed to create or update deployment %s", instance.Name) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.OpenStackProvisionServerCondReasonDeploymentError) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeError) + err = common.WrapErrorForObject(cond.Message, instance, err) + + return err + } + + if op != controllerutil.OperationResultNone { + cond.Message = fmt.Sprintf("%s %s %s", instance.Kind, instance.Name, op) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.OpenStackProvisionServerCondReasonDeploymentCreated) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeProvisioned) + } + + return nil } func (r *OpenStackProvisionServerReconciler) getLocalImageURL(instance *ospdirectorv1beta1.OpenStackProvisionServer) string { @@ -398,7 +495,9 @@ func (r *OpenStackProvisionServerReconciler) getLocalImageURL(instance *ospdirec return fmt.Sprintf("http://%s:%d/images/%s/compressed-%s", instance.Status.ProvisionIP, instance.Spec.Port, baseFilename, baseFilename) } -func (r *OpenStackProvisionServerReconciler) getProvisioningInterface(instance *ospdirectorv1beta1.OpenStackProvisionServer) (string, error) { +func (r *OpenStackProvisionServerReconciler) getProvisioningInterface( + instance *ospdirectorv1beta1.OpenStackProvisionServer, +) (string, error) { cfg, err := config.GetConfig() if err != nil { @@ -432,27 +531,3 @@ func (r *OpenStackProvisionServerReconciler) getProvisioningInterface(instance * return "", nil } - -func (r *OpenStackProvisionServerReconciler) setProvisioningStatus(instance *ospdirectorv1beta1.OpenStackProvisionServer, actualState ospdirectorv1beta1.OpenStackProvisionServerProvisioningStatus) error { - // get current ProvisioningStatus - currentState := instance.Status.ProvisioningStatus - - // if the current ProvisioningStatus is different from the actual, store the update - // otherwise, just log the status again - if !reflect.DeepEqual(currentState, actualState) { - r.Log.Info(fmt.Sprintf("%s - diff %s", actualState.Reason, diff.ObjectReflectDiff(currentState, actualState))) - instance.Status.ProvisioningStatus = actualState - - instance.Status.Conditions = ospdirectorv1beta1.ConditionList{} - instance.Status.Conditions.Set(ospdirectorv1beta1.ConditionType(actualState.State), corev1.ConditionTrue, ospdirectorv1beta1.ConditionReason(actualState.Reason), actualState.Reason) - - if err := r.Client.Status().Update(context.TODO(), instance); err != nil { - r.Log.Error(err, "Failed to update CR status %v") - return err - } - } else if actualState.Reason != "" { - r.Log.Info(actualState.Reason) - } - - return nil -} diff --git a/controllers/openstackvmset_controller.go b/controllers/openstackvmset_controller.go index 51ded856..bbddf2e5 100644 --- a/controllers/openstackvmset_controller.go +++ b/controllers/openstackvmset_controller.go @@ -230,11 +230,17 @@ func (r *OpenStackVMSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque secretLabels := common.GetLabels(instance, vmset.AppLabel, map[string]string{}) var ctrlResult ctrl.Result + currentLabels := instance.DeepCopy().Labels // // add osnetcfg CR label reference which is used in the in the osnetcfg // controller to watch this resource and reconcile // - ctrlResult, err = openstacknetconfig.AddOSNetConfigRefLabel(r, instance, cond, instance.Spec.Networks[0]) + instance.Labels, ctrlResult, err = openstacknetconfig.AddOSNetConfigRefLabel( + r, + instance, + cond, + instance.Spec.Networks[0], + ) if (err != nil) || (ctrlResult != ctrl.Result{}) { return ctrlResult, err } @@ -242,9 +248,25 @@ func (r *OpenStackVMSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque // // add labels of all networks used by this CR // - err = openstacknet.AddOSNetNameLowerLabels(r, instance, cond, instance.Spec.Networks) - if err != nil { - return ctrl.Result{}, err + instance.Labels = openstacknet.AddOSNetNameLowerLabels(r, instance, cond, instance.Spec.Networks) + + // + // update instance to sync labels if changed + // + if !equality.Semantic.DeepEqual( + currentLabels, + instance.Labels, + ) { + err = r.Client.Update(context.TODO(), instance) + if err != nil { + cond.Message = fmt.Sprintf("Failed to update %s %s", instance.Kind, instance.Name) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.CommonCondReasonAddOSNetLabelError) + cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeError) + + err = common.WrapErrorForObject(cond.Message, instance, err) + + return ctrl.Result{}, err + } } // @@ -385,6 +407,7 @@ func (r *OpenStackVMSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque // for hostname, hostStatus := range instance.Status.VMHosts { err = openstacknetconfig.WaitOnIPsCreated( + r, instance, cond, osnetcfg, @@ -393,7 +416,7 @@ func (r *OpenStackVMSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque &hostStatus, ) if err != nil { - return ctrl.Result{RequeueAfter: 10 * time.Second}, err + return ctrl.Result{RequeueAfter: 10 * time.Second}, nil } hostStatus.HostRef = hostname @@ -1175,10 +1198,6 @@ func (r *OpenStackVMSetReconciler) createNewHostnames( return newHostnames, err } - if instance.Status.VMHosts == nil { - instance.Status.VMHosts = map[string]ospdirectorv1beta1.HostStatus{} - } - if hostnameDetails.Hostname != "" { if _, ok := instance.Status.VMHosts[hostnameDetails.Hostname]; !ok { instance.Status.VMHosts[hostnameDetails.Hostname] = ospdirectorv1beta1.HostStatus{ diff --git a/pkg/common/ipam.go b/pkg/common/ipam.go index 45a58a3c..d51071f4 100644 --- a/pkg/common/ipam.go +++ b/pkg/common/ipam.go @@ -34,16 +34,6 @@ type AssignIPDetails struct { Deleted bool } -// IPSet - ipset details -type IPSet struct { - Networks []string - Role string - HostCount int - AddToPredictableIPs bool - VIP bool - HostNameRefs map[string]string -} - func (a AssignmentError) Error() string { return fmt.Sprintf("Could not allocate IP in range: ip: %v / - %v / range: %#v", a.firstIP, a.lastIP, a.ipnet) } diff --git a/pkg/openstacknet/funcs.go b/pkg/openstacknet/funcs.go index b6ef79af..c42e18e3 100644 --- a/pkg/openstacknet/funcs.go +++ b/pkg/openstacknet/funcs.go @@ -13,9 +13,7 @@ import ( openstacknetattachment "github.com/openstack-k8s-operators/osp-director-operator/pkg/openstacknetattachment" v1 "k8s.io/api/apps/v1" k8s_errors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" ) // GetOpenStackNetsBindingMap - Returns map of OpenStackNet name to binding type @@ -124,11 +122,11 @@ func AddOSNetNameLowerLabels( obj client.Object, cond *ospdirectorv1beta1.Condition, networkNameLowerNames []string, -) error { +) map[string]string { - currentLabels := obj.GetLabels() - if currentLabels == nil { - currentLabels = map[string]string{} + labels := obj.GetLabels() + if labels == nil { + labels = map[string]string{} } osNetLabels := map[string]string{} @@ -144,19 +142,19 @@ func AddOSNetNameLowerLabels( // // get current osNet Labels and verify if nets got removed // - for _, label := range reflect.ValueOf(currentLabels).MapKeys() { + for _, label := range reflect.ValueOf(labels).MapKeys() { // // has label key SubNetNameLabelSelector string included? // if strings.HasSuffix(label.String(), SubNetNameLabelSelector) { l := label.String() - osNetLabels[l] = currentLabels[l] + osNetLabels[l] = labels[l] // // if l is not in networkNameLowerNamesMap it got removed // if _, ok := networkNameLowerNamesMap[l]; !ok { - delete(currentLabels, l) + delete(labels, l) removedOsNets[l] = true } @@ -183,7 +181,7 @@ func AddOSNetNameLowerLabels( // if label is not in osNetLabels its a new one // if _, ok := osNetLabels[label]; !ok { - currentLabels[label] = strconv.FormatBool(true) + labels[label] = strconv.FormatBool(true) newOsNets[label] = true } @@ -201,28 +199,7 @@ func AddOSNetNameLowerLabels( ) } - // - // update labels on obj - // - _, err := controllerutil.CreateOrUpdate(context.TODO(), r.GetClient(), obj, func() error { - obj.SetLabels( - labels.Merge( - obj.GetLabels(), - currentLabels, - )) - - return nil - }) - if err != nil { - cond.Message = fmt.Sprintf("Failed to update %s labels on %s", obj.GetObjectKind().GroupVersionKind().Kind, obj.GetName()) - cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.CommonCondReasonAddOSNetLabelError) - cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeError) - err = common.WrapErrorForObject(cond.Message, obj, err) - - return err - } - - return nil + return labels } // @@ -231,6 +208,7 @@ func AddOSNetNameLowerLabels( func GetAllIPReservations( osNet *ospdirectorv1beta1.OpenStackNet, newReservations []ospdirectorv1beta1.IPReservation, + staticReservations []ospdirectorv1beta1.IPReservation, ) []ospdirectorv1beta1.IPReservation { // // add just now new created @@ -238,21 +216,65 @@ func GetAllIPReservations( reservationList := newReservations // - // add already synamic created + // add reservation already stored in the osnet.Status.Reservations // - for _, roleReservations := range osNet.Spec.RoleReservations { - reservationList = append(reservationList, roleReservations.Reservations...) + for hostname, res := range osNet.Status.Reservations { + reservationList = append( + reservationList, + ospdirectorv1beta1.IPReservation{ + IP: res.IP, + Hostname: hostname, + Deleted: res.Deleted, + }, + ) + } - // TODO static reservation - /* - // - // add static configured reservations - // - for node, res := range instance.Spec.XX.StaticReservations { - reservations[node] = res + // + // add new reservations from osnet.Spec.Reservations which are not yet synced to osnet.Status.Reservations + // + for _, role := range osNet.Spec.RoleReservations { + for _, res := range role.Reservations { + found := false + for _, resList := range reservationList { + if res.IP == resList.IP { + found = true + break + } + } + if !found { + reservationList = append( + reservationList, + ospdirectorv1beta1.IPReservation{ + IP: res.IP, + Hostname: res.Hostname, + Deleted: res.Deleted, + }, + ) + } } - */ + } + + // + // add new staticReservations provided by the osnetcfg CR + // + for _, staticRes := range staticReservations { + found := false + for _, res := range reservationList { + if res.IP == staticRes.IP { + found = true + break + } + } + if !found { + reservationList = append(reservationList, staticRes) + } + } + + // + // add staticReservations provided by osnetcfg CR + // + reservationList = append(reservationList, staticReservations...) // sort reservationList by IP sort.Slice(reservationList[:], func(i, j int) bool { diff --git a/pkg/openstacknetconfig/funcs.go b/pkg/openstacknetconfig/funcs.go index a926aded..d33a6f49 100644 --- a/pkg/openstacknetconfig/funcs.go +++ b/pkg/openstacknetconfig/funcs.go @@ -1,7 +1,6 @@ package openstacknetconfig import ( - "context" "fmt" "time" @@ -12,9 +11,7 @@ import ( k8s_errors "k8s.io/apimachinery/pkg/api/errors" ctrl "sigs.k8s.io/controller-runtime" - "k8s.io/apimachinery/pkg/labels" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/reconcile" ) @@ -27,7 +24,8 @@ func AddOSNetConfigRefLabel( obj client.Object, cond *ospdirectorv1beta1.Condition, networkNameLower string, -) (reconcile.Result, error) { +) (map[string]string, reconcile.Result, error) { + labels := obj.GetLabels() // // only add label if it is not already there @@ -50,14 +48,14 @@ func AddOSNetConfigRefLabel( cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeWaiting) common.LogForObject(r, cond.Message, obj) - return ctrl.Result{RequeueAfter: 10 * time.Second}, nil + return labels, ctrl.Result{RequeueAfter: 10 * time.Second}, nil } else if err != nil { cond.Message = fmt.Sprintf("Failed to get OpenStackNet %s ", networkNameLower) cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.CommonCondReasonOSNetError) cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.NetError) err = common.WrapErrorForObject(cond.Message, obj, err) - return ctrl.Result{}, err + return labels, ctrl.Result{}, err } // @@ -66,50 +64,37 @@ func AddOSNetConfigRefLabel( for _, ownerRef := range osnet.ObjectMeta.OwnerReferences { if ownerRef.Kind == "OpenStackNetConfig" { // - // update labels on obj + // merge with obj labels // - op, err := controllerutil.CreateOrUpdate(context.TODO(), r.GetClient(), obj, func() error { - obj.SetLabels( - labels.Merge( - obj.GetLabels(), - map[string]string{ - OpenStackNetConfigReconcileLabel: ownerRef.Name, - }, - )) - - return nil - }) - if err != nil { - cond.Message = fmt.Sprintf("Failed to update RefLabel label on %s %s", obj.GetObjectKind().GroupVersionKind().Kind, obj.GetName()) - cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.CommonCondReasonAddRefLabelError) - cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.ConfigGeneratorCondTypeError) - err = common.WrapErrorForObject(cond.Message, obj, err) - - return ctrl.Result{}, err - } + labels = common.MergeStringMaps( + labels, + map[string]string{ + OpenStackNetConfigReconcileLabel: ownerRef.Name, + }, + ) + common.LogForObject( r, - fmt.Sprintf("%s updated with %s:%s label: %s", + fmt.Sprintf("%s updated with %s:%s label", obj.GetName(), OpenStackNetConfigReconcileLabel, ownerRef.Name, - op, ), obj, ) - - return ctrl.Result{}, nil + break } } } - return ctrl.Result{}, nil + return labels, ctrl.Result{}, nil } // // WaitOnIPsCreated - Wait for IPs created on all configured networks // func WaitOnIPsCreated( + r common.ReconcilerCommon, obj client.Object, cond *ospdirectorv1beta1.Condition, osnetcfg *ospdirectorv1beta1.OpenStackNetConfig, @@ -118,18 +103,27 @@ func WaitOnIPsCreated( hostStatus *ospdirectorv1beta1.HostStatus, ) error { // - // If verify that we have the hosts entry on the status if the osnetcfg object + // verify that we have the host entry on the status of the osnetcfg object // var osnetcfgHostStatus ospdirectorv1beta1.OpenStackHostStatus var ok bool if osnetcfgHostStatus, ok = osnetcfg.Status.Hosts[hostname]; !ok { - cond.Message = fmt.Sprintf("%s %s waiting on node %s to be added to %s config %s", + common.LogForObject( + r, + fmt.Sprintf("%s %s waiting on node %s to be added to %s config %s", + obj.GetObjectKind().GroupVersionKind().Kind, + obj.GetName(), + hostname, + osnetcfg.Kind, + osnetcfg.Name, + ), + obj, + ) + cond.Message = fmt.Sprintf("%s %s waiting on IPs to be created for all nodes and networks", obj.GetObjectKind().GroupVersionKind().Kind, obj.GetName(), - hostname, - osnetcfg.Kind, - osnetcfg.Name) - cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.NetConfigCondReasonWaitingOnHost) + ) + cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.NetConfigCondReasonWaitingOnIPsForHost) cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeWaiting) return k8s_errors.NewNotFound(v1.Resource(obj.GetObjectKind().GroupVersionKind().Kind), cond.Message) @@ -143,12 +137,21 @@ func WaitOnIPsCreated( hostStatus.IPAddresses[osNet] = ip continue } - - cond.Message = fmt.Sprintf("%s %s waiting on IP address for node %s on network %s to be available", + common.LogForObject( + r, + fmt.Sprintf("%s %s waiting on IP address for node %s on network %s to be available", + obj.GetObjectKind().GroupVersionKind().Kind, + obj.GetName(), + hostname, + osNet, + ), + obj, + ) + + cond.Message = fmt.Sprintf("%s %s waiting on IPs to be created for all nodes and networks", obj.GetObjectKind().GroupVersionKind().Kind, obj.GetName(), - hostname, - osNet) + ) cond.Reason = ospdirectorv1beta1.ConditionReason(ospdirectorv1beta1.NetConfigCondReasonWaitingOnIPsForHost) cond.Type = ospdirectorv1beta1.ConditionType(ospdirectorv1beta1.CommonCondTypeWaiting) diff --git a/templates/openstackconfiggenerator/bin/create-playbooks.sh b/templates/openstackconfiggenerator/bin/create-playbooks.sh index 3887408f..f3a15e4e 100755 --- a/templates/openstackconfiggenerator/bin/create-playbooks.sh +++ b/templates/openstackconfiggenerator/bin/create-playbooks.sh @@ -162,6 +162,7 @@ EOF_PYTHON # with OSP17 the rendered templates get into overcloud directory, create link to have the same dst output_dir=$(ls -dtr $HOME/ansible/tripleo-ansible-* | tail -1) +rm -f $HOME/ansible/overcloud ln -sf ${output_dir} $HOME/ansible/overcloud {{- else }} diff --git a/templates/vmset/cloudinit/networkdata b/templates/vmset/cloudinit/networkdata index 5aed4fe7..6b7ee222 100644 --- a/templates/vmset/cloudinit/networkdata +++ b/templates/vmset/cloudinit/networkdata @@ -1,20 +1,20 @@ version: 2 ethernets: {{ .CtlplaneInterface }}: - addresses: [ {{ .ControllerIP }} ] - {{ if not (eq (len .CtlplaneDns) 0) }} + addresses: [ "{{ .ControllerIP }}" ] + {{- if not (eq (len .CtlplaneDns) 0) }} nameservers: - {{ if not (eq (len .CtlplaneDnsSearch) 0) }} + {{- if not (eq (len .CtlplaneDnsSearch) 0) }} search: - {{ range $value := .CtlplaneDnsSearch }} + {{- range $value := .CtlplaneDnsSearch }} - {{ $value }} - {{ end }} - {{ end }} + {{- end }} + {{- end }} addresses: - {{ range $value := .CtlplaneDns }} + {{- range $value := .CtlplaneDns }} - {{ $value }} - {{ end }} - {{ end }} + {{- end }} + {{- end }} {{- if .Gateway }} {{ .Gateway }} {{- end }} diff --git a/tests/kuttl/common/scripts/prep.sh b/tests/kuttl/common/scripts/prep.sh index fab86f44..c7ee79f9 100755 --- a/tests/kuttl/common/scripts/prep.sh +++ b/tests/kuttl/common/scripts/prep.sh @@ -18,4 +18,4 @@ oc delete secret -n openstack userpassword --ignore-not-found oc delete secret -n openstack osp-controlplane-ssh-keys osp-baremetalset-ssh-keys --ignore-not-found # Free any dead PVs -for i in $(oc get pv | grep Failed | awk {'print $1'}); do oc patch pv $i --type='json' -p='[{"op": "remove", "path": "/spec/claimRef"}]'; done +for i in $(oc get pv | egrep "Failed|Released" | awk {'print $1'}); do oc patch pv $i --type='json' -p='[{"op": "remove", "path": "/spec/claimRef"}]'; done diff --git a/tests/kuttl/common/tests/create_openstackcontrolplane-assert.yaml b/tests/kuttl/common/tests/create_openstackcontrolplane-assert.yaml index bac07d9a..2973027f 100644 --- a/tests/kuttl/common/tests/create_openstackcontrolplane-assert.yaml +++ b/tests/kuttl/common/tests/create_openstackcontrolplane-assert.yaml @@ -58,7 +58,7 @@ status: hostRef: controlplane hostname: controlplane ipaddresses: - ctlplane: 192.168.25.100/24 + ctlplane: 192.168.25.10/24 external: 10.0.0.10/24 internal_api: 172.17.0.10/24 storage: 172.18.0.10/24 @@ -123,9 +123,9 @@ status: hostRef: openstackclient-0 hostname: openstackclient-0 ipaddresses: - ctlplane: 192.168.25.101/24 - external: 10.0.0.11/24 - internal_api: 172.17.0.11/24 + ctlplane: 192.168.25.251/24 + external: 10.0.0.251/24 + internal_api: 172.17.0.251/24 provisioningState: Provisioned --- apiVersion: osp-director.openstack.org/v1beta1 @@ -159,14 +159,14 @@ spec: reservations: - deleted: false hostname: controlplane - ip: 192.168.25.100 + ip: 192.168.25.10 vip: true OpenstackClientopenstackclient: addToPredictableIPs: false reservations: - deleted: false hostname: openstackclient-0 - ip: 192.168.25.101 + ip: 192.168.25.251 vip: false routes: [] vip: true @@ -176,10 +176,10 @@ status: reservations: controlplane: deleted: false - ip: 192.168.25.100 + ip: 192.168.25.10 openstackclient-0: deleted: false - ip: 192.168.25.101 + ip: 192.168.25.251 reservedIpCount: 2 --- apiVersion: osp-director.openstack.org/v1beta1 @@ -220,7 +220,7 @@ spec: reservations: - deleted: false hostname: openstackclient-0 - ip: 10.0.0.11 + ip: 10.0.0.251 vip: false routes: [] vip: true @@ -233,7 +233,7 @@ status: ip: 10.0.0.10 openstackclient-0: deleted: false - ip: 10.0.0.11 + ip: 10.0.0.251 reservedIpCount: 2 --- apiVersion: osp-director.openstack.org/v1beta1 @@ -274,7 +274,7 @@ spec: reservations: - deleted: false hostname: openstackclient-0 - ip: 172.17.0.11 + ip: 172.17.0.251 vip: false routes: [] vip: true @@ -287,7 +287,7 @@ status: ip: 172.17.0.10 openstackclient-0: deleted: false - ip: 172.17.0.11 + ip: 172.17.0.251 reservedIpCount: 2 --- apiVersion: osp-director.openstack.org/v1beta1 diff --git a/tests/kuttl/common/tests/create_openstackcontrolplane_single_net-assert.yaml b/tests/kuttl/common/tests/create_openstackcontrolplane_single_net-assert.yaml index 8bf96573..ae301f8b 100644 --- a/tests/kuttl/common/tests/create_openstackcontrolplane_single_net-assert.yaml +++ b/tests/kuttl/common/tests/create_openstackcontrolplane_single_net-assert.yaml @@ -51,7 +51,7 @@ status: hostRef: controlplane hostname: controlplane ipaddresses: - ctlplane: 192.168.25.100/24 + ctlplane: 192.168.25.10/24 provisioningState: Provisioned --- apiVersion: osp-director.openstack.org/v1beta1 @@ -105,7 +105,7 @@ status: hostRef: openstackclient-0 hostname: openstackclient-0 ipaddresses: - ctlplane: 192.168.25.101/24 + ctlplane: 192.168.25.251/24 provisioningState: Provisioned --- apiVersion: osp-director.openstack.org/v1beta1 @@ -139,14 +139,14 @@ spec: reservations: - deleted: false hostname: controlplane - ip: 192.168.25.100 + ip: 192.168.25.10 vip: true OpenstackClientopenstackclient: addToPredictableIPs: false reservations: - deleted: false hostname: openstackclient-0 - ip: 192.168.25.101 + ip: 192.168.25.251 vip: false routes: [] vip: true @@ -156,10 +156,10 @@ status: reservations: controlplane: deleted: false - ip: 192.168.25.100 + ip: 192.168.25.10 openstackclient-0: deleted: false - ip: 192.168.25.101 + ip: 192.168.25.251 reservedIpCount: 2 --- apiVersion: v1 diff --git a/tests/kuttl/common/tests/create_openstackcontrolplane_single_net_ipv6-assert.yaml b/tests/kuttl/common/tests/create_openstackcontrolplane_single_net_ipv6-assert.yaml new file mode 100644 index 00000000..80d2e15a --- /dev/null +++ b/tests/kuttl/common/tests/create_openstackcontrolplane_single_net_ipv6-assert.yaml @@ -0,0 +1,191 @@ +# +# Check for: +# +# - 1 OpenStackControlPlane +# - 1 OpenStackVMSet +# - 1 OpenStackClient +# - 6 OpenStackNet (IP reservations for OpenStackControlPlane and OpenStackClient) +# - 1 Secret (TripleO passwords) +# - 1 OpenStackMACAddress +# + +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackControlPlane +metadata: + name: overcloud + namespace: openstack +spec: + domainName: ostest.test.metalkube.org + enableFencing: false + gitSecret: git-secret + openStackClientImageURL: registry.redhat.io/rhosp-rhel8/openstack-tripleoclient:16.2 + openStackClientNetworks: + - ctlplane + openStackClientStorageClass: host-nfs-storageclass + openStackRelease: "16.2" + passwordSecret: userpassword + virtualMachineRoles: + controller: + baseImageVolumeName: controller-base-img + cores: 6 + ctlplaneInterface: enp2s0 + diskSize: 50 + isTripleoRole: true + memory: 20 + networks: + - ctlplane + roleCount: 0 + roleName: Controller + storageClass: host-nfs-storageclass +status: + ospVersion: "16.2" + provisioningStatus: + clientReady: true + desiredCount: 1 + readyCount: 1 + reason: All requested OSVMSets have been provisioned + state: Provisioned + vipStatus: + controlplane: + annotatedForDeletion: false + hostRef: controlplane + hostname: controlplane + ipaddresses: + ctlplane: 2001:db8:fd00:2000::10/64 + provisioningState: Provisioned +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackVMSet +metadata: + finalizers: + - openstackvmsets.osp-director.openstack.org/virtualmachine + name: controller + namespace: openstack +spec: + baseImageVolumeName: controller-base-img + cores: 6 + ctlplaneInterface: enp2s0 + deploymentSSHSecret: osp-controlplane-ssh-keys + diskSize: 50 + domainName: ostest.test.metalkube.org + isTripleoRole: true + memory: 20 + networks: + - ctlplane + passwordSecret: userpassword + roleName: Controller + storageClass: host-nfs-storageclass + vmCount: 0 +status: + baseImageDVReady: true + provisioningStatus: + reason: No VirtualMachines have been requested + state: Empty +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackClient +metadata: + name: openstackclient + namespace: openstack +spec: + cloudName: overcloud + deploymentSSHSecret: osp-controlplane-ssh-keys + domainName: ostest.test.metalkube.org + gitSecret: git-secret + imageURL: registry.redhat.io/rhosp-rhel8/openstack-tripleoclient:16.2 + networks: + - ctlplane + runGID: 42401 + runUID: 42401 + storageClass: host-nfs-storageclass +status: + netStatus: + openstackclient-0: + annotatedForDeletion: false + hostRef: openstackclient-0 + hostname: openstackclient-0 + ipaddresses: + ctlplane: 2001:db8:fd00:2000::251/64 + provisioningState: Provisioned +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNet +metadata: + finalizers: + - openstacknet.osp-director.openstack.org + labels: + ooo-ctlplane-network: "true" + ooo-netname: Control + ooo-netname-lower: ctlplane + ooo-subnetname: ctlplane + osp-director.openstack.org/controller: osp-openstacknetconfig + osp-director.openstack.org/name: openstacknetconfig + osp-director.openstack.org/namespace: openstack + name: ctlplane + namespace: openstack +spec: + allocationEnd: 2001:db8:fd00:2000:ffff:ffff:ffff:fffe + allocationStart: 2001:db8:fd00:2000::100 + attachConfiguration: br-osp + cidr: 2001:db8:fd00:2000::/64 + domainName: ctlplane.localdomain + gateway: 2001:db8:fd00:2000::1 + mtu: 1500 + name: Control + nameLower: ctlplane + roleReservations: + ControlPlane: + addToPredictableIPs: true + reservations: + - deleted: false + hostname: controlplane + ip: 2001:db8:fd00:2000::10 + vip: true + OpenstackClientopenstackclient: + addToPredictableIPs: false + reservations: + - deleted: false + hostname: openstackclient-0 + ip: 2001:db8:fd00:2000::251 + vip: false + routes: [] + vip: true + vlan: 0 +status: + currentState: Configured + reservations: + controlplane: + deleted: false + ip: 2001:db8:fd00:2000::10 + openstackclient-0: + deleted: false + ip: 2001:db8:fd00:2000::251 + reservedIpCount: 2 +--- +apiVersion: v1 +kind: Secret +metadata: + labels: + osp-director.openstack.org/controller: osp-controlplane + osp-director.openstack.org/name: overcloud + osp-director.openstack.org/namespace: openstack + name: tripleo-passwords + namespace: openstack +type: Opaque +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackMACAddress +metadata: + name: openstacknetconfig + namespace: openstack +spec: + physNetworks: + - macPrefix: fa:16:3a + name: datacentre + roleReservations: + Controller: + reservations: {} +status: + currentState: Created + macReservations: {} + reservedMACCount: 0 diff --git a/tests/kuttl/common/tests/create_openstacknetconfig-assert.yaml b/tests/kuttl/common/tests/create_openstacknetconfig-assert.yaml index 32fcefab..9673325e 100644 --- a/tests/kuttl/common/tests/create_openstacknetconfig-assert.yaml +++ b/tests/kuttl/common/tests/create_openstacknetconfig-assert.yaml @@ -190,23 +190,62 @@ spec: name: datacentre - macPrefix: fa:16:3b name: datacentre2 - staticReservations: - compute-0: - deleted: false - reservations: - datacentre: fa:16:3a:bb:bb:bb - datacentre2: fa:16:3b:bb:bb:bb - controller-0: - deleted: false - reservations: - datacentre: fa:16:3a:aa:aa:aa - datacentre2: fa:16:3b:aa:aa:aa - controller-1: - deleted: false - reservations: - datacentre: fa:16:3a:aa:aa:bb - datacentre2: fa:16:3b:aa:aa:bb preserveReservations: true + reservations: + compute-0: + ipReservations: + ctlplane: 192.168.25.40 + internal_api: 172.17.0.40 + storage: 172.18.0.40 + tenant: 172.20.0.40 + macReservations: + datacentre: fa:16:3a:bb:bb:bb + datacentre2: fa:16:3b:bb:bb:bb + controller-0: + ipReservations: + ctlplane: 192.168.25.20 + external: 10.0.0.20 + internal_api: 172.17.0.20 + storage: 172.18.0.20 + storage_mgmt: 172.19.0.20 + tenant: 172.20.0.20 + macReservations: + datacentre: fa:16:3a:aa:aa:aa + datacentre2: fa:16:3b:aa:aa:aa + controller-1: + ipReservations: + ctlplane: 192.168.25.21 + external: 10.0.0.21 + internal_api: 172.17.0.21 + storage: 172.18.0.21 + storage_mgmt: 172.19.0.21 + tenant: 172.20.0.21 + macReservations: + datacentre: fa:16:3a:aa:aa:bb + datacentre2: fa:16:3b:aa:aa:bb + controller-2: + ipReservations: + ctlplane: 192.168.25.22 + external: 10.0.0.22 + internal_api: 172.17.0.22 + storage: 172.18.0.22 + storage_mgmt: 172.19.0.22 + tenant: 172.20.0.22 + macReservations: {} + controlplane: + ipReservations: + ctlplane: 192.168.25.10 + external: 10.0.0.10 + internal_api: 172.17.0.10 + storage: 172.18.0.10 + storage_mgmt: 172.19.0.10 + macReservations: {} + openstackclient-0: + ipReservations: + ctlplane: 192.168.25.251 + external: 10.0.0.251 + internal_api: 172.17.0.251 + macReservations: {} status: provisioningStatus: attachDesiredCount: 2 diff --git a/tests/kuttl/common/tests/create_openstacknetconfig_single_net-assert.yaml b/tests/kuttl/common/tests/create_openstacknetconfig_single_net-assert.yaml index 5064d1bd..245ec7de 100644 --- a/tests/kuttl/common/tests/create_openstacknetconfig_single_net-assert.yaml +++ b/tests/kuttl/common/tests/create_openstacknetconfig_single_net-assert.yaml @@ -71,9 +71,17 @@ spec: physNetworks: - macPrefix: fa:16:3a name: datacentre - staticReservations: {} preserveReservations: true + reservations: + controlplane: + ipReservations: + ctlplane: 192.168.25.10 + macReservations: {} + openstackclient-0: + ipReservations: + ctlplane: 192.168.25.251 status: + hosts: {} provisioningStatus: attachDesiredCount: 1 attachReadyCount: 1 diff --git a/tests/kuttl/common/tests/create_openstacknetconfig_single_net_ipv6-assert.yaml b/tests/kuttl/common/tests/create_openstacknetconfig_single_net_ipv6-assert.yaml new file mode 100644 index 00000000..f133b67b --- /dev/null +++ b/tests/kuttl/common/tests/create_openstacknetconfig_single_net_ipv6-assert.yaml @@ -0,0 +1,226 @@ +# +# Check for: +# +# - 1 OpenstackNetworkConfig +# - 2 OpenStackNetworkAttachment +# - 2 NodeNetworkConfigurationPolicy +# - 6 OpenStackNets +# - 1 OpenStackMACAddress +# + +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNetConfig +metadata: + finalizers: + - openstacknetconfig.osp-director.openstack.org + name: openstacknetconfig + namespace: openstack +spec: +spec: + attachConfigurations: + br-osp: + nodeNetworkConfigurationPolicy: + desiredState: + interfaces: + - bridge: + options: + stp: + enabled: false + port: + - name: enp7s0 + description: Linux bridge with enp7s0 as a port + mtu: 1500 + name: br-osp + state: up + type: linux-bridge + nodeSelector: + node-role.kubernetes.io/worker: "" + nodeSriovConfigurationPolicy: + desiredState: + deviceType: vfio-pci + mtu: 9000 + numVfs: 0 + port: "" + spoofCheck: "on" + trust: "off" + dnsServers: [] + domainName: localdomain + networks: + - isControlPlane: true + mtu: 1500 + name: Control + nameLower: ctlplane + subnets: + - attachConfiguration: br-osp + ipv4: + allocationEnd: "" + allocationStart: "" + cidr: "" + gateway: "" + routes: [] + ipv6: + allocationEnd: 2001:db8:fd00:2000:ffff:ffff:ffff:fffe + allocationStart: 2001:db8:fd00:2000::100 + cidr: 2001:db8:fd00:2000::/64 + gateway: 2001:db8:fd00:2000::1 + routes: [] + name: ctlplane + vlan: 0 + vip: true + ovnBridgeMacMappings: + physNetworks: + - macPrefix: fa:16:3a + name: datacentre + preserveReservations: true + reservations: + controlplane: + ipReservations: + ctlplane: 2001:db8:fd00:2000::10 + macReservations: {} + openstackclient-0: + ipReservations: + ctlplane: 2001:db8:fd00:2000::251 +status: + hosts: {} + provisioningStatus: + attachDesiredCount: 1 + attachReadyCount: 1 + netDesiredCount: 1 + netReadyCount: 1 + physNetDesiredCount: 1 + physNetReadyCount: 1 + reason: OpenStackNetConfig openstacknetconfig all resources configured + state: Configured +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNetAttachment +metadata: + finalizers: + - openstacknetattachment + labels: + bridge: br-osp + ooo-attach-reference: br-osp + ooo-attach-type: bridge + osp-director.openstack.org/controller: osp-openstacknetconfig + osp-director.openstack.org/name: openstacknetconfig + osp-director.openstack.org/namespace: openstack + name: br-osp-bridge + namespace: openstack +spec: + attachConfiguration: + nodeNetworkConfigurationPolicy: + desiredState: + interfaces: + - bridge: + options: + stp: + enabled: false + port: + - name: enp7s0 + description: Linux bridge with enp7s0 as a port + mtu: 1500 + name: br-osp + state: up + type: linux-bridge + nodeSelector: + node-role.kubernetes.io/worker: "" + nodeSriovConfigurationPolicy: + desiredState: + deviceType: vfio-pci + mtu: 9000 + numVfs: 0 + port: "" + spoofCheck: "on" + trust: "off" +--- +apiVersion: nmstate.io/v1alpha1 +kind: NodeNetworkConfigurationPolicy +metadata: + finalizers: + - openstacknetattachment + labels: + ooo-bridge: br-osp + osp-director.openstack.org/controller: osp-openstacknetattach + osp-director.openstack.org/name: br-osp-bridge + osp-director.openstack.org/namespace: openstack + name: br-osp +spec: + desiredState: + interfaces: + - bridge: + options: + stp: + enabled: false + port: + - name: enp7s0 + description: Linux bridge with enp7s0 as a port + name: br-osp + state: up + type: linux-bridge + nodeSelector: + node-role.kubernetes.io/worker: "" +status: + conditions: + - reason: SuccessfullyConfigured + status: "True" + type: Available + - reason: SuccessfullyConfigured + status: "False" + type: Degraded +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNet +metadata: + finalizers: + - openstacknet.osp-director.openstack.org + labels: + ooo-netname: Control + ooo-netname-lower: ctlplane + ooo-subnetname: ctlplane + osp-director.openstack.org/controller: osp-openstacknetconfig + osp-director.openstack.org/name: openstacknetconfig + osp-director.openstack.org/namespace: openstack + name: ctlplane + namespace: openstack +spec: + allocationEnd: 2001:db8:fd00:2000:ffff:ffff:ffff:fffe + allocationStart: 2001:db8:fd00:2000::100 + attachConfiguration: br-osp + cidr: 2001:db8:fd00:2000::/64 + gateway: 2001:db8:fd00:2000::1 + mtu: 1500 + name: Control + nameLower: ctlplane + vip: true + vlan: 0 +status: + conditions: + - message: OpenStackNet ctlplane has been successfully configured on targeted node(s) + reason: OpenStackNet ctlplane has been successfully configured on targeted node(s) + status: "True" + type: Configured + currentState: Configured + reservations: {} + reservedIpCount: 0 +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackMACAddress +metadata: + finalizers: + - openstackmacaddress.osp-director.openstack.org + name: openstacknetconfig + namespace: openstack +spec: + physNetworks: + - macPrefix: fa:16:3a + name: datacentre + roleReservations: {} +status: + conditions: + - message: All MAC addresses created + reason: MACAddressesCreated + status: "True" + type: Created + currentState: Created + macReservations: {} + reservedMACCount: 0 diff --git a/tests/kuttl/common/tests/create_openstacknetconfig_single_net_ipv6.yaml b/tests/kuttl/common/tests/create_openstacknetconfig_single_net_ipv6.yaml new file mode 100644 index 00000000..23ea2e1b --- /dev/null +++ b/tests/kuttl/common/tests/create_openstacknetconfig_single_net_ipv6.yaml @@ -0,0 +1,9 @@ +# +# First, create all OpenStackNetConfig with single ipv6 net +# + +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: oc apply -f ../../../../config/samples/osp-director_v1beta1_openstacknetconfig_single_net_ipv6.yaml + namespaced: true diff --git a/tests/kuttl/common/tests/scale_down_openstackcontrolplane_single_controller-assert.yaml b/tests/kuttl/common/tests/scale_down_openstackcontrolplane_single_controller-assert.yaml index b902d249..42116212 100644 --- a/tests/kuttl/common/tests/scale_down_openstackcontrolplane_single_controller-assert.yaml +++ b/tests/kuttl/common/tests/scale_down_openstackcontrolplane_single_controller-assert.yaml @@ -24,7 +24,7 @@ status: hostRef: controlplane hostname: controlplane ipaddresses: - ctlplane: 192.168.25.100/24 + ctlplane: 192.168.25.10/24 external: 10.0.0.10/24 internal_api: 172.17.0.10/24 storage: 172.18.0.10/24 @@ -68,12 +68,12 @@ status: hostRef: controller-2 hostname: controller-2 ipaddresses: - ctlplane: 192.168.25.104/24 - external: 10.0.0.14/24 - internal_api: 172.17.0.14/24 - storage: 172.18.0.13/24 - storage_mgmt: 172.19.0.13/24 - tenant: 172.20.0.12/24 + ctlplane: 192.168.25.22/24 + external: 10.0.0.22/24 + internal_api: 172.17.0.22/24 + storage: 172.18.0.22/24 + storage_mgmt: 172.19.0.22/24 + tenant: 172.20.0.22/24 provisioningState: Provisioned --- apiVersion: kubevirt.io/v1alpha3 @@ -102,48 +102,48 @@ spec: reservations: - deleted: false hostname: controlplane - ip: 192.168.25.100 + ip: 192.168.25.10 vip: true Controller: addToPredictableIPs: true reservations: - deleted: true hostname: controller-0 - ip: 192.168.25.102 + ip: 192.168.25.20 vip: false - deleted: true hostname: controller-1 - ip: 192.168.25.103 + ip: 192.168.25.21 vip: false - deleted: false hostname: controller-2 - ip: 192.168.25.104 + ip: 192.168.25.22 vip: false OpenstackClientopenstackclient: addToPredictableIPs: false reservations: - deleted: false hostname: openstackclient-0 - ip: 192.168.25.101 + ip: 192.168.25.251 vip: false status: currentState: Configured reservations: controller-0: deleted: true - ip: 192.168.25.102 + ip: 192.168.25.20 controller-1: deleted: true - ip: 192.168.25.103 + ip: 192.168.25.21 controller-2: deleted: false - ip: 192.168.25.104 + ip: 192.168.25.22 controlplane: deleted: false - ip: 192.168.25.100 + ip: 192.168.25.10 openstackclient-0: deleted: false - ip: 192.168.25.101 + ip: 192.168.25.251 reservedIpCount: 5 --- apiVersion: osp-director.openstack.org/v1beta1 @@ -167,41 +167,41 @@ spec: reservations: - deleted: true hostname: controller-0 - ip: 10.0.0.12 + ip: 10.0.0.20 vip: false - deleted: true hostname: controller-1 - ip: 10.0.0.13 + ip: 10.0.0.21 vip: false - deleted: false hostname: controller-2 - ip: 10.0.0.14 + ip: 10.0.0.22 vip: false OpenstackClientopenstackclient: addToPredictableIPs: false reservations: - deleted: false hostname: openstackclient-0 - ip: 10.0.0.11 + ip: 10.0.0.251 vip: false status: currentState: Configured reservations: controller-0: deleted: true - ip: 10.0.0.12 + ip: 10.0.0.20 controller-1: deleted: true - ip: 10.0.0.13 + ip: 10.0.0.21 controller-2: deleted: false - ip: 10.0.0.14 + ip: 10.0.0.22 controlplane: deleted: false ip: 10.0.0.10 openstackclient-0: deleted: false - ip: 10.0.0.11 + ip: 10.0.0.251 reservedIpCount: 5 --- apiVersion: osp-director.openstack.org/v1beta1 @@ -225,41 +225,41 @@ spec: reservations: - deleted: true hostname: controller-0 - ip: 172.17.0.12 + ip: 172.17.0.20 vip: false - deleted: true hostname: controller-1 - ip: 172.17.0.13 + ip: 172.17.0.21 vip: false - deleted: false hostname: controller-2 - ip: 172.17.0.14 + ip: 172.17.0.22 vip: false OpenstackClientopenstackclient: addToPredictableIPs: false reservations: - deleted: false hostname: openstackclient-0 - ip: 172.17.0.11 + ip: 172.17.0.251 vip: false status: currentState: Configured reservations: controller-0: deleted: true - ip: 172.17.0.12 + ip: 172.17.0.20 controller-1: deleted: true - ip: 172.17.0.13 + ip: 172.17.0.21 controller-2: deleted: false - ip: 172.17.0.14 + ip: 172.17.0.22 controlplane: deleted: false ip: 172.17.0.10 openstackclient-0: deleted: false - ip: 172.17.0.11 + ip: 172.17.0.251 reservedIpCount: 5 --- apiVersion: osp-director.openstack.org/v1beta1 @@ -283,28 +283,28 @@ spec: reservations: - deleted: true hostname: controller-0 - ip: 172.18.0.11 + ip: 172.18.0.20 vip: false - deleted: true hostname: controller-1 - ip: 172.18.0.12 + ip: 172.18.0.21 vip: false - deleted: false hostname: controller-2 - ip: 172.18.0.13 + ip: 172.18.0.22 vip: false status: currentState: Configured reservations: controller-0: deleted: true - ip: 172.18.0.11 + ip: 172.18.0.20 controller-1: deleted: true - ip: 172.18.0.12 + ip: 172.18.0.21 controller-2: deleted: false - ip: 172.18.0.13 + ip: 172.18.0.22 controlplane: deleted: false ip: 172.18.0.10 @@ -331,28 +331,28 @@ spec: reservations: - deleted: true hostname: controller-0 - ip: 172.19.0.11 + ip: 172.19.0.20 vip: false - deleted: true hostname: controller-1 - ip: 172.19.0.12 + ip: 172.19.0.21 vip: false - deleted: false hostname: controller-2 - ip: 172.19.0.13 + ip: 172.19.0.22 vip: false status: currentState: Configured reservations: controller-0: deleted: true - ip: 172.19.0.11 + ip: 172.19.0.20 controller-1: deleted: true - ip: 172.19.0.12 + ip: 172.19.0.21 controller-2: deleted: false - ip: 172.19.0.13 + ip: 172.19.0.22 controlplane: deleted: false ip: 172.19.0.10 @@ -372,28 +372,28 @@ spec: reservations: - deleted: true hostname: controller-0 - ip: 172.20.0.10 + ip: 172.20.0.20 vip: false - deleted: true hostname: controller-1 - ip: 172.20.0.11 + ip: 172.20.0.21 vip: false - deleted: false hostname: controller-2 - ip: 172.20.0.12 + ip: 172.20.0.22 vip: false status: currentState: Configured reservations: controller-0: deleted: true - ip: 172.20.0.10 + ip: 172.20.0.20 controller-1: deleted: true - ip: 172.20.0.11 + ip: 172.20.0.21 controller-2: deleted: false - ip: 172.20.0.12 + ip: 172.20.0.22 reservedIpCount: 3 --- apiVersion: osp-director.openstack.org/v1beta1 diff --git a/tests/kuttl/common/tests/scale_down_openstackcontrolplane_single_controller.yaml b/tests/kuttl/common/tests/scale_down_openstackcontrolplane_single_controller.yaml index f8b5874a..3d9f9965 100644 --- a/tests/kuttl/common/tests/scale_down_openstackcontrolplane_single_controller.yaml +++ b/tests/kuttl/common/tests/scale_down_openstackcontrolplane_single_controller.yaml @@ -15,4 +15,9 @@ commands: oc patch openstackcontrolplane overcloud --type='json' -p='[{"op": "replace", "path": "/spec/virtualMachineRoles/controller/roleCount", "value":1}]' namespaced: true - command: | - sleep 5 + sleep 20 + - script: | + # Remove bindings of PV's in Released state + for i in $(oc get pv | egrep "Failed|Released" | awk {'print $1'}); do + oc patch pv $i --type='json' -p='[{"op": "remove", "path": "/spec/claimRef"}]' + done diff --git a/tests/kuttl/common/tests/scale_up_openstackcontrolplane_3_controllers-assert.yaml b/tests/kuttl/common/tests/scale_up_openstackcontrolplane_3_controllers-assert.yaml index ff9c31f9..edd6fcc8 100644 --- a/tests/kuttl/common/tests/scale_up_openstackcontrolplane_3_controllers-assert.yaml +++ b/tests/kuttl/common/tests/scale_up_openstackcontrolplane_3_controllers-assert.yaml @@ -57,36 +57,36 @@ status: hostRef: controller-0 hostname: controller-0 ipaddresses: - ctlplane: 192.168.25.102/24 - external: 10.0.0.12/24 - internal_api: 172.17.0.12/24 - storage: 172.18.0.11/24 - storage_mgmt: 172.19.0.11/24 - tenant: 172.20.0.10/24 + ctlplane: 192.168.25.20/24 + external: 10.0.0.20/24 + internal_api: 172.17.0.20/24 + storage: 172.18.0.20/24 + storage_mgmt: 172.19.0.20/24 + tenant: 172.20.0.20/24 provisioningState: Provisioned controller-1: annotatedForDeletion: false hostRef: controller-1 hostname: controller-1 ipaddresses: - ctlplane: 192.168.25.103/24 - external: 10.0.0.13/24 - internal_api: 172.17.0.13/24 - storage: 172.18.0.12/24 - storage_mgmt: 172.19.0.12/24 - tenant: 172.20.0.11/24 + ctlplane: 192.168.25.21/24 + external: 10.0.0.21/24 + internal_api: 172.17.0.21/24 + storage: 172.18.0.21/24 + storage_mgmt: 172.19.0.21/24 + tenant: 172.20.0.21/24 provisioningState: Provisioned controller-2: annotatedForDeletion: false hostRef: controller-2 hostname: controller-2 ipaddresses: - ctlplane: 192.168.25.104/24 - external: 10.0.0.14/24 - internal_api: 172.17.0.14/24 - storage: 172.18.0.13/24 - storage_mgmt: 172.19.0.13/24 - tenant: 172.20.0.12/24 + ctlplane: 192.168.25.22/24 + external: 10.0.0.22/24 + internal_api: 172.17.0.22/24 + storage: 172.18.0.22/24 + storage_mgmt: 172.19.0.22/24 + tenant: 172.20.0.22/24 provisioningState: Provisioned --- apiVersion: kubevirt.io/v1alpha3 @@ -139,48 +139,48 @@ spec: reservations: - deleted: false hostname: controlplane - ip: 192.168.25.100 + ip: 192.168.25.10 vip: true Controller: addToPredictableIPs: true reservations: - deleted: false hostname: controller-0 - ip: 192.168.25.102 + ip: 192.168.25.20 vip: false - deleted: false hostname: controller-1 - ip: 192.168.25.103 + ip: 192.168.25.21 vip: false - deleted: false hostname: controller-2 - ip: 192.168.25.104 + ip: 192.168.25.22 vip: false OpenstackClientopenstackclient: addToPredictableIPs: false reservations: - deleted: false hostname: openstackclient-0 - ip: 192.168.25.101 + ip: 192.168.25.251 vip: false status: currentState: Configured reservations: controller-0: deleted: false - ip: 192.168.25.102 + ip: 192.168.25.20 controller-1: deleted: false - ip: 192.168.25.103 + ip: 192.168.25.21 controller-2: deleted: false - ip: 192.168.25.104 + ip: 192.168.25.22 controlplane: deleted: false - ip: 192.168.25.100 + ip: 192.168.25.10 openstackclient-0: deleted: false - ip: 192.168.25.101 + ip: 192.168.25.251 reservedIpCount: 5 --- apiVersion: osp-director.openstack.org/v1beta1 @@ -204,41 +204,41 @@ spec: reservations: - deleted: false hostname: controller-0 - ip: 10.0.0.12 + ip: 10.0.0.20 vip: false - deleted: false hostname: controller-1 - ip: 10.0.0.13 + ip: 10.0.0.21 vip: false - deleted: false hostname: controller-2 - ip: 10.0.0.14 + ip: 10.0.0.22 vip: false OpenstackClientopenstackclient: addToPredictableIPs: false reservations: - deleted: false hostname: openstackclient-0 - ip: 10.0.0.11 + ip: 10.0.0.251 vip: false status: currentState: Configured reservations: controller-0: deleted: false - ip: 10.0.0.12 + ip: 10.0.0.20 controller-1: deleted: false - ip: 10.0.0.13 + ip: 10.0.0.21 controller-2: deleted: false - ip: 10.0.0.14 + ip: 10.0.0.22 controlplane: deleted: false ip: 10.0.0.10 openstackclient-0: deleted: false - ip: 10.0.0.11 + ip: 10.0.0.251 reservedIpCount: 5 --- apiVersion: osp-director.openstack.org/v1beta1 @@ -262,41 +262,41 @@ spec: reservations: - deleted: false hostname: controller-0 - ip: 172.17.0.12 + ip: 172.17.0.20 vip: false - deleted: false hostname: controller-1 - ip: 172.17.0.13 + ip: 172.17.0.21 vip: false - deleted: false hostname: controller-2 - ip: 172.17.0.14 + ip: 172.17.0.22 vip: false OpenstackClientopenstackclient: addToPredictableIPs: false reservations: - deleted: false hostname: openstackclient-0 - ip: 172.17.0.11 + ip: 172.17.0.251 vip: false status: currentState: Configured reservations: controller-0: deleted: false - ip: 172.17.0.12 + ip: 172.17.0.20 controller-1: deleted: false - ip: 172.17.0.13 + ip: 172.17.0.21 controller-2: deleted: false - ip: 172.17.0.14 + ip: 172.17.0.22 controlplane: deleted: false ip: 172.17.0.10 openstackclient-0: deleted: false - ip: 172.17.0.11 + ip: 172.17.0.251 reservedIpCount: 5 --- apiVersion: osp-director.openstack.org/v1beta1 @@ -320,28 +320,28 @@ spec: reservations: - deleted: false hostname: controller-0 - ip: 172.18.0.11 + ip: 172.18.0.20 vip: false - deleted: false hostname: controller-1 - ip: 172.18.0.12 + ip: 172.18.0.21 vip: false - deleted: false hostname: controller-2 - ip: 172.18.0.13 + ip: 172.18.0.22 vip: false status: currentState: Configured reservations: controller-0: deleted: false - ip: 172.18.0.11 + ip: 172.18.0.20 controller-1: deleted: false - ip: 172.18.0.12 + ip: 172.18.0.21 controller-2: deleted: false - ip: 172.18.0.13 + ip: 172.18.0.22 controlplane: deleted: false ip: 172.18.0.10 @@ -368,28 +368,28 @@ spec: reservations: - deleted: false hostname: controller-0 - ip: 172.19.0.11 + ip: 172.19.0.20 vip: false - deleted: false hostname: controller-1 - ip: 172.19.0.12 + ip: 172.19.0.21 vip: false - deleted: false hostname: controller-2 - ip: 172.19.0.13 + ip: 172.19.0.22 vip: false status: currentState: Configured reservations: controller-0: deleted: false - ip: 172.19.0.11 + ip: 172.19.0.20 controller-1: deleted: false - ip: 172.19.0.12 + ip: 172.19.0.21 controller-2: deleted: false - ip: 172.19.0.13 + ip: 172.19.0.22 controlplane: deleted: false ip: 172.19.0.10 @@ -409,28 +409,28 @@ spec: reservations: - deleted: false hostname: controller-0 - ip: 172.20.0.10 + ip: 172.20.0.20 vip: false - deleted: false hostname: controller-1 - ip: 172.20.0.11 + ip: 172.20.0.21 vip: false - deleted: false hostname: controller-2 - ip: 172.20.0.12 + ip: 172.20.0.22 vip: false status: currentState: Configured reservations: controller-0: deleted: false - ip: 172.20.0.10 + ip: 172.20.0.20 controller-1: deleted: false - ip: 172.20.0.11 + ip: 172.20.0.21 controller-2: deleted: false - ip: 172.20.0.12 + ip: 172.20.0.22 reservedIpCount: 3 --- apiVersion: osp-director.openstack.org/v1beta1 diff --git a/tests/kuttl/common/tests/scale_up_openstackcontrolplane_single_controller_single_net-assert.yaml b/tests/kuttl/common/tests/scale_up_openstackcontrolplane_single_controller_single_net-assert.yaml index 1e07903c..ce8b0574 100644 --- a/tests/kuttl/common/tests/scale_up_openstackcontrolplane_single_controller_single_net-assert.yaml +++ b/tests/kuttl/common/tests/scale_up_openstackcontrolplane_single_controller_single_net-assert.yaml @@ -52,7 +52,7 @@ status: hostRef: controller-0 hostname: controller-0 ipaddresses: - ctlplane: 192.168.25.102/24 + ctlplane: 192.168.25.100/24 provisioningState: Provisioned --- apiVersion: kubevirt.io/v1alpha3 @@ -81,34 +81,34 @@ spec: reservations: - deleted: false hostname: controlplane - ip: 192.168.25.100 + ip: 192.168.25.10 vip: true Controller: addToPredictableIPs: true reservations: - deleted: false hostname: controller-0 - ip: 192.168.25.102 + ip: 192.168.25.100 vip: false OpenstackClientopenstackclient: addToPredictableIPs: false reservations: - deleted: false hostname: openstackclient-0 - ip: 192.168.25.101 + ip: 192.168.25.251 vip: false status: currentState: Configured reservations: controller-0: deleted: false - ip: 192.168.25.102 + ip: 192.168.25.100 controlplane: deleted: false - ip: 192.168.25.100 + ip: 192.168.25.10 openstackclient-0: deleted: false - ip: 192.168.25.101 + ip: 192.168.25.251 reservedIpCount: 3 --- apiVersion: osp-director.openstack.org/v1beta1 diff --git a/tests/kuttl/common/tests/scale_up_openstackcontrolplane_single_controller_single_net_ipv6-assert.yaml b/tests/kuttl/common/tests/scale_up_openstackcontrolplane_single_controller_single_net_ipv6-assert.yaml new file mode 100644 index 00000000..f2d53f43 --- /dev/null +++ b/tests/kuttl/common/tests/scale_up_openstackcontrolplane_single_controller_single_net_ipv6-assert.yaml @@ -0,0 +1,131 @@ +# +# Check for: +# +# - 1 OpenStackControlPlane +# - 1 OpenStackVMSet +# - 1 VirtualMachines +# - 1 OpenStackNets (IP reservations) +# - 1 OpenStackMACAddress +# + +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackControlPlane +metadata: + name: overcloud + namespace: openstack +spec: + virtualMachineRoles: + controller: + roleCount: 1 +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackVMSet +metadata: + finalizers: + - openstackvmsets.osp-director.openstack.org/virtualmachine + name: controller + namespace: openstack +spec: + baseImageVolumeName: controller-base-img + cores: 6 + ctlplaneInterface: enp2s0 + deploymentSSHSecret: osp-controlplane-ssh-keys + diskSize: 50 + domainName: ostest.test.metalkube.org + isTripleoRole: true + memory: 20 + networks: + - ctlplane + passwordSecret: userpassword + roleName: Controller + storageClass: host-nfs-storageclass + vmCount: 1 +status: + baseImageDVReady: true + provisioningStatus: + readyCount: 1 + reason: All requested VirtualMachines have been provisioned + state: Provisioned + vmHosts: + controller-0: + annotatedForDeletion: false + hostRef: controller-0 + hostname: controller-0 + ipaddresses: + ctlplane: 2001:db8:fd00:2000::101/64 + provisioningState: Provisioned +--- +apiVersion: kubevirt.io/v1alpha3 +kind: VirtualMachine +metadata: + name: controller-0 + namespace: openstack +status: + conditions: + - status: "True" + type: Ready + created: true + ready: true +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNet +metadata: + finalizers: + - openstacknet.osp-director.openstack.org + name: ctlplane + namespace: openstack +spec: + roleReservations: + ControlPlane: + addToPredictableIPs: true + reservations: + - deleted: false + hostname: controlplane + ip: 2001:db8:fd00:2000::10 + vip: true + Controller: + addToPredictableIPs: true + reservations: + - deleted: false + hostname: controller-0 + ip: 2001:db8:fd00:2000::101 + vip: false + OpenstackClientopenstackclient: + addToPredictableIPs: false + reservations: + - deleted: false + hostname: openstackclient-0 + ip: 2001:db8:fd00:2000::251 + vip: false +status: + currentState: Configured + reservations: + controller-0: + deleted: false + ip: 2001:db8:fd00:2000::101 + controlplane: + deleted: false + ip: 2001:db8:fd00:2000::10 + openstackclient-0: + deleted: false + ip: 2001:db8:fd00:2000::251 + reservedIpCount: 3 +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackMACAddress +metadata: + finalizers: + - openstackmacaddress.osp-director.openstack.org + name: openstacknetconfig + namespace: openstack +spec: + physNetworks: + - macPrefix: fa:16:3a + name: datacentre + roleReservations: + Controller: + reservations: + controller-0: + deleted: false +status: + reservedMACCount: 1 diff --git a/tests/kuttl/tests/openstackbaremetalset_scale/03-assert.yaml b/tests/kuttl/tests/openstackbaremetalset_scale/03-assert.yaml index ccbd5098..53fe10b2 100644 --- a/tests/kuttl/tests/openstackbaremetalset_scale/03-assert.yaml +++ b/tests/kuttl/tests/openstackbaremetalset_scale/03-assert.yaml @@ -27,9 +27,9 @@ spec: status: conditions: - message: OpenStackBaremetalSet compute OpenStackProvisionServer local image URL not yet available, requeuing and waiting 30 seconds - reason: Waiting + reason: OpenStackProvisionServerCondReasonProvisioning status: "False" - type: OpenStackProvisionServerNotReady + type: Waiting - message: No BaremetalHost have been requested reason: BaremetalHostCountZero status: "True" @@ -44,7 +44,7 @@ metadata: name: compute-provisionserver namespace: openstack spec: - apacheImageUrl: registry.redhat.io/rhel8/httpd-24@sha256:d63a22b930f0309a8bb160b452147e81ceb1d3fd3df2d78f0a30e763e1d6f0c4 + apacheImageUrl: registry.redhat.io/rhel8/httpd-24@sha256:87d58041da70f094e685511f86f8a83e9b2a67424fcf8cf2530ff071f566350b baseImageUrl: http://192.168.111.1/images/rhel-guest-image-8.4-992.x86_64.qcow2 downloaderImageUrl: registry.redhat.io/rhosp-rhel8-tech-preview/osp-director-downloader@sha256:dadca151e8712eef8b206b69722c558b2aac035a4a3c52e705bf69c26d649567 port: 6190 diff --git a/tests/kuttl/tests/openstackbaremetalset_scale/04-assert.yaml b/tests/kuttl/tests/openstackbaremetalset_scale/04-assert.yaml index 984139b8..ff5991c7 100644 --- a/tests/kuttl/tests/openstackbaremetalset_scale/04-assert.yaml +++ b/tests/kuttl/tests/openstackbaremetalset_scale/04-assert.yaml @@ -33,12 +33,12 @@ status: baremetalHosts: compute-0: annotatedForDeletion: false - ctlplaneIP: 192.168.25.102/24 + ctlplaneIP: 192.168.25.40/24 hostname: compute-0 provisioningState: provisioned compute-1: annotatedForDeletion: false - ctlplaneIP: 192.168.25.103/24 + ctlplaneIP: 192.168.25.100/24 hostname: compute-1 provisioningState: provisioned provisioningStatus: @@ -134,25 +134,25 @@ spec: reservations: - deleted: false hostname: compute-0 - ip: 192.168.25.102 + ip: 192.168.25.40 vip: false - deleted: false hostname: compute-1 - ip: 192.168.25.103 + ip: 192.168.25.100 vip: false ControlPlane: addToPredictableIPs: true reservations: - deleted: false hostname: controlplane - ip: 192.168.25.100 + ip: 192.168.25.10 vip: true OpenstackClientopenstackclient: addToPredictableIPs: false reservations: - deleted: false hostname: openstackclient-0 - ip: 192.168.25.101 + ip: 192.168.25.251 vip: false status: conditions: @@ -164,16 +164,16 @@ status: reservations: compute-0: deleted: false - ip: 192.168.25.102 + ip: 192.168.25.40 compute-1: deleted: false - ip: 192.168.25.103 + ip: 192.168.25.100 controlplane: deleted: false - ip: 192.168.25.100 + ip: 192.168.25.10 openstackclient-0: deleted: false - ip: 192.168.25.101 + ip: 192.168.25.251 reservedIpCount: 4 --- apiVersion: osp-director.openstack.org/v1beta1 @@ -190,11 +190,11 @@ spec: reservations: - deleted: false hostname: compute-0 - ip: 172.17.0.12 + ip: 172.17.0.40 vip: false - deleted: false hostname: compute-1 - ip: 172.17.0.13 + ip: 172.17.0.11 vip: false ControlPlane: addToPredictableIPs: true @@ -208,7 +208,7 @@ spec: reservations: - deleted: false hostname: openstackclient-0 - ip: 172.17.0.11 + ip: 172.17.0.251 vip: false status: conditions: @@ -220,16 +220,16 @@ status: reservations: compute-0: deleted: false - ip: 172.17.0.12 + ip: 172.17.0.40 compute-1: deleted: false - ip: 172.17.0.13 + ip: 172.17.0.11 controlplane: deleted: false ip: 172.17.0.10 openstackclient-0: deleted: false - ip: 172.17.0.11 + ip: 172.17.0.251 reservedIpCount: 4 --- apiVersion: osp-director.openstack.org/v1beta1 @@ -246,11 +246,11 @@ spec: reservations: - deleted: false hostname: compute-0 - ip: 172.20.0.10 + ip: 172.20.0.40 vip: false - deleted: false hostname: compute-1 - ip: 172.20.0.11 + ip: 172.20.0.10 vip: false status: conditions: @@ -262,10 +262,10 @@ status: reservations: compute-0: deleted: false - ip: 172.20.0.10 + ip: 172.20.0.40 compute-1: deleted: false - ip: 172.20.0.11 + ip: 172.20.0.10 reservedIpCount: 2 --- apiVersion: osp-director.openstack.org/v1beta1 diff --git a/tests/kuttl/tests/openstackbaremetalset_scale/05-check_openstackbaremetalset_connectivity.yaml b/tests/kuttl/tests/openstackbaremetalset_scale/05-check_openstackbaremetalset_connectivity.yaml index 8aabc6a2..967b9bb9 100644 --- a/tests/kuttl/tests/openstackbaremetalset_scale/05-check_openstackbaremetalset_connectivity.yaml +++ b/tests/kuttl/tests/openstackbaremetalset_scale/05-check_openstackbaremetalset_connectivity.yaml @@ -9,15 +9,10 @@ commands: sleep 10 RETRIES="${RETRIES:-20}" for i in $(seq 1 $RETRIES); do - SUCCESS="0" - for k in 102 103; do - oc rsh -n openstack openstackclient ssh cloud-admin@192.168.25.$k hostname && SUCCESS=$((SUCCESS+1)); - done - if [ "$SUCCESS" -eq "2" ]; then - break - fi - sleep $i - if [ "$i" -eq "${RETRIES}" ]; then - exit 1 + oc rsh -n openstack openstackclient ansible -m ping -i /home/cloud-admin/ctlplane-ansible-inventory Compute + if [ "$?" -eq "0" ]; then + exit 0 fi + sleep 10 done + exit 1 diff --git a/tests/kuttl/tests/openstackbaremetalset_scale/06-assert.yaml b/tests/kuttl/tests/openstackbaremetalset_scale/06-assert.yaml index 82fc98e8..175f870a 100644 --- a/tests/kuttl/tests/openstackbaremetalset_scale/06-assert.yaml +++ b/tests/kuttl/tests/openstackbaremetalset_scale/06-assert.yaml @@ -29,7 +29,7 @@ status: baremetalHosts: compute-1: annotatedForDeletion: false - ctlplaneIP: 192.168.25.103/24 + ctlplaneIP: 192.168.25.100/24 hostname: compute-1 provisioningState: provisioned provisioningStatus: @@ -104,25 +104,25 @@ spec: reservations: - deleted: true hostname: compute-0 - ip: 192.168.25.102 + ip: 192.168.25.40 vip: false - deleted: false hostname: compute-1 - ip: 192.168.25.103 + ip: 192.168.25.100 vip: false ControlPlane: addToPredictableIPs: true reservations: - deleted: false hostname: controlplane - ip: 192.168.25.100 + ip: 192.168.25.10 vip: true OpenstackClientopenstackclient: addToPredictableIPs: false reservations: - deleted: false hostname: openstackclient-0 - ip: 192.168.25.101 + ip: 192.168.25.251 vip: false status: conditions: @@ -134,16 +134,16 @@ status: reservations: compute-0: deleted: true - ip: 192.168.25.102 + ip: 192.168.25.40 compute-1: deleted: false - ip: 192.168.25.103 + ip: 192.168.25.100 controlplane: deleted: false - ip: 192.168.25.100 + ip: 192.168.25.10 openstackclient-0: deleted: false - ip: 192.168.25.101 + ip: 192.168.25.251 reservedIpCount: 4 --- apiVersion: osp-director.openstack.org/v1beta1 @@ -160,11 +160,11 @@ spec: reservations: - deleted: true hostname: compute-0 - ip: 172.17.0.12 + ip: 172.17.0.40 vip: false - deleted: false hostname: compute-1 - ip: 172.17.0.13 + ip: 172.17.0.11 vip: false ControlPlane: addToPredictableIPs: true @@ -178,7 +178,7 @@ spec: reservations: - deleted: false hostname: openstackclient-0 - ip: 172.17.0.11 + ip: 172.17.0.251 vip: false status: conditions: @@ -190,16 +190,16 @@ status: reservations: compute-0: deleted: true - ip: 172.17.0.12 + ip: 172.17.0.40 compute-1: deleted: false - ip: 172.17.0.13 + ip: 172.17.0.11 controlplane: deleted: false ip: 172.17.0.10 openstackclient-0: deleted: false - ip: 172.17.0.11 + ip: 172.17.0.251 reservedIpCount: 4 --- apiVersion: osp-director.openstack.org/v1beta1 @@ -216,11 +216,11 @@ spec: reservations: - deleted: true hostname: compute-0 - ip: 172.20.0.10 + ip: 172.20.0.40 vip: false - deleted: false hostname: compute-1 - ip: 172.20.0.11 + ip: 172.20.0.10 vip: false status: conditions: @@ -232,10 +232,10 @@ status: reservations: compute-0: deleted: true - ip: 172.20.0.10 + ip: 172.20.0.40 compute-1: deleted: false - ip: 172.20.0.11 + ip: 172.20.0.10 reservedIpCount: 2 --- apiVersion: osp-director.openstack.org/v1beta1 diff --git a/tests/kuttl/tests/openstackbaremetalset_scale/09-assert.yaml b/tests/kuttl/tests/openstackbaremetalset_scale/09-assert.yaml index 0a19c7b4..f89bc860 100644 --- a/tests/kuttl/tests/openstackbaremetalset_scale/09-assert.yaml +++ b/tests/kuttl/tests/openstackbaremetalset_scale/09-assert.yaml @@ -19,14 +19,14 @@ spec: reservations: - deleted: false hostname: controlplane - ip: 192.168.25.100 + ip: 192.168.25.10 vip: true OpenstackClientopenstackclient: addToPredictableIPs: false reservations: - deleted: false hostname: openstackclient-0 - ip: 192.168.25.101 + ip: 192.168.25.251 vip: false status: conditions: @@ -38,10 +38,10 @@ status: reservations: controlplane: deleted: false - ip: 192.168.25.100 + ip: 192.168.25.10 openstackclient-0: deleted: false - ip: 192.168.25.101 + ip: 192.168.25.251 reservedIpCount: 2 --- apiVersion: osp-director.openstack.org/v1beta1 @@ -65,7 +65,7 @@ spec: reservations: - deleted: false hostname: openstackclient-0 - ip: 172.17.0.11 + ip: 172.17.0.251 vip: false status: conditions: @@ -80,7 +80,7 @@ status: ip: 172.17.0.10 openstackclient-0: deleted: false - ip: 172.17.0.11 + ip: 172.17.0.251 reservedIpCount: 2 --- apiVersion: osp-director.openstack.org/v1beta1 diff --git a/tests/kuttl/tests/openstackcontrolplane_scale/04-check_openstackcontrolplane_connectivity.yaml b/tests/kuttl/tests/openstackcontrolplane_scale/04-check_openstackcontrolplane_connectivity.yaml index 19c2351a..19a487cb 100644 --- a/tests/kuttl/tests/openstackcontrolplane_scale/04-check_openstackcontrolplane_connectivity.yaml +++ b/tests/kuttl/tests/openstackcontrolplane_scale/04-check_openstackcontrolplane_connectivity.yaml @@ -9,15 +9,10 @@ commands: sleep 10 RETRIES="${RETRIES:-20}" for i in $(seq 1 $RETRIES); do - SUCCESS="0" - for k in 102 103 104; do - oc rsh -n openstack openstackclient ssh cloud-admin@192.168.25.$k hostname && SUCCESS=$((SUCCESS+1)); - done - if [ "$SUCCESS" -eq "3" ]; then - break - fi - sleep $i - if [ "$i" -eq "${RETRIES}" ]; then - exit 1 + oc rsh -n openstack openstackclient ansible -m ping -i /home/cloud-admin/ctlplane-ansible-inventory Controller + if [ "$?" -eq "0" ]; then + exit 0 fi + sleep 10 done + exit 1 diff --git a/tests/kuttl/tests/openstacknetconfig_immutable_bridge_name/02-assert.yaml b/tests/kuttl/tests/openstacknetconfig_immutable_bridge_name/02-assert.yaml index 8b87ecc8..faa6c827 100644 --- a/tests/kuttl/tests/openstacknetconfig_immutable_bridge_name/02-assert.yaml +++ b/tests/kuttl/tests/openstacknetconfig_immutable_bridge_name/02-assert.yaml @@ -40,8 +40,8 @@ status: attachType: bridge bridgeName: br-osp conditions: - - message: NodeNetworkConfigurationPolicy br-osp configured targeted node(s) - reason: NodeNetworkConfigurationPolicy br-osp configured targeted node(s) + - message: 'NodeNetworkConfigurationPolicy br-osp: 3/3 nodes successfully configured' + reason: 'NodeNetworkConfigurationPolicy br-osp: 3/3 nodes successfully configured' status: "True" type: Configured currentState: Configured diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/00-prep.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/00-prep.yaml new file mode 120000 index 00000000..414efe4b --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/00-prep.yaml @@ -0,0 +1 @@ +../../common/tests/00-prep.yaml \ No newline at end of file diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/01-assert.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/01-assert.yaml new file mode 120000 index 00000000..887fe6b1 --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/01-assert.yaml @@ -0,0 +1 @@ +../../common/tests/create_openstacknetconfig_single_net-assert.yaml \ No newline at end of file diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/01-create_openstacknetconfig_single_net.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/01-create_openstacknetconfig_single_net.yaml new file mode 120000 index 00000000..9576021a --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/01-create_openstacknetconfig_single_net.yaml @@ -0,0 +1 @@ +../../common/tests/create_openstacknetconfig_single_net.yaml \ No newline at end of file diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/02-assert.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/02-assert.yaml new file mode 120000 index 00000000..3af6002d --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/02-assert.yaml @@ -0,0 +1 @@ +../../common/tests/create_openstackcontrolplane_single_net-assert.yaml \ No newline at end of file diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/02-create_openstackcontrolplane_single_net.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/02-create_openstackcontrolplane_single_net.yaml new file mode 120000 index 00000000..4ad45f5e --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/02-create_openstackcontrolplane_single_net.yaml @@ -0,0 +1 @@ +../../common/tests/create_openstackcontrolplane_single_net.yaml \ No newline at end of file diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/03-assert.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/03-assert.yaml new file mode 120000 index 00000000..dbeb68b3 --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/03-assert.yaml @@ -0,0 +1 @@ +../../common/tests/scale_up_openstackcontrolplane_single_controller_single_net-assert.yaml \ No newline at end of file diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/03-scale_up_openstackcontrolplane.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/03-scale_up_openstackcontrolplane.yaml new file mode 120000 index 00000000..dcbce48d --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/03-scale_up_openstackcontrolplane.yaml @@ -0,0 +1 @@ +../../common/tests/scale_up_openstackcontrolplane_single_controller.yaml \ No newline at end of file diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/04-add_static_reservation.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/04-add_static_reservation.yaml new file mode 100644 index 00000000..5781c6ae --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/04-add_static_reservation.yaml @@ -0,0 +1,13 @@ +# +# Add static MAC reservation for controller-1 +# + +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: | + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "add", "path": "/spec/reservations/controller-1", "value": {"ipReservations":{}, "macReservations": {}}}]' + namespaced: true + - command: | + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "add", "path": "/spec/reservations/controller-1/ipReservations", "value": {"ctlplane": "192.168.25.41" }}]' + namespaced: true diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/04-assert.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/04-assert.yaml new file mode 100644 index 00000000..a9014623 --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/04-assert.yaml @@ -0,0 +1,93 @@ +# +# Check for: +# +# - 1 OpenstackNetworkConfig +# + +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNetConfig +metadata: + finalizers: + - openstacknetconfig.osp-director.openstack.org + name: openstacknetconfig + namespace: openstack +spec: +spec: + attachConfigurations: + br-osp: + nodeNetworkConfigurationPolicy: + desiredState: + interfaces: + - bridge: + options: + stp: + enabled: false + port: + - name: enp7s0 + description: Linux bridge with enp7s0 as a port + mtu: 1500 + name: br-osp + state: up + type: linux-bridge + nodeSelector: + node-role.kubernetes.io/worker: "" + nodeSriovConfigurationPolicy: + desiredState: + deviceType: vfio-pci + mtu: 9000 + numVfs: 0 + port: "" + spoofCheck: "on" + trust: "off" + dnsServers: [] + domainName: localdomain + networks: + - isControlPlane: true + mtu: 1500 + name: Control + nameLower: ctlplane + subnets: + - attachConfiguration: br-osp + ipv4: + allocationEnd: 192.168.25.250 + allocationStart: 192.168.25.100 + cidr: 192.168.25.0/24 + gateway: 192.168.25.1 + routes: [] + ipv6: + allocationEnd: "" + allocationStart: "" + cidr: "" + gateway: "" + routes: [] + name: ctlplane + vlan: 0 + vip: true + ovnBridgeMacMappings: + physNetworks: + - macPrefix: fa:16:3a + name: datacentre + preserveReservations: true + reservations: + controller-1: + ipReservations: + ctlplane: 192.168.25.41 + macReservations: {} + controlplane: + ipReservations: + ctlplane: 192.168.25.10 + macReservations: {} + openstackclient-0: + ipReservations: + ctlplane: 192.168.25.251 + macReservations: {} +status: + provisioningStatus: + attachDesiredCount: 1 + attachReadyCount: 1 + netDesiredCount: 1 + netReadyCount: 1 + physNetDesiredCount: 1 + physNetReadyCount: 1 + reason: OpenStackNetConfig openstacknetconfig all resources configured + state: Configured diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/05-assert.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/05-assert.yaml new file mode 100644 index 00000000..a83db440 --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/05-assert.yaml @@ -0,0 +1,112 @@ +# +# Check for: +# +# - 1 OpenstackNetworkConfig +# - 2 OpenStackNetworkAttachment +# - 2 NodeNetworkConfigurationPolicy +# - 6 OpenStackNets +# - 1 OpenStackMACAddress +# + +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNetConfig +metadata: + finalizers: + - openstacknetconfig.osp-director.openstack.org + name: openstacknetconfig + namespace: openstack +spec: + attachConfigurations: + br-osp: + nodeNetworkConfigurationPolicy: + desiredState: + interfaces: + - bridge: + options: + stp: + enabled: false + port: + - name: enp7s0 + description: Linux bridge with enp7s0 as a port + mtu: 1500 + name: br-osp + state: up + type: linux-bridge + nodeSelector: + node-role.kubernetes.io/worker: "" + nodeSriovConfigurationPolicy: + desiredState: + deviceType: vfio-pci + mtu: 9000 + numVfs: 0 + port: "" + spoofCheck: "on" + trust: "off" + dnsServers: [] + domainName: localdomain + networks: + - isControlPlane: true + mtu: 1500 + name: Control + nameLower: ctlplane + subnets: + - attachConfiguration: br-osp + ipv4: + allocationEnd: 192.168.25.250 + allocationStart: 192.168.25.100 + cidr: 192.168.25.0/24 + gateway: 192.168.25.1 + routes: [] + ipv6: + allocationEnd: "" + allocationStart: "" + cidr: "" + gateway: "" + routes: [] + name: ctlplane + vlan: 0 + vip: true + ovnBridgeMacMappings: + physNetworks: + - macPrefix: fa:16:3a + name: datacentre + preserveReservations: true + reservations: + controller-1: + ipReservations: + ctlplane: 192.168.25.41 + macReservations: {} + controller-2: + ipReservations: {} + macReservations: {} + openstackclient-0: + ipReservations: + ctlplane: 192.168.25.251 + macReservations: {} + controlplane: + ipReservations: + ctlplane: 192.168.25.10 + macReservations: {} +status: +status: + hosts: + controller-0: + ipaddresses: + ctlplane: 192.168.25.100/24 + controlplane: + ipaddresses: + ctlplane: 192.168.25.10/24 + ovnBridgeMacAdresses: {} + openstackclient-0: + ipaddresses: + ctlplane: 192.168.25.251/24 + ovnBridgeMacAdresses: {} + provisioningStatus: + attachDesiredCount: 1 + attachReadyCount: 1 + netDesiredCount: 1 + netReadyCount: 1 + physNetDesiredCount: 1 + physNetReadyCount: 1 + reason: OpenStackNetConfig openstacknetconfig all resources configured + state: Configured diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/05-webhook_validations.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/05-webhook_validations.yaml new file mode 100644 index 00000000..639bf20b --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/05-webhook_validations.yaml @@ -0,0 +1,29 @@ +# +# verify no changes on: +# - add reservation with dupe from dynamic created IP +# - add reservation with dupe from static IP reservation +# - add reservation with wrong IP format +# + +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: | + # add new empty reservation for controller-2 + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "add", "path": "/spec/reservations/controller-2", "value": {"ipReservations":{}, "macReservations": {}}}]' + namespaced: true + - command: | + # add static reservation with dupe dynamic IP entry (IP from controller-0) + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "replace", "path": "/spec/reservations/controller-2/ipReservations/ctlplane", "value": "192.168.25.100"}]' + namespaced: true + ignoreFailure: true + - command: | + # add static reservation with dupe static IP entry (IP from controller-1) + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "replace", "path": "/spec/reservations/controller-2/ipReservations/ctlplane", "value": "192.168.25.41"}]' + namespaced: true + ignoreFailure: true + - command: | + # add static reservation with wrong IP format + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "add", "path": "/spec/reservations/controller-2/ipReservations/ctlplane", "value": "192.168.25.25.42" }]' + namespaced: true + ignoreFailure: true diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/06-add_second_reservation.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/06-add_second_reservation.yaml new file mode 100644 index 00000000..de1a7cb5 --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/06-add_second_reservation.yaml @@ -0,0 +1,14 @@ +# +# Add static IP reservation for controller-2 +# + +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: | + # add new empty reservation for controller-2 + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "add", "path": "/spec/reservations/controller-2", "value": {"ipReservations":{}, "macReservations": {}}}]' + namespaced: true + - command: | + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "replace", "path": "/spec/reservations/controller-2/ipReservations/ctlplane", "value": "192.168.25.42"}]' + namespaced: true diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/06-assert.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/06-assert.yaml new file mode 100644 index 00000000..d34626e0 --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/06-assert.yaml @@ -0,0 +1,97 @@ +# +# Check for: +# +# - 1 OpenstackNetworkConfig +# + +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNetConfig +metadata: + finalizers: + - openstacknetconfig.osp-director.openstack.org + name: openstacknetconfig + namespace: openstack +spec: +spec: + attachConfigurations: + br-osp: + nodeNetworkConfigurationPolicy: + desiredState: + interfaces: + - bridge: + options: + stp: + enabled: false + port: + - name: enp7s0 + description: Linux bridge with enp7s0 as a port + mtu: 1500 + name: br-osp + state: up + type: linux-bridge + nodeSelector: + node-role.kubernetes.io/worker: "" + nodeSriovConfigurationPolicy: + desiredState: + deviceType: vfio-pci + mtu: 9000 + numVfs: 0 + port: "" + spoofCheck: "on" + trust: "off" + dnsServers: [] + domainName: localdomain + networks: + - isControlPlane: true + mtu: 1500 + name: Control + nameLower: ctlplane + subnets: + - attachConfiguration: br-osp + ipv4: + allocationEnd: 192.168.25.250 + allocationStart: 192.168.25.100 + cidr: 192.168.25.0/24 + gateway: 192.168.25.1 + routes: [] + ipv6: + allocationEnd: "" + allocationStart: "" + cidr: "" + gateway: "" + routes: [] + name: ctlplane + vlan: 0 + vip: true + ovnBridgeMacMappings: + physNetworks: + - macPrefix: fa:16:3a + name: datacentre + preserveReservations: true + reservations: + controller-1: + ipReservations: + ctlplane: 192.168.25.41 + macReservations: {} + controller-2: + ipReservations: + ctlplane: 192.168.25.42 + macReservations: {} + openstackclient-0: + ipReservations: + ctlplane: 192.168.25.251 + macReservations: {} + controlplane: + ipReservations: + ctlplane: 192.168.25.10 + macReservations: {} +status: + provisioningStatus: + attachDesiredCount: 1 + attachReadyCount: 1 + netDesiredCount: 1 + netReadyCount: 1 + physNetDesiredCount: 1 + physNetReadyCount: 1 + reason: OpenStackNetConfig openstacknetconfig all resources configured + state: Configured diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/07-assert.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/07-assert.yaml new file mode 100644 index 00000000..b6fe94cd --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/07-assert.yaml @@ -0,0 +1,328 @@ +# +# Check for: +# +# - 1 OpenStackNetConfig +# - 1 OpenStackControlPlane +# - 1 OpenStackVMSet +# - 1 OpenStackClient +# - 6 OpenStackNet (IP reservations for OpenStackControlPlane and OpenStackClient) +# + +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNetConfig +metadata: + finalizers: + - openstacknetconfig.osp-director.openstack.org + name: openstacknetconfig + namespace: openstack +spec: +spec: + attachConfigurations: + br-osp: + nodeNetworkConfigurationPolicy: + desiredState: + interfaces: + - bridge: + options: + stp: + enabled: false + port: + - name: enp7s0 + description: Linux bridge with enp7s0 as a port + mtu: 1500 + name: br-osp + state: up + type: linux-bridge + nodeSelector: + node-role.kubernetes.io/worker: "" + nodeSriovConfigurationPolicy: + desiredState: + deviceType: vfio-pci + mtu: 9000 + numVfs: 0 + port: "" + spoofCheck: "on" + trust: "off" + dnsServers: [] + domainName: localdomain + networks: + - isControlPlane: true + mtu: 1500 + name: Control + nameLower: ctlplane + subnets: + - attachConfiguration: br-osp + ipv4: + allocationEnd: 192.168.25.250 + allocationStart: 192.168.25.100 + cidr: 192.168.25.0/24 + gateway: 192.168.25.1 + routes: [] + ipv6: + allocationEnd: "" + allocationStart: "" + cidr: "" + gateway: "" + routes: [] + name: ctlplane + vlan: 0 + vip: true + ovnBridgeMacMappings: + physNetworks: + - macPrefix: fa:16:3a + name: datacentre + preserveReservations: true + reservations: + controller-1: + ipReservations: + ctlplane: 192.168.25.41 + macReservations: {} + controller-2: + ipReservations: + ctlplane: 192.168.25.42 + macReservations: {} + controlplane: + ipReservations: + ctlplane: 192.168.25.10 + macReservations: {} + openstackclient-0: + ipReservations: + ctlplane: 192.168.25.251 + macReservations: {} +status: + hosts: + controller-0: + ipaddresses: + ctlplane: 192.168.25.100/24 + controller-1: + ipaddresses: + ctlplane: 192.168.25.41/24 + controller-2: + ipaddresses: + ctlplane: 192.168.25.42/24 + controlplane: + ipaddresses: + ctlplane: 192.168.25.10/24 + ovnBridgeMacAdresses: {} + openstackclient-0: + ipaddresses: + ctlplane: 192.168.25.251/24 + ovnBridgeMacAdresses: {} + provisioningStatus: + attachDesiredCount: 1 + attachReadyCount: 1 + netDesiredCount: 1 + netReadyCount: 1 + physNetDesiredCount: 1 + physNetReadyCount: 1 + reason: OpenStackNetConfig openstacknetconfig all resources configured + state: Configured +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackControlPlane +metadata: + name: overcloud + namespace: openstack +spec: + domainName: ostest.test.metalkube.org + enableFencing: false + gitSecret: git-secret + openStackClientImageURL: registry.redhat.io/rhosp-rhel8/openstack-tripleoclient:16.2 + openStackClientNetworks: + - ctlplane + openStackClientStorageClass: host-nfs-storageclass + openStackRelease: "16.2" + passwordSecret: userpassword + virtualMachineRoles: + controller: + baseImageVolumeName: controller-base-img + cores: 6 + ctlplaneInterface: enp2s0 + diskSize: 50 + isTripleoRole: true + memory: 20 + networks: + - ctlplane + roleCount: 3 + roleName: Controller + storageClass: host-nfs-storageclass +status: + ospVersion: "16.2" + provisioningStatus: + clientReady: true + desiredCount: 1 + readyCount: 1 + reason: All requested OSVMSets have been provisioned + state: Provisioned + vipStatus: + controlplane: + annotatedForDeletion: false + hostRef: controlplane + hostname: controlplane + ipaddresses: + ctlplane: 192.168.25.10/24 + provisioningState: Provisioned +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackVMSet +metadata: + finalizers: + - openstackvmsets.osp-director.openstack.org/virtualmachine + name: controller + namespace: openstack +spec: + baseImageVolumeName: controller-base-img + cores: 6 + ctlplaneInterface: enp2s0 + deploymentSSHSecret: osp-controlplane-ssh-keys + diskSize: 50 + domainName: ostest.test.metalkube.org + isTripleoRole: true + memory: 20 + networks: + - ctlplane + passwordSecret: userpassword + roleName: Controller + storageClass: host-nfs-storageclass + vmCount: 3 +status: + baseImageDVReady: true + provisioningStatus: + readyCount: 3 + reason: All requested VirtualMachines have been provisioned + state: Provisioned + vmHosts: + controller-0: + annotatedForDeletion: false + ctlplaneIP: "" + hostRef: controller-0 + hostname: controller-0 + ipaddresses: + ctlplane: 192.168.25.100/24 + networkDataSecretName: controller-controller-0-networkdata + provisioningState: Provisioned + userDataSecretName: controller-cloudinit + controller-1: + annotatedForDeletion: false + ctlplaneIP: "" + hostRef: controller-1 + hostname: controller-1 + ipaddresses: + ctlplane: 192.168.25.41/24 + networkDataSecretName: controller-controller-1-networkdata + provisioningState: Provisioned + userDataSecretName: controller-cloudinit + controller-2: + annotatedForDeletion: false + ctlplaneIP: "" + hostRef: controller-2 + hostname: controller-2 + ipaddresses: + ctlplane: 192.168.25.42/24 + networkDataSecretName: controller-controller-2-networkdata + provisioningState: Provisioned + userDataSecretName: controller-cloudinit +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackClient +metadata: + name: openstackclient + namespace: openstack +spec: + cloudName: overcloud + deploymentSSHSecret: osp-controlplane-ssh-keys + domainName: ostest.test.metalkube.org + gitSecret: git-secret + imageURL: registry.redhat.io/rhosp-rhel8/openstack-tripleoclient:16.2 + networks: + - ctlplane + runGID: 42401 + runUID: 42401 + storageClass: host-nfs-storageclass +status: + netStatus: + openstackclient-0: + annotatedForDeletion: false + hostRef: openstackclient-0 + hostname: openstackclient-0 + ipaddresses: + ctlplane: 192.168.25.251/24 + provisioningState: Provisioned +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNet +metadata: + finalizers: + - openstacknet.osp-director.openstack.org + labels: + ooo-ctlplane-network: "true" + ooo-netname: Control + ooo-netname-lower: ctlplane + ooo-subnetname: ctlplane + osp-director.openstack.org/controller: osp-openstacknetconfig + osp-director.openstack.org/name: openstacknetconfig + osp-director.openstack.org/namespace: openstack + name: ctlplane + namespace: openstack +spec: + allocationEnd: 192.168.25.250 + allocationStart: 192.168.25.100 + attachConfiguration: br-osp + cidr: 192.168.25.0/24 + domainName: ctlplane.localdomain + gateway: 192.168.25.1 + mtu: 1500 + name: Control + nameLower: ctlplane + roleReservations: + ControlPlane: + addToPredictableIPs: true + reservations: + - deleted: false + hostname: controlplane + ip: 192.168.25.10 + vip: true + Controller: + addToPredictableIPs: true + reservations: + - deleted: false + hostname: controller-0 + ip: 192.168.25.100 + vip: false + - deleted: false + hostname: controller-1 + ip: 192.168.25.41 + vip: false + - deleted: false + hostname: controller-2 + ip: 192.168.25.42 + vip: false + OpenstackClientopenstackclient: + addToPredictableIPs: false + reservations: + - deleted: false + hostname: openstackclient-0 + ip: 192.168.25.251 + vip: false + routes: [] + vip: true + vlan: 0 +status: + currentState: Configured + reservations: + controller-0: + deleted: false + ip: 192.168.25.100 + controller-1: + deleted: false + ip: 192.168.25.41 + controller-2: + deleted: false + ip: 192.168.25.42 + controlplane: + deleted: false + ip: 192.168.25.10 + openstackclient-0: + deleted: false + ip: 192.168.25.251 + reservedIpCount: 5 diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/07-scale_up_openstackcontrolplane.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/07-scale_up_openstackcontrolplane.yaml new file mode 120000 index 00000000..70ad7ee2 --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/07-scale_up_openstackcontrolplane.yaml @@ -0,0 +1 @@ +../../common/tests/scale_up_openstackcontrolplane_3_controllers.yaml \ No newline at end of file diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/08-assert.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/08-assert.yaml new file mode 100644 index 00000000..3666549e --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/08-assert.yaml @@ -0,0 +1,301 @@ +# +# Check for: +# +# - 1 OpenStackControlPlane +# - 1 OpenStackVMSet +# - 1 OpenStackClient +# - 6 OpenStackNet (IP reservations for OpenStackControlPlane and OpenStackClient) +# + +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNetConfig +metadata: + finalizers: + - openstacknetconfig.osp-director.openstack.org + name: openstacknetconfig + namespace: openstack +spec: +spec: + attachConfigurations: + br-osp: + nodeNetworkConfigurationPolicy: + desiredState: + interfaces: + - bridge: + options: + stp: + enabled: false + port: + - name: enp7s0 + description: Linux bridge with enp7s0 as a port + mtu: 1500 + name: br-osp + state: up + type: linux-bridge + nodeSelector: + node-role.kubernetes.io/worker: "" + nodeSriovConfigurationPolicy: + desiredState: + deviceType: vfio-pci + mtu: 9000 + numVfs: 0 + port: "" + spoofCheck: "on" + trust: "off" + dnsServers: [] + domainName: localdomain + networks: + - isControlPlane: true + mtu: 1500 + name: Control + nameLower: ctlplane + subnets: + - attachConfiguration: br-osp + ipv4: + allocationEnd: 192.168.25.250 + allocationStart: 192.168.25.100 + cidr: 192.168.25.0/24 + gateway: 192.168.25.1 + routes: [] + ipv6: + allocationEnd: "" + allocationStart: "" + cidr: "" + gateway: "" + routes: [] + name: ctlplane + vlan: 0 + vip: true + ovnBridgeMacMappings: + physNetworks: + - macPrefix: fa:16:3a + name: datacentre + preserveReservations: true + reservations: + controller-1: + ipReservations: + ctlplane: 192.168.25.41 + macReservations: {} + controller-2: + ipReservations: + ctlplane: 192.168.25.42 + macReservations: {} + controlplane: + ipReservations: + ctlplane: 192.168.25.10 + macReservations: {} + openstackclient-0: + ipReservations: + ctlplane: 192.168.25.251 + macReservations: {} +status: + hosts: + controller-2: + ipaddresses: + ctlplane: 192.168.25.42/24 + controlplane: + ipaddresses: + ctlplane: 192.168.25.10/24 + ovnBridgeMacAdresses: {} + openstackclient-0: + ipaddresses: + ctlplane: 192.168.25.251/24 + ovnBridgeMacAdresses: {} + provisioningStatus: + attachDesiredCount: 1 + attachReadyCount: 1 + netDesiredCount: 1 + netReadyCount: 1 + physNetDesiredCount: 1 + physNetReadyCount: 1 + reason: OpenStackNetConfig openstacknetconfig all resources configured + state: Configured +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackControlPlane +metadata: + name: overcloud + namespace: openstack +spec: + domainName: ostest.test.metalkube.org + enableFencing: false + gitSecret: git-secret + openStackClientImageURL: registry.redhat.io/rhosp-rhel8/openstack-tripleoclient:16.2 + openStackClientNetworks: + - ctlplane + openStackClientStorageClass: host-nfs-storageclass + openStackRelease: "16.2" + passwordSecret: userpassword + virtualMachineRoles: + controller: + baseImageVolumeName: controller-base-img + cores: 6 + ctlplaneInterface: enp2s0 + diskSize: 50 + isTripleoRole: true + memory: 20 + networks: + - ctlplane + roleCount: 1 + roleName: Controller + storageClass: host-nfs-storageclass +status: + ospVersion: "16.2" + provisioningStatus: + clientReady: true + desiredCount: 1 + readyCount: 1 + reason: All requested OSVMSets have been provisioned + state: Provisioned + vipStatus: + controlplane: + annotatedForDeletion: false + hostRef: controlplane + hostname: controlplane + ipaddresses: + ctlplane: 192.168.25.10/24 + provisioningState: Provisioned +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackVMSet +metadata: + finalizers: + - openstackvmsets.osp-director.openstack.org/virtualmachine + name: controller + namespace: openstack +spec: + baseImageVolumeName: controller-base-img + cores: 6 + ctlplaneInterface: enp2s0 + deploymentSSHSecret: osp-controlplane-ssh-keys + diskSize: 50 + domainName: ostest.test.metalkube.org + isTripleoRole: true + memory: 20 + networks: + - ctlplane + passwordSecret: userpassword + roleName: Controller + storageClass: host-nfs-storageclass + vmCount: 1 +status: + baseImageDVReady: true + provisioningStatus: + readyCount: 1 + reason: All requested VirtualMachines have been provisioned + state: Provisioned + vmHosts: + controller-2: + annotatedForDeletion: false + ctlplaneIP: "" + hostRef: controller-2 + hostname: controller-2 + ipaddresses: + ctlplane: 192.168.25.42/24 + networkDataSecretName: controller-controller-2-networkdata + provisioningState: Provisioned + userDataSecretName: controller-cloudinit +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackClient +metadata: + name: openstackclient + namespace: openstack +spec: + cloudName: overcloud + deploymentSSHSecret: osp-controlplane-ssh-keys + domainName: ostest.test.metalkube.org + gitSecret: git-secret + imageURL: registry.redhat.io/rhosp-rhel8/openstack-tripleoclient:16.2 + networks: + - ctlplane + runGID: 42401 + runUID: 42401 + storageClass: host-nfs-storageclass +status: + netStatus: + openstackclient-0: + annotatedForDeletion: false + hostRef: openstackclient-0 + hostname: openstackclient-0 + ipaddresses: + ctlplane: 192.168.25.251/24 + provisioningState: Provisioned +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNet +metadata: + finalizers: + - openstacknet.osp-director.openstack.org + labels: + ooo-ctlplane-network: "true" + ooo-netname: Control + ooo-netname-lower: ctlplane + ooo-subnetname: ctlplane + osp-director.openstack.org/controller: osp-openstacknetconfig + osp-director.openstack.org/name: openstacknetconfig + osp-director.openstack.org/namespace: openstack + name: ctlplane + namespace: openstack +spec: + allocationEnd: 192.168.25.250 + allocationStart: 192.168.25.100 + attachConfiguration: br-osp + cidr: 192.168.25.0/24 + domainName: ctlplane.localdomain + gateway: 192.168.25.1 + mtu: 1500 + name: Control + nameLower: ctlplane + roleReservations: + ControlPlane: + addToPredictableIPs: true + reservations: + - deleted: false + hostname: controlplane + ip: 192.168.25.10 + vip: true + Controller: + addToPredictableIPs: true + reservations: + - deleted: true + hostname: controller-0 + ip: 192.168.25.100 + vip: false + - deleted: true + hostname: controller-1 + ip: 192.168.25.41 + vip: false + - deleted: false + hostname: controller-2 + ip: 192.168.25.42 + vip: false + OpenstackClientopenstackclient: + addToPredictableIPs: false + reservations: + - deleted: false + hostname: openstackclient-0 + ip: 192.168.25.251 + vip: false + routes: [] + vip: true + vlan: 0 +status: + currentState: Configured + reservations: + controller-0: + deleted: true + ip: 192.168.25.100 + controller-1: + deleted: true + ip: 192.168.25.41 + controller-2: + deleted: false + ip: 192.168.25.42 + controlplane: + deleted: false + ip: 192.168.25.10 + openstackclient-0: + deleted: false + ip: 192.168.25.251 + reservedIpCount: 5 diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/08-errors.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/08-errors.yaml new file mode 100644 index 00000000..785fab20 --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/08-errors.yaml @@ -0,0 +1,17 @@ +# +# Check for: +# +# - VirtualMachines (2 should be removed) +# + +apiVersion: kubevirt.io/v1alpha3 +kind: VirtualMachine +metadata: + name: controller-0 + namespace: openstack +--- +apiVersion: kubevirt.io/v1alpha3 +kind: VirtualMachine +metadata: + name: controller-1 + namespace: openstack diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/08-scale_down_openstackcontrolplane.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/08-scale_down_openstackcontrolplane.yaml new file mode 120000 index 00000000..66a7ee1c --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/08-scale_down_openstackcontrolplane.yaml @@ -0,0 +1 @@ +../../common/tests/scale_down_openstackcontrolplane_single_controller.yaml \ No newline at end of file diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/09-assert.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/09-assert.yaml new file mode 100644 index 00000000..7e1f5fc6 --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/09-assert.yaml @@ -0,0 +1,287 @@ +# +# Check for: +# +# - 1 OpenStackControlPlane +# - 1 OpenStackVMSet +# - 1 OpenStackClient +# - 6 OpenStackNet (IP reservations for OpenStackControlPlane and OpenStackClient) +# + +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNetConfig +metadata: + finalizers: + - openstacknetconfig.osp-director.openstack.org + name: openstacknetconfig + namespace: openstack +spec: +spec: + attachConfigurations: + br-osp: + nodeNetworkConfigurationPolicy: + desiredState: + interfaces: + - bridge: + options: + stp: + enabled: false + port: + - name: enp7s0 + description: Linux bridge with enp7s0 as a port + mtu: 1500 + name: br-osp + state: up + type: linux-bridge + nodeSelector: + node-role.kubernetes.io/worker: "" + nodeSriovConfigurationPolicy: + desiredState: + deviceType: vfio-pci + mtu: 9000 + numVfs: 0 + port: "" + spoofCheck: "on" + trust: "off" + dnsServers: [] + domainName: localdomain + networks: + - isControlPlane: true + mtu: 1500 + name: Control + nameLower: ctlplane + subnets: + - attachConfiguration: br-osp + ipv4: + allocationEnd: 192.168.25.250 + allocationStart: 192.168.25.100 + cidr: 192.168.25.0/24 + gateway: 192.168.25.1 + routes: [] + ipv6: + allocationEnd: "" + allocationStart: "" + cidr: "" + gateway: "" + routes: [] + name: ctlplane + vlan: 0 + vip: true + ovnBridgeMacMappings: + physNetworks: + - macPrefix: fa:16:3a + name: datacentre + preserveReservations: false + reservations: + controller-1: + ipReservations: + ctlplane: 192.168.25.41 + macReservations: {} + controller-2: + ipReservations: + ctlplane: 192.168.25.42 + macReservations: {} + controlplane: + ipReservations: + ctlplane: 192.168.25.10 + macReservations: {} + openstackclient-0: + ipReservations: + ctlplane: 192.168.25.251 + macReservations: {} +status: + hosts: + controller-2: + ipaddresses: + ctlplane: 192.168.25.42/24 + controlplane: + ipaddresses: + ctlplane: 192.168.25.10/24 + ovnBridgeMacAdresses: {} + openstackclient-0: + ipaddresses: + ctlplane: 192.168.25.251/24 + ovnBridgeMacAdresses: {} + provisioningStatus: + attachDesiredCount: 1 + attachReadyCount: 1 + netDesiredCount: 1 + netReadyCount: 1 + physNetDesiredCount: 1 + physNetReadyCount: 1 + reason: OpenStackNetConfig openstacknetconfig all resources configured + state: Configured +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackControlPlane +metadata: + name: overcloud + namespace: openstack +spec: + domainName: ostest.test.metalkube.org + enableFencing: false + gitSecret: git-secret + openStackClientImageURL: registry.redhat.io/rhosp-rhel8/openstack-tripleoclient:16.2 + openStackClientNetworks: + - ctlplane + openStackClientStorageClass: host-nfs-storageclass + openStackRelease: "16.2" + passwordSecret: userpassword + virtualMachineRoles: + controller: + baseImageVolumeName: controller-base-img + cores: 6 + ctlplaneInterface: enp2s0 + diskSize: 50 + isTripleoRole: true + memory: 20 + networks: + - ctlplane + roleCount: 1 + roleName: Controller + storageClass: host-nfs-storageclass +status: + ospVersion: "16.2" + provisioningStatus: + clientReady: true + desiredCount: 1 + readyCount: 1 + reason: All requested OSVMSets have been provisioned + state: Provisioned + vipStatus: + controlplane: + annotatedForDeletion: false + hostRef: controlplane + hostname: controlplane + ipaddresses: + ctlplane: 192.168.25.10/24 + provisioningState: Provisioned +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackVMSet +metadata: + finalizers: + - openstackvmsets.osp-director.openstack.org/virtualmachine + name: controller + namespace: openstack +spec: + baseImageVolumeName: controller-base-img + cores: 6 + ctlplaneInterface: enp2s0 + deploymentSSHSecret: osp-controlplane-ssh-keys + diskSize: 50 + domainName: ostest.test.metalkube.org + isTripleoRole: true + memory: 20 + networks: + - ctlplane + passwordSecret: userpassword + roleName: Controller + storageClass: host-nfs-storageclass + vmCount: 1 +status: + baseImageDVReady: true + provisioningStatus: + readyCount: 1 + reason: All requested VirtualMachines have been provisioned + state: Provisioned + vmHosts: + controller-2: + annotatedForDeletion: false + ctlplaneIP: "" + hostRef: controller-2 + hostname: controller-2 + ipaddresses: + ctlplane: 192.168.25.42/24 + networkDataSecretName: controller-controller-2-networkdata + provisioningState: Provisioned + userDataSecretName: controller-cloudinit +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackClient +metadata: + name: openstackclient + namespace: openstack +spec: + cloudName: overcloud + deploymentSSHSecret: osp-controlplane-ssh-keys + domainName: ostest.test.metalkube.org + gitSecret: git-secret + imageURL: registry.redhat.io/rhosp-rhel8/openstack-tripleoclient:16.2 + networks: + - ctlplane + runGID: 42401 + runUID: 42401 + storageClass: host-nfs-storageclass +status: + netStatus: + openstackclient-0: + annotatedForDeletion: false + hostRef: openstackclient-0 + hostname: openstackclient-0 + ipaddresses: + ctlplane: 192.168.25.251/24 + provisioningState: Provisioned +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNet +metadata: + finalizers: + - openstacknet.osp-director.openstack.org + labels: + ooo-ctlplane-network: "true" + ooo-netname: Control + ooo-netname-lower: ctlplane + ooo-subnetname: ctlplane + osp-director.openstack.org/controller: osp-openstacknetconfig + osp-director.openstack.org/name: openstacknetconfig + osp-director.openstack.org/namespace: openstack + name: ctlplane + namespace: openstack +spec: + allocationEnd: 192.168.25.250 + allocationStart: 192.168.25.100 + attachConfiguration: br-osp + cidr: 192.168.25.0/24 + domainName: ctlplane.localdomain + gateway: 192.168.25.1 + mtu: 1500 + name: Control + nameLower: ctlplane + roleReservations: + ControlPlane: + addToPredictableIPs: true + reservations: + - deleted: false + hostname: controlplane + ip: 192.168.25.10 + vip: true + Controller: + addToPredictableIPs: true + reservations: + - deleted: false + hostname: controller-2 + ip: 192.168.25.42 + vip: false + OpenstackClientopenstackclient: + addToPredictableIPs: false + reservations: + - deleted: false + hostname: openstackclient-0 + ip: 192.168.25.251 + vip: false + routes: [] + vip: true + vlan: 0 +status: + currentState: Configured + reservations: + controller-2: + deleted: false + ip: 192.168.25.42 + controlplane: + deleted: false + ip: 192.168.25.10 + openstackclient-0: + deleted: false + ip: 192.168.25.251 + reservedIpCount: 3 diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/09-switch_preserveReservations_off.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/09-switch_preserveReservations_off.yaml new file mode 100644 index 00000000..a6fdb932 --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/09-switch_preserveReservations_off.yaml @@ -0,0 +1,10 @@ +# +# Disable preserveReservations +# + +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: | + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "add", "path": "/spec/preserveReservations", "value": false}]' + namespaced: true diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/10-add_network.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/10-add_network.yaml new file mode 100644 index 00000000..1e1602ab --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/10-add_network.yaml @@ -0,0 +1,10 @@ +# +# Add new network definition to spec.networks +# + +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: | + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "add", "path": "/spec/networks/-", "value": {"name": "InternalApi", "nameLower": "internal_api","subnets": [{"name": "internal_api", "vlan": 20, "attachConfiguration": "br-osp", "ipv4": {"allocationEnd": "172.17.0.250", "allocationStart": "172.17.0.10", "cidr": "172.17.0.0/24"}}]}}]' + namespaced: true diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/10-assert.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/10-assert.yaml new file mode 100644 index 00000000..0c9e1ea7 --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/10-assert.yaml @@ -0,0 +1,164 @@ +# +# Check for: +# +# - 1 OpenStackNetConfig +# - 1 OpenStackMACAddress +# - 1 TestAssert +# + +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNetConfig +metadata: + finalizers: + - openstacknetconfig.osp-director.openstack.org + name: openstacknetconfig + namespace: openstack +spec: + attachConfigurations: + br-osp: + nodeNetworkConfigurationPolicy: + desiredState: + interfaces: + - bridge: + options: + stp: + enabled: false + port: + - name: enp7s0 + description: Linux bridge with enp7s0 as a port + mtu: 1500 + name: br-osp + state: up + type: linux-bridge + nodeSelector: + node-role.kubernetes.io/worker: "" + nodeSriovConfigurationPolicy: + desiredState: + deviceType: vfio-pci + mtu: 9000 + numVfs: 0 + port: "" + spoofCheck: "on" + trust: "off" + dnsServers: [] + domainName: localdomain + networks: + - isControlPlane: true + mtu: 1500 + name: Control + nameLower: ctlplane + subnets: + - attachConfiguration: br-osp + ipv4: + allocationEnd: 192.168.25.250 + allocationStart: 192.168.25.100 + cidr: 192.168.25.0/24 + gateway: 192.168.25.1 + routes: [] + ipv6: + allocationEnd: "" + allocationStart: "" + cidr: "" + gateway: "" + routes: [] + name: ctlplane + vlan: 0 + vip: true + - isControlPlane: false + mtu: 1500 + name: InternalApi + nameLower: internal_api + subnets: + - attachConfiguration: br-osp + ipv4: + allocationEnd: 172.17.0.250 + allocationStart: 172.17.0.10 + cidr: 172.17.0.0/24 + gateway: "" + routes: [] + ipv6: + allocationEnd: "" + allocationStart: "" + cidr: "" + gateway: "" + routes: [] + name: internal_api + vlan: 20 + vip: true + ovnBridgeMacMappings: + physNetworks: + - macPrefix: fa:16:3a + name: datacentre + preserveReservations: false + reservations: + controller-1: + ipReservations: + ctlplane: 192.168.25.41 + macReservations: {} + controller-2: + ipReservations: + ctlplane: 192.168.25.42 + macReservations: {} + controlplane: + ipReservations: + ctlplane: 192.168.25.10 + macReservations: {} + openstackclient-0: + ipReservations: + ctlplane: 192.168.25.251 + macReservations: {} +status: + provisioningStatus: + attachDesiredCount: 1 + attachReadyCount: 1 + netDesiredCount: 2 + netReadyCount: 2 + physNetDesiredCount: 1 + physNetReadyCount: 1 + reason: OpenStackNetConfig openstacknetconfig all resources configured + state: Configured +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNet +metadata: + name: internalapi + namespace: openstack +spec: + allocationEnd: 172.17.0.250 + allocationStart: 172.17.0.10 + attachConfiguration: br-osp + cidr: 172.17.0.0/24 + domainName: internalapi.localdomain + gateway: "" + mtu: 1500 + name: InternalApi + nameLower: internal_api + roleReservations: {} + routes: [] + vip: true + vlan: 20 +status: + conditions: + - message: OpenStackNet internalapi has been successfully configured on targeted node(s) + reason: OpenStackNet internalapi has been successfully configured on targeted node(s) + status: "True" + type: Configured + currentState: Configured + reservations: {} + reservedIpCount: 0 +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +timeout: 10 +namespaced: true +commands: + - script: | + set -x + # should return the new reservation for the added physnet + reservation=$(oc get -n openstack osmacaddr openstacknetconfig -o json | jq .spec.roleReservations.Controller.reservations | jq -r 'to_entries | map(select(.key == "controller-2"))[0] | .value.reservations.datacentre2'| wc -l) + if [ $reservation -eq 1 ]; then + exit 0 + else + exit 1 + fi + diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/11-add_network_to_vmrole.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/11-add_network_to_vmrole.yaml new file mode 100644 index 00000000..4c38a473 --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/11-add_network_to_vmrole.yaml @@ -0,0 +1,10 @@ +# +# Add new network definition to spec.networks +# + +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: | + oc patch -n openstack osctlplane overcloud --type='json' -p='[{"op": "add", "path": "/spec/virtualMachineRoles/controller/networks/-", "value": "internal_api"}]' + namespaced: true diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/11-assert.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/11-assert.yaml new file mode 100644 index 00000000..88bb318e --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/11-assert.yaml @@ -0,0 +1,276 @@ +# +# Check for: +# +# - 1 OpenStackNetConfig +# - 2 OpenStackNet +# - 1 OpenStackVMset +# + +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNetConfig +metadata: + name: openstacknetconfig + namespace: openstack +spec: + attachConfigurations: + br-osp: + nodeNetworkConfigurationPolicy: + desiredState: + interfaces: + - bridge: + options: + stp: + enabled: false + port: + - name: enp7s0 + description: Linux bridge with enp7s0 as a port + mtu: 1500 + name: br-osp + state: up + type: linux-bridge + nodeSelector: + node-role.kubernetes.io/worker: "" + nodeSriovConfigurationPolicy: + desiredState: + deviceType: vfio-pci + mtu: 9000 + numVfs: 0 + port: "" + spoofCheck: "on" + trust: "off" + dnsServers: [] + domainName: localdomain + networks: + - isControlPlane: true + mtu: 1500 + name: Control + nameLower: ctlplane + subnets: + - attachConfiguration: br-osp + ipv4: + allocationEnd: 192.168.25.250 + allocationStart: 192.168.25.100 + cidr: 192.168.25.0/24 + gateway: 192.168.25.1 + routes: [] + ipv6: + allocationEnd: "" + allocationStart: "" + cidr: "" + gateway: "" + routes: [] + name: ctlplane + vlan: 0 + vip: true + - isControlPlane: false + mtu: 1500 + name: InternalApi + nameLower: internal_api + subnets: + - attachConfiguration: br-osp + ipv4: + allocationEnd: 172.17.0.250 + allocationStart: 172.17.0.10 + cidr: 172.17.0.0/24 + gateway: "" + routes: [] + ipv6: + allocationEnd: "" + allocationStart: "" + cidr: "" + gateway: "" + routes: [] + name: internal_api + vlan: 20 + vip: true + ovnBridgeMacMappings: + physNetworks: + - macPrefix: fa:16:3a + name: datacentre + reservations: + controller-1: + ipReservations: + ctlplane: 192.168.25.41 + macReservations: {} + controller-2: + ipReservations: + ctlplane: 192.168.25.42 + macReservations: {} + controlplane: + ipReservations: + ctlplane: 192.168.25.10 + macReservations: {} + openstackclient-0: + ipReservations: + ctlplane: 192.168.25.251 + macReservations: {} +status: + hosts: + controller-0: + ipaddresses: {} + ovnBridgeMacAdresses: {} + controller-1: + ipaddresses: {} + ovnBridgeMacAdresses: {} + controller-2: + ipaddresses: + ctlplane: 192.168.25.42/24 + internal_api: 172.17.0.11/24 + controlplane: + ipaddresses: + ctlplane: 192.168.25.10/24 + internal_api: 172.17.0.10/24 + ovnBridgeMacAdresses: {} + openstackclient-0: + ipaddresses: + ctlplane: 192.168.25.251/24 + ovnBridgeMacAdresses: {} + provisioningStatus: + attachDesiredCount: 1 + attachReadyCount: 1 + netDesiredCount: 2 + netReadyCount: 2 + physNetDesiredCount: 1 + physNetReadyCount: 1 + reason: OpenStackNetConfig openstacknetconfig all resources configured + state: Configured +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNet +metadata: + name: ctlplane + namespace: openstack +spec: + allocationEnd: 192.168.25.250 + allocationStart: 192.168.25.100 + attachConfiguration: br-osp + cidr: 192.168.25.0/24 + domainName: ctlplane.localdomain + gateway: 192.168.25.1 + mtu: 1500 + name: Control + nameLower: ctlplane + roleReservations: + ControlPlane: + addToPredictableIPs: true + reservations: + - deleted: false + hostname: controlplane + ip: 192.168.25.10 + vip: true + Controller: + addToPredictableIPs: true + reservations: + - deleted: false + hostname: controller-2 + ip: 192.168.25.42 + vip: false + OpenstackClientopenstackclient: + addToPredictableIPs: false + reservations: + - deleted: false + hostname: openstackclient-0 + ip: 192.168.25.251 + vip: false + routes: [] + vip: true + vlan: 0 +status: + currentState: Configured + reservations: + controller-2: + deleted: false + ip: 192.168.25.42 + controlplane: + deleted: false + ip: 192.168.25.10 + openstackclient-0: + deleted: false + ip: 192.168.25.251 + reservedIpCount: 3 +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNet +metadata: + name: internalapi + namespace: openstack +spec: + allocationEnd: 172.17.0.250 + allocationStart: 172.17.0.10 + attachConfiguration: br-osp + cidr: 172.17.0.0/24 + domainName: internalapi.localdomain + gateway: "" + mtu: 1500 + name: InternalApi + nameLower: internal_api + roleReservations: + ControlPlane: + addToPredictableIPs: true + reservations: + - deleted: false + hostname: controlplane + ip: 172.17.0.10 + vip: true + Controller: + addToPredictableIPs: true + reservations: + - deleted: false + hostname: controller-2 + ip: 172.17.0.11 + vip: false + routes: [] + vip: true + vlan: 20 +status: + currentState: Configured + reservations: + controller-2: + deleted: false + ip: 172.17.0.11 + controlplane: + deleted: false + ip: 172.17.0.10 + reservedIpCount: 2 +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackVMSet +metadata: + name: controller + namespace: openstack +spec: + baseImageVolumeName: controller-base-img + cores: 6 + ctlplaneInterface: enp2s0 + deploymentSSHSecret: osp-controlplane-ssh-keys + diskSize: 50 + domainName: ostest.test.metalkube.org + isTripleoRole: true + memory: 20 + networks: + - ctlplane + - internal_api + passwordSecret: userpassword + roleName: Controller + storageAccessMode: ReadWriteMany + storageClass: host-nfs-storageclass + storageVolumeMode: Filesystem + vmCount: 1 +status: + baseImageDVReady: true + provisioningStatus: + readyCount: 1 + reason: All requested VirtualMachines have been provisioned + state: Provisioned + vmHosts: + controller-2: + annotatedForDeletion: false + ctlplaneIP: "" + hostRef: controller-2 + hostname: controller-2 + ipaddresses: + ctlplane: 192.168.25.42/24 + internal_api: 172.17.0.11/24 + networkDataSecretName: controller-controller-2-networkdata + provisioningState: Provisioned + userDataSecretName: controller-cloudinit diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/README.md b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/README.md new file mode 100644 index 00000000..a852943c --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv4/README.md @@ -0,0 +1,14 @@ +Q: WHAT IS TESTED HERE? + +A: +- create osnetcfg with no static reservation +- add static reservation for controller-0 +- scale up to 1 controller ctlplane +- Run webhook fail tests + - add static reservation with wrong IP format + - add static reservation with dupe IP +- add good additional reservation +- scale ctlplane nodes +- scale down node to verify reservation persist +- set persist to false to verify reservations for deleted nodes are gone +- add a new network diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/00-prep.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/00-prep.yaml new file mode 120000 index 00000000..414efe4b --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/00-prep.yaml @@ -0,0 +1 @@ +../../common/tests/00-prep.yaml \ No newline at end of file diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/01-assert.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/01-assert.yaml new file mode 120000 index 00000000..83ada4d2 --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/01-assert.yaml @@ -0,0 +1 @@ +../../common/tests/create_openstacknetconfig_single_net_ipv6-assert.yaml \ No newline at end of file diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/01-create_openstacknetconfig_single_net.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/01-create_openstacknetconfig_single_net.yaml new file mode 120000 index 00000000..3b7ed60d --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/01-create_openstacknetconfig_single_net.yaml @@ -0,0 +1 @@ +../../common/tests/create_openstacknetconfig_single_net_ipv6.yaml \ No newline at end of file diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/02-assert.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/02-assert.yaml new file mode 120000 index 00000000..97ee2975 --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/02-assert.yaml @@ -0,0 +1 @@ +../../common/tests/create_openstackcontrolplane_single_net_ipv6-assert.yaml \ No newline at end of file diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/02-create_openstackcontrolplane_single_net.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/02-create_openstackcontrolplane_single_net.yaml new file mode 120000 index 00000000..4ad45f5e --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/02-create_openstackcontrolplane_single_net.yaml @@ -0,0 +1 @@ +../../common/tests/create_openstackcontrolplane_single_net.yaml \ No newline at end of file diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/03-assert.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/03-assert.yaml new file mode 120000 index 00000000..35a82189 --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/03-assert.yaml @@ -0,0 +1 @@ +../../common/tests/scale_up_openstackcontrolplane_single_controller_single_net_ipv6-assert.yaml \ No newline at end of file diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/03-scale_up_openstackcontrolplane.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/03-scale_up_openstackcontrolplane.yaml new file mode 120000 index 00000000..dcbce48d --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/03-scale_up_openstackcontrolplane.yaml @@ -0,0 +1 @@ +../../common/tests/scale_up_openstackcontrolplane_single_controller.yaml \ No newline at end of file diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/04-add_static_reservation.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/04-add_static_reservation.yaml new file mode 100644 index 00000000..cc9d3ed5 --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/04-add_static_reservation.yaml @@ -0,0 +1,13 @@ +# +# Add static MAC reservation for controller-1 +# + +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: | + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "add", "path": "/spec/reservations/controller-1", "value": {"ipReservations":{}, "macReservations": {}}}]' + namespaced: true + - command: | + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "add", "path": "/spec/reservations/controller-1/ipReservations", "value": {"ctlplane": "2001:db8:fd00:2000::41" }}]' + namespaced: true diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/04-assert.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/04-assert.yaml new file mode 100644 index 00000000..0ff88400 --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/04-assert.yaml @@ -0,0 +1,93 @@ +# +# Check for: +# +# - 1 OpenstackNetworkConfig +# + +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNetConfig +metadata: + finalizers: + - openstacknetconfig.osp-director.openstack.org + name: openstacknetconfig + namespace: openstack +spec: +spec: + attachConfigurations: + br-osp: + nodeNetworkConfigurationPolicy: + desiredState: + interfaces: + - bridge: + options: + stp: + enabled: false + port: + - name: enp7s0 + description: Linux bridge with enp7s0 as a port + mtu: 1500 + name: br-osp + state: up + type: linux-bridge + nodeSelector: + node-role.kubernetes.io/worker: "" + nodeSriovConfigurationPolicy: + desiredState: + deviceType: vfio-pci + mtu: 9000 + numVfs: 0 + port: "" + spoofCheck: "on" + trust: "off" + dnsServers: [] + domainName: localdomain + networks: + - isControlPlane: true + mtu: 1500 + name: Control + nameLower: ctlplane + subnets: + - attachConfiguration: br-osp + ipv4: + allocationEnd: "" + allocationStart: "" + cidr: "" + gateway: "" + routes: [] + ipv6: + allocationEnd: 2001:db8:fd00:2000:ffff:ffff:ffff:fffe + allocationStart: 2001:db8:fd00:2000::100 + cidr: 2001:db8:fd00:2000::/64 + gateway: 2001:db8:fd00:2000::1 + routes: [] + name: ctlplane + vlan: 0 + vip: true + ovnBridgeMacMappings: + physNetworks: + - macPrefix: fa:16:3a + name: datacentre + preserveReservations: true + reservations: + controller-1: + ipReservations: + ctlplane: 2001:db8:fd00:2000::41 + macReservations: {} + controlplane: + ipReservations: + ctlplane: 2001:db8:fd00:2000::10 + macReservations: {} + openstackclient-0: + ipReservations: + ctlplane: 2001:db8:fd00:2000::251 + macReservations: {} +status: + provisioningStatus: + attachDesiredCount: 1 + attachReadyCount: 1 + netDesiredCount: 1 + netReadyCount: 1 + physNetDesiredCount: 1 + physNetReadyCount: 1 + reason: OpenStackNetConfig openstacknetconfig all resources configured + state: Configured diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/05-assert.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/05-assert.yaml new file mode 100644 index 00000000..0858ddc7 --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/05-assert.yaml @@ -0,0 +1,111 @@ +# +# Check for: +# +# - 1 OpenstackNetworkConfig +# - 2 OpenStackNetworkAttachment +# - 2 NodeNetworkConfigurationPolicy +# - 6 OpenStackNets +# - 1 OpenStackMACAddress +# + +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNetConfig +metadata: + finalizers: + - openstacknetconfig.osp-director.openstack.org + name: openstacknetconfig + namespace: openstack +spec: + attachConfigurations: + br-osp: + nodeNetworkConfigurationPolicy: + desiredState: + interfaces: + - bridge: + options: + stp: + enabled: false + port: + - name: enp7s0 + description: Linux bridge with enp7s0 as a port + mtu: 1500 + name: br-osp + state: up + type: linux-bridge + nodeSelector: + node-role.kubernetes.io/worker: "" + nodeSriovConfigurationPolicy: + desiredState: + deviceType: vfio-pci + mtu: 9000 + numVfs: 0 + port: "" + spoofCheck: "on" + trust: "off" + dnsServers: [] + domainName: localdomain + networks: + - isControlPlane: true + mtu: 1500 + name: Control + nameLower: ctlplane + subnets: + - attachConfiguration: br-osp + ipv4: + allocationEnd: "" + allocationStart: "" + cidr: "" + gateway: "" + routes: [] + ipv6: + allocationEnd: 2001:db8:fd00:2000:ffff:ffff:ffff:fffe + allocationStart: 2001:db8:fd00:2000::100 + cidr: 2001:db8:fd00:2000::/64 + gateway: 2001:db8:fd00:2000::1 + routes: [] + name: ctlplane + vlan: 0 + vip: true + ovnBridgeMacMappings: + physNetworks: + - macPrefix: fa:16:3a + name: datacentre + preserveReservations: true + reservations: + controller-1: + ipReservations: + ctlplane: 2001:db8:fd00:2000::41 + macReservations: {} + controller-2: + ipReservations: {} + macReservations: {} + controlplane: + ipReservations: + ctlplane: 2001:db8:fd00:2000::10 + macReservations: {} + openstackclient-0: + ipReservations: + ctlplane: 2001:db8:fd00:2000::251 + macReservations: {} +status: + hosts: + controller-0: + ipaddresses: + ctlplane: 2001:db8:fd00:2000::101/64 + controlplane: + ipaddresses: + ctlplane: 2001:db8:fd00:2000::10/64 + ovnBridgeMacAdresses: {} + openstackclient-0: + ipaddresses: + ctlplane: 2001:db8:fd00:2000::251/64 + ovnBridgeMacAdresses: {} + provisioningStatus: + attachDesiredCount: 1 + attachReadyCount: 1 + netDesiredCount: 1 + netReadyCount: 1 + physNetDesiredCount: 1 + physNetReadyCount: 1 + reason: OpenStackNetConfig openstacknetconfig all resources configured + state: Configured diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/05-webhook_validations.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/05-webhook_validations.yaml new file mode 100644 index 00000000..996e1658 --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/05-webhook_validations.yaml @@ -0,0 +1,29 @@ +# +# verify no changes on: +# - add reservation with dupe from dynamic created IP +# - add reservation with dupe from static IP reservation +# - add reservation with wrong IP format +# + +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: | + # add new empty reservation for controller-2 + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "add", "path": "/spec/reservations/controller-2", "value": {"ipReservations":{}, "macReservations": {}}}]' + namespaced: true + - command: | + # add static reservation with dupe dynamic IP entry (IP from controller-0) + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "replace", "path": "/spec/reservations/controller-2/ipReservations/ctlplane", "value": "2001:db8:fd00:2000::101"}]' + namespaced: true + ignoreFailure: true + - command: | + # add static reservation with dupe static IP entry (IP from controller-1) + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "replace", "path": "/spec/reservations/controller-2/ipReservations/ctlplane", "value": "2001:db8:fd00:2000::41"}]' + namespaced: true + ignoreFailure: true + - command: | + # add static reservation with wrong IP format + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "add", "path": "/spec/reservations/controller-2/ipReservations/ctlplane", "value": "2001:db8:fd00:2000:42" }]' + namespaced: true + ignoreFailure: true diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/06-add_second_reservation.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/06-add_second_reservation.yaml new file mode 100644 index 00000000..6d5fdcda --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/06-add_second_reservation.yaml @@ -0,0 +1,14 @@ +# +# Add static IP reservation for controller-2 +# + +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: | + # add new empty reservation for controller-2 + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "add", "path": "/spec/reservations/controller-2", "value": {"ipReservations":{}, "macReservations": {}}}]' + namespaced: true + - command: | + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "replace", "path": "/spec/reservations/controller-2/ipReservations/ctlplane", "value": "2001:db8:fd00:2000::42"}]' + namespaced: true diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/06-assert.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/06-assert.yaml new file mode 100644 index 00000000..1e13fe34 --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/06-assert.yaml @@ -0,0 +1,109 @@ +# +# Check for: +# +# - 1 OpenstackNetworkConfig +# + +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNetConfig +metadata: + finalizers: + - openstacknetconfig.osp-director.openstack.org + name: openstacknetconfig + namespace: openstack +spec: +spec: + attachConfigurations: + br-osp: + nodeNetworkConfigurationPolicy: + desiredState: + interfaces: + - bridge: + options: + stp: + enabled: false + port: + - name: enp7s0 + description: Linux bridge with enp7s0 as a port + mtu: 1500 + name: br-osp + state: up + type: linux-bridge + nodeSelector: + node-role.kubernetes.io/worker: "" + nodeSriovConfigurationPolicy: + desiredState: + deviceType: vfio-pci + mtu: 9000 + numVfs: 0 + port: "" + spoofCheck: "on" + trust: "off" + dnsServers: [] + domainName: localdomain + networks: + - isControlPlane: true + mtu: 1500 + name: Control + nameLower: ctlplane + subnets: + - attachConfiguration: br-osp + ipv4: + allocationEnd: "" + allocationStart: "" + cidr: "" + gateway: "" + routes: [] + ipv6: + allocationEnd: 2001:db8:fd00:2000:ffff:ffff:ffff:fffe + allocationStart: 2001:db8:fd00:2000::100 + cidr: 2001:db8:fd00:2000::/64 + gateway: 2001:db8:fd00:2000::1 + routes: [] + name: ctlplane + vlan: 0 + vip: true + ovnBridgeMacMappings: + physNetworks: + - macPrefix: fa:16:3a + name: datacentre + preserveReservations: true + reservations: + controller-1: + ipReservations: + ctlplane: 2001:db8:fd00:2000::41 + macReservations: {} + controller-2: + ipReservations: + ctlplane: 2001:db8:fd00:2000::42 + macReservations: {} + controlplane: + ipReservations: + ctlplane: 2001:db8:fd00:2000::10 + macReservations: {} + openstackclient-0: + ipReservations: + ctlplane: 2001:db8:fd00:2000::251 + macReservations: {} +status: + hosts: + controller-0: + ipaddresses: + ctlplane: 2001:db8:fd00:2000::101/64 + controlplane: + ipaddresses: + ctlplane: 2001:db8:fd00:2000::10/64 + ovnBridgeMacAdresses: {} + openstackclient-0: + ipaddresses: + ctlplane: 2001:db8:fd00:2000::251/64 + ovnBridgeMacAdresses: {} + provisioningStatus: + attachDesiredCount: 1 + attachReadyCount: 1 + netDesiredCount: 1 + netReadyCount: 1 + physNetDesiredCount: 1 + physNetReadyCount: 1 + reason: OpenStackNetConfig openstacknetconfig all resources configured + state: Configured diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/07-assert.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/07-assert.yaml new file mode 100644 index 00000000..ee5c583c --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/07-assert.yaml @@ -0,0 +1,328 @@ +# +# Check for: +# +# - 1 OpenStackNetConfig +# - 1 OpenStackControlPlane +# - 1 OpenStackVMSet +# - 1 OpenStackClient +# - 6 OpenStackNet (IP reservations for OpenStackControlPlane and OpenStackClient) +# + +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNetConfig +metadata: + finalizers: + - openstacknetconfig.osp-director.openstack.org + name: openstacknetconfig + namespace: openstack +spec: +spec: + attachConfigurations: + br-osp: + nodeNetworkConfigurationPolicy: + desiredState: + interfaces: + - bridge: + options: + stp: + enabled: false + port: + - name: enp7s0 + description: Linux bridge with enp7s0 as a port + mtu: 1500 + name: br-osp + state: up + type: linux-bridge + nodeSelector: + node-role.kubernetes.io/worker: "" + nodeSriovConfigurationPolicy: + desiredState: + deviceType: vfio-pci + mtu: 9000 + numVfs: 0 + port: "" + spoofCheck: "on" + trust: "off" + dnsServers: [] + domainName: localdomain + networks: + - isControlPlane: true + mtu: 1500 + name: Control + nameLower: ctlplane + subnets: + - attachConfiguration: br-osp + ipv4: + allocationEnd: "" + allocationStart: "" + cidr: "" + gateway: "" + routes: [] + ipv6: + allocationEnd: 2001:db8:fd00:2000:ffff:ffff:ffff:fffe + allocationStart: 2001:db8:fd00:2000::100 + cidr: 2001:db8:fd00:2000::/64 + gateway: 2001:db8:fd00:2000::1 + routes: [] + name: ctlplane + vlan: 0 + vip: true + ovnBridgeMacMappings: + physNetworks: + - macPrefix: fa:16:3a + name: datacentre + preserveReservations: true + reservations: + controller-1: + ipReservations: + ctlplane: 2001:db8:fd00:2000::41 + macReservations: {} + controller-2: + ipReservations: + ctlplane: 2001:db8:fd00:2000::42 + macReservations: {} + controlplane: + ipReservations: + ctlplane: 2001:db8:fd00:2000::10 + macReservations: {} + openstackclient-0: + ipReservations: + ctlplane: 2001:db8:fd00:2000::251 + macReservations: {} +status: + hosts: + controller-0: + ipaddresses: + ctlplane: 2001:db8:fd00:2000::101/64 + controller-1: + ipaddresses: + ctlplane: 2001:db8:fd00:2000::41/64 + controller-2: + ipaddresses: + ctlplane: 2001:db8:fd00:2000::42/64 + controlplane: + ipaddresses: + ctlplane: 2001:db8:fd00:2000::10/64 + ovnBridgeMacAdresses: {} + openstackclient-0: + ipaddresses: + ctlplane: 2001:db8:fd00:2000::251/64 + ovnBridgeMacAdresses: {} + provisioningStatus: + attachDesiredCount: 1 + attachReadyCount: 1 + netDesiredCount: 1 + netReadyCount: 1 + physNetDesiredCount: 1 + physNetReadyCount: 1 + reason: OpenStackNetConfig openstacknetconfig all resources configured + state: Configured +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackControlPlane +metadata: + name: overcloud + namespace: openstack +spec: + domainName: ostest.test.metalkube.org + enableFencing: false + gitSecret: git-secret + openStackClientImageURL: registry.redhat.io/rhosp-rhel8/openstack-tripleoclient:16.2 + openStackClientNetworks: + - ctlplane + openStackClientStorageClass: host-nfs-storageclass + openStackRelease: "16.2" + passwordSecret: userpassword + virtualMachineRoles: + controller: + baseImageVolumeName: controller-base-img + cores: 6 + ctlplaneInterface: enp2s0 + diskSize: 50 + isTripleoRole: true + memory: 20 + networks: + - ctlplane + roleCount: 3 + roleName: Controller + storageClass: host-nfs-storageclass +status: + ospVersion: "16.2" + provisioningStatus: + clientReady: true + desiredCount: 1 + readyCount: 1 + reason: All requested OSVMSets have been provisioned + state: Provisioned + vipStatus: + controlplane: + annotatedForDeletion: false + hostRef: controlplane + hostname: controlplane + ipaddresses: + ctlplane: 2001:db8:fd00:2000::10/64 + provisioningState: Provisioned +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackVMSet +metadata: + finalizers: + - openstackvmsets.osp-director.openstack.org/virtualmachine + name: controller + namespace: openstack +spec: + baseImageVolumeName: controller-base-img + cores: 6 + ctlplaneInterface: enp2s0 + deploymentSSHSecret: osp-controlplane-ssh-keys + diskSize: 50 + domainName: ostest.test.metalkube.org + isTripleoRole: true + memory: 20 + networks: + - ctlplane + passwordSecret: userpassword + roleName: Controller + storageClass: host-nfs-storageclass + vmCount: 3 +status: + baseImageDVReady: true + provisioningStatus: + readyCount: 3 + reason: All requested VirtualMachines have been provisioned + state: Provisioned + vmHosts: + controller-0: + annotatedForDeletion: false + ctlplaneIP: "" + hostRef: controller-0 + hostname: controller-0 + ipaddresses: + ctlplane: 2001:db8:fd00:2000::101/64 + networkDataSecretName: controller-controller-0-networkdata + provisioningState: Provisioned + userDataSecretName: controller-cloudinit + controller-1: + annotatedForDeletion: false + ctlplaneIP: "" + hostRef: controller-1 + hostname: controller-1 + ipaddresses: + ctlplane: 2001:db8:fd00:2000::41/64 + networkDataSecretName: controller-controller-1-networkdata + provisioningState: Provisioned + userDataSecretName: controller-cloudinit + controller-2: + annotatedForDeletion: false + ctlplaneIP: "" + hostRef: controller-2 + hostname: controller-2 + ipaddresses: + ctlplane: 2001:db8:fd00:2000::42/64 + networkDataSecretName: controller-controller-2-networkdata + provisioningState: Provisioned + userDataSecretName: controller-cloudinit +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackClient +metadata: + name: openstackclient + namespace: openstack +spec: + cloudName: overcloud + deploymentSSHSecret: osp-controlplane-ssh-keys + domainName: ostest.test.metalkube.org + gitSecret: git-secret + imageURL: registry.redhat.io/rhosp-rhel8/openstack-tripleoclient:16.2 + networks: + - ctlplane + runGID: 42401 + runUID: 42401 + storageClass: host-nfs-storageclass +status: + netStatus: + openstackclient-0: + annotatedForDeletion: false + hostRef: openstackclient-0 + hostname: openstackclient-0 + ipaddresses: + ctlplane: 2001:db8:fd00:2000::251/64 + provisioningState: Provisioned +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNet +metadata: + finalizers: + - openstacknet.osp-director.openstack.org + labels: + ooo-ctlplane-network: "true" + ooo-netname: Control + ooo-netname-lower: ctlplane + ooo-subnetname: ctlplane + osp-director.openstack.org/controller: osp-openstacknetconfig + osp-director.openstack.org/name: openstacknetconfig + osp-director.openstack.org/namespace: openstack + name: ctlplane + namespace: openstack +spec: + allocationEnd: 2001:db8:fd00:2000:ffff:ffff:ffff:fffe + allocationStart: 2001:db8:fd00:2000::100 + attachConfiguration: br-osp + cidr: 2001:db8:fd00:2000::/64 + domainName: ctlplane.localdomain + gateway: 2001:db8:fd00:2000::1 + mtu: 1500 + name: Control + nameLower: ctlplane + roleReservations: + ControlPlane: + addToPredictableIPs: true + reservations: + - deleted: false + hostname: controlplane + ip: 2001:db8:fd00:2000::10 + vip: true + Controller: + addToPredictableIPs: true + reservations: + - deleted: false + hostname: controller-0 + ip: 2001:db8:fd00:2000::101 + vip: false + - deleted: false + hostname: controller-1 + ip: 2001:db8:fd00:2000::41 + vip: false + - deleted: false + hostname: controller-2 + ip: 2001:db8:fd00:2000::42 + vip: false + OpenstackClientopenstackclient: + addToPredictableIPs: false + reservations: + - deleted: false + hostname: openstackclient-0 + ip: 2001:db8:fd00:2000::251 + vip: false + routes: [] + vip: true + vlan: 0 +status: + currentState: Configured + reservations: + controller-0: + deleted: false + ip: 2001:db8:fd00:2000::101 + controller-1: + deleted: false + ip: 2001:db8:fd00:2000::41 + controller-2: + deleted: false + ip: 2001:db8:fd00:2000::42 + controlplane: + deleted: false + ip: 2001:db8:fd00:2000::10 + openstackclient-0: + deleted: false + ip: 2001:db8:fd00:2000::251 + reservedIpCount: 5 diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/07-scale_up_openstackcontrolplane.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/07-scale_up_openstackcontrolplane.yaml new file mode 120000 index 00000000..70ad7ee2 --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/07-scale_up_openstackcontrolplane.yaml @@ -0,0 +1 @@ +../../common/tests/scale_up_openstackcontrolplane_3_controllers.yaml \ No newline at end of file diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/08-assert.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/08-assert.yaml new file mode 100644 index 00000000..cf614b32 --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/08-assert.yaml @@ -0,0 +1,301 @@ +# +# Check for: +# +# - 1 OpenStackControlPlane +# - 1 OpenStackVMSet +# - 1 OpenStackClient +# - 6 OpenStackNet (IP reservations for OpenStackControlPlane and OpenStackClient) +# + +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNetConfig +metadata: + finalizers: + - openstacknetconfig.osp-director.openstack.org + name: openstacknetconfig + namespace: openstack +spec: +spec: + attachConfigurations: + br-osp: + nodeNetworkConfigurationPolicy: + desiredState: + interfaces: + - bridge: + options: + stp: + enabled: false + port: + - name: enp7s0 + description: Linux bridge with enp7s0 as a port + mtu: 1500 + name: br-osp + state: up + type: linux-bridge + nodeSelector: + node-role.kubernetes.io/worker: "" + nodeSriovConfigurationPolicy: + desiredState: + deviceType: vfio-pci + mtu: 9000 + numVfs: 0 + port: "" + spoofCheck: "on" + trust: "off" + dnsServers: [] + domainName: localdomain + networks: + - isControlPlane: true + mtu: 1500 + name: Control + nameLower: ctlplane + subnets: + - attachConfiguration: br-osp + ipv4: + allocationEnd: "" + allocationStart: "" + cidr: "" + gateway: "" + routes: [] + ipv6: + allocationEnd: 2001:db8:fd00:2000:ffff:ffff:ffff:fffe + allocationStart: 2001:db8:fd00:2000::100 + cidr: 2001:db8:fd00:2000::/64 + gateway: 2001:db8:fd00:2000::1 + routes: [] + name: ctlplane + vlan: 0 + vip: true + ovnBridgeMacMappings: + physNetworks: + - macPrefix: fa:16:3a + name: datacentre + preserveReservations: true + reservations: + controller-1: + ipReservations: + ctlplane: 2001:db8:fd00:2000::41 + macReservations: {} + controller-2: + ipReservations: + ctlplane: 2001:db8:fd00:2000::42 + macReservations: {} + controlplane: + ipReservations: + ctlplane: 2001:db8:fd00:2000::10 + macReservations: {} + openstackclient-0: + ipReservations: + ctlplane: 2001:db8:fd00:2000::251 + macReservations: {} +status: + hosts: + controller-2: + ipaddresses: + ctlplane: 2001:db8:fd00:2000::42/64 + controlplane: + ipaddresses: + ctlplane: 2001:db8:fd00:2000::10/64 + ovnBridgeMacAdresses: {} + openstackclient-0: + ipaddresses: + ctlplane: 2001:db8:fd00:2000::251/64 + ovnBridgeMacAdresses: {} + provisioningStatus: + attachDesiredCount: 1 + attachReadyCount: 1 + netDesiredCount: 1 + netReadyCount: 1 + physNetDesiredCount: 1 + physNetReadyCount: 1 + reason: OpenStackNetConfig openstacknetconfig all resources configured + state: Configured +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackControlPlane +metadata: + name: overcloud + namespace: openstack +spec: + domainName: ostest.test.metalkube.org + enableFencing: false + gitSecret: git-secret + openStackClientImageURL: registry.redhat.io/rhosp-rhel8/openstack-tripleoclient:16.2 + openStackClientNetworks: + - ctlplane + openStackClientStorageClass: host-nfs-storageclass + openStackRelease: "16.2" + passwordSecret: userpassword + virtualMachineRoles: + controller: + baseImageVolumeName: controller-base-img + cores: 6 + ctlplaneInterface: enp2s0 + diskSize: 50 + isTripleoRole: true + memory: 20 + networks: + - ctlplane + roleCount: 1 + roleName: Controller + storageClass: host-nfs-storageclass +status: + ospVersion: "16.2" + provisioningStatus: + clientReady: true + desiredCount: 1 + readyCount: 1 + reason: All requested OSVMSets have been provisioned + state: Provisioned + vipStatus: + controlplane: + annotatedForDeletion: false + hostRef: controlplane + hostname: controlplane + ipaddresses: + ctlplane: 2001:db8:fd00:2000::10/64 + provisioningState: Provisioned +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackVMSet +metadata: + finalizers: + - openstackvmsets.osp-director.openstack.org/virtualmachine + name: controller + namespace: openstack +spec: + baseImageVolumeName: controller-base-img + cores: 6 + ctlplaneInterface: enp2s0 + deploymentSSHSecret: osp-controlplane-ssh-keys + diskSize: 50 + domainName: ostest.test.metalkube.org + isTripleoRole: true + memory: 20 + networks: + - ctlplane + passwordSecret: userpassword + roleName: Controller + storageClass: host-nfs-storageclass + vmCount: 1 +status: + baseImageDVReady: true + provisioningStatus: + readyCount: 1 + reason: All requested VirtualMachines have been provisioned + state: Provisioned + vmHosts: + controller-2: + annotatedForDeletion: false + ctlplaneIP: "" + hostRef: controller-2 + hostname: controller-2 + ipaddresses: + ctlplane: 2001:db8:fd00:2000::42/64 + networkDataSecretName: controller-controller-2-networkdata + provisioningState: Provisioned + userDataSecretName: controller-cloudinit +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackClient +metadata: + name: openstackclient + namespace: openstack +spec: + cloudName: overcloud + deploymentSSHSecret: osp-controlplane-ssh-keys + domainName: ostest.test.metalkube.org + gitSecret: git-secret + imageURL: registry.redhat.io/rhosp-rhel8/openstack-tripleoclient:16.2 + networks: + - ctlplane + runGID: 42401 + runUID: 42401 + storageClass: host-nfs-storageclass +status: + netStatus: + openstackclient-0: + annotatedForDeletion: false + hostRef: openstackclient-0 + hostname: openstackclient-0 + ipaddresses: + ctlplane: 2001:db8:fd00:2000::251/64 + provisioningState: Provisioned +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNet +metadata: + finalizers: + - openstacknet.osp-director.openstack.org + labels: + ooo-ctlplane-network: "true" + ooo-netname: Control + ooo-netname-lower: ctlplane + ooo-subnetname: ctlplane + osp-director.openstack.org/controller: osp-openstacknetconfig + osp-director.openstack.org/name: openstacknetconfig + osp-director.openstack.org/namespace: openstack + name: ctlplane + namespace: openstack +spec: + allocationEnd: 2001:db8:fd00:2000:ffff:ffff:ffff:fffe + allocationStart: 2001:db8:fd00:2000::100 + attachConfiguration: br-osp + cidr: 2001:db8:fd00:2000::/64 + domainName: ctlplane.localdomain + gateway: 2001:db8:fd00:2000::1 + mtu: 1500 + name: Control + nameLower: ctlplane + roleReservations: + ControlPlane: + addToPredictableIPs: true + reservations: + - deleted: false + hostname: controlplane + ip: 2001:db8:fd00:2000::10 + vip: true + Controller: + addToPredictableIPs: true + reservations: + - deleted: true + hostname: controller-0 + ip: 2001:db8:fd00:2000::101 + vip: false + - deleted: true + hostname: controller-1 + ip: 2001:db8:fd00:2000::41 + vip: false + - deleted: false + hostname: controller-2 + ip: 2001:db8:fd00:2000::42 + vip: false + OpenstackClientopenstackclient: + addToPredictableIPs: false + reservations: + - deleted: false + hostname: openstackclient-0 + ip: 2001:db8:fd00:2000::251 + vip: false + routes: [] + vip: true + vlan: 0 +status: + currentState: Configured + reservations: + controller-0: + deleted: true + ip: 2001:db8:fd00:2000::101 + controller-1: + deleted: true + ip: 2001:db8:fd00:2000::41 + controller-2: + deleted: false + ip: 2001:db8:fd00:2000::42 + controlplane: + deleted: false + ip: 2001:db8:fd00:2000::10 + openstackclient-0: + deleted: false + ip: 2001:db8:fd00:2000::251 + reservedIpCount: 5 diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/08-errors.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/08-errors.yaml new file mode 100644 index 00000000..785fab20 --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/08-errors.yaml @@ -0,0 +1,17 @@ +# +# Check for: +# +# - VirtualMachines (2 should be removed) +# + +apiVersion: kubevirt.io/v1alpha3 +kind: VirtualMachine +metadata: + name: controller-0 + namespace: openstack +--- +apiVersion: kubevirt.io/v1alpha3 +kind: VirtualMachine +metadata: + name: controller-1 + namespace: openstack diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/08-scale_down_openstackcontrolplane.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/08-scale_down_openstackcontrolplane.yaml new file mode 120000 index 00000000..66a7ee1c --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/08-scale_down_openstackcontrolplane.yaml @@ -0,0 +1 @@ +../../common/tests/scale_down_openstackcontrolplane_single_controller.yaml \ No newline at end of file diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/09-assert.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/09-assert.yaml new file mode 100644 index 00000000..076679fd --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/09-assert.yaml @@ -0,0 +1,287 @@ +# +# Check for: +# +# - 1 OpenStackControlPlane +# - 1 OpenStackVMSet +# - 1 OpenStackClient +# - 6 OpenStackNet (IP reservations for OpenStackControlPlane and OpenStackClient) +# + +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNetConfig +metadata: + finalizers: + - openstacknetconfig.osp-director.openstack.org + name: openstacknetconfig + namespace: openstack +spec: +spec: + attachConfigurations: + br-osp: + nodeNetworkConfigurationPolicy: + desiredState: + interfaces: + - bridge: + options: + stp: + enabled: false + port: + - name: enp7s0 + description: Linux bridge with enp7s0 as a port + mtu: 1500 + name: br-osp + state: up + type: linux-bridge + nodeSelector: + node-role.kubernetes.io/worker: "" + nodeSriovConfigurationPolicy: + desiredState: + deviceType: vfio-pci + mtu: 9000 + numVfs: 0 + port: "" + spoofCheck: "on" + trust: "off" + dnsServers: [] + domainName: localdomain + networks: + - isControlPlane: true + mtu: 1500 + name: Control + nameLower: ctlplane + subnets: + - attachConfiguration: br-osp + ipv4: + allocationEnd: "" + allocationStart: "" + cidr: "" + gateway: "" + routes: [] + ipv6: + allocationEnd: 2001:db8:fd00:2000:ffff:ffff:ffff:fffe + allocationStart: 2001:db8:fd00:2000::100 + cidr: 2001:db8:fd00:2000::/64 + gateway: 2001:db8:fd00:2000::1 + routes: [] + name: ctlplane + vlan: 0 + vip: true + ovnBridgeMacMappings: + physNetworks: + - macPrefix: fa:16:3a + name: datacentre + preserveReservations: false + reservations: + controller-1: + ipReservations: + ctlplane: 2001:db8:fd00:2000::41 + macReservations: {} + controller-2: + ipReservations: + ctlplane: 2001:db8:fd00:2000::42 + macReservations: {} + controlplane: + ipReservations: + ctlplane: 2001:db8:fd00:2000::10 + macReservations: {} + openstackclient-0: + ipReservations: + ctlplane: 2001:db8:fd00:2000::251 + macReservations: {} +status: + hosts: + controller-2: + ipaddresses: + ctlplane: 2001:db8:fd00:2000::42/64 + controlplane: + ipaddresses: + ctlplane: 2001:db8:fd00:2000::10/64 + ovnBridgeMacAdresses: {} + openstackclient-0: + ipaddresses: + ctlplane: 2001:db8:fd00:2000::251/64 + ovnBridgeMacAdresses: {} + provisioningStatus: + attachDesiredCount: 1 + attachReadyCount: 1 + netDesiredCount: 1 + netReadyCount: 1 + physNetDesiredCount: 1 + physNetReadyCount: 1 + reason: OpenStackNetConfig openstacknetconfig all resources configured + state: Configured +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackControlPlane +metadata: + name: overcloud + namespace: openstack +spec: + domainName: ostest.test.metalkube.org + enableFencing: false + gitSecret: git-secret + openStackClientImageURL: registry.redhat.io/rhosp-rhel8/openstack-tripleoclient:16.2 + openStackClientNetworks: + - ctlplane + openStackClientStorageClass: host-nfs-storageclass + openStackRelease: "16.2" + passwordSecret: userpassword + virtualMachineRoles: + controller: + baseImageVolumeName: controller-base-img + cores: 6 + ctlplaneInterface: enp2s0 + diskSize: 50 + isTripleoRole: true + memory: 20 + networks: + - ctlplane + roleCount: 1 + roleName: Controller + storageClass: host-nfs-storageclass +status: + ospVersion: "16.2" + provisioningStatus: + clientReady: true + desiredCount: 1 + readyCount: 1 + reason: All requested OSVMSets have been provisioned + state: Provisioned + vipStatus: + controlplane: + annotatedForDeletion: false + hostRef: controlplane + hostname: controlplane + ipaddresses: + ctlplane: 2001:db8:fd00:2000::10/64 + provisioningState: Provisioned +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackVMSet +metadata: + finalizers: + - openstackvmsets.osp-director.openstack.org/virtualmachine + name: controller + namespace: openstack +spec: + baseImageVolumeName: controller-base-img + cores: 6 + ctlplaneInterface: enp2s0 + deploymentSSHSecret: osp-controlplane-ssh-keys + diskSize: 50 + domainName: ostest.test.metalkube.org + isTripleoRole: true + memory: 20 + networks: + - ctlplane + passwordSecret: userpassword + roleName: Controller + storageClass: host-nfs-storageclass + vmCount: 1 +status: + baseImageDVReady: true + provisioningStatus: + readyCount: 1 + reason: All requested VirtualMachines have been provisioned + state: Provisioned + vmHosts: + controller-2: + annotatedForDeletion: false + ctlplaneIP: "" + hostRef: controller-2 + hostname: controller-2 + ipaddresses: + ctlplane: 2001:db8:fd00:2000::42/64 + networkDataSecretName: controller-controller-2-networkdata + provisioningState: Provisioned + userDataSecretName: controller-cloudinit +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackClient +metadata: + name: openstackclient + namespace: openstack +spec: + cloudName: overcloud + deploymentSSHSecret: osp-controlplane-ssh-keys + domainName: ostest.test.metalkube.org + gitSecret: git-secret + imageURL: registry.redhat.io/rhosp-rhel8/openstack-tripleoclient:16.2 + networks: + - ctlplane + runGID: 42401 + runUID: 42401 + storageClass: host-nfs-storageclass +status: + netStatus: + openstackclient-0: + annotatedForDeletion: false + hostRef: openstackclient-0 + hostname: openstackclient-0 + ipaddresses: + ctlplane: 2001:db8:fd00:2000::251/64 + provisioningState: Provisioned +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNet +metadata: + finalizers: + - openstacknet.osp-director.openstack.org + labels: + ooo-ctlplane-network: "true" + ooo-netname: Control + ooo-netname-lower: ctlplane + ooo-subnetname: ctlplane + osp-director.openstack.org/controller: osp-openstacknetconfig + osp-director.openstack.org/name: openstacknetconfig + osp-director.openstack.org/namespace: openstack + name: ctlplane + namespace: openstack +spec: + allocationEnd: 2001:db8:fd00:2000:ffff:ffff:ffff:fffe + allocationStart: 2001:db8:fd00:2000::100 + attachConfiguration: br-osp + cidr: 2001:db8:fd00:2000::/64 + domainName: ctlplane.localdomain + gateway: 2001:db8:fd00:2000::1 + mtu: 1500 + name: Control + nameLower: ctlplane + roleReservations: + ControlPlane: + addToPredictableIPs: true + reservations: + - deleted: false + hostname: controlplane + ip: 2001:db8:fd00:2000::10 + vip: true + Controller: + addToPredictableIPs: true + reservations: + - deleted: false + hostname: controller-2 + ip: 2001:db8:fd00:2000::42 + vip: false + OpenstackClientopenstackclient: + addToPredictableIPs: false + reservations: + - deleted: false + hostname: openstackclient-0 + ip: 2001:db8:fd00:2000::251 + vip: false + routes: [] + vip: true + vlan: 0 +status: + currentState: Configured + reservations: + controller-2: + deleted: false + ip: 2001:db8:fd00:2000::42 + controlplane: + deleted: false + ip: 2001:db8:fd00:2000::10 + openstackclient-0: + deleted: false + ip: 2001:db8:fd00:2000::251 + reservedIpCount: 3 diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/09-switch_preserveReservations_off.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/09-switch_preserveReservations_off.yaml new file mode 100644 index 00000000..a6fdb932 --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/09-switch_preserveReservations_off.yaml @@ -0,0 +1,10 @@ +# +# Disable preserveReservations +# + +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: | + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "add", "path": "/spec/preserveReservations", "value": false}]' + namespaced: true diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/10-add_network.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/10-add_network.yaml new file mode 100644 index 00000000..6afca636 --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/10-add_network.yaml @@ -0,0 +1,10 @@ +# +# Add new network definition to spec.networks +# + +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: | + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "add", "path": "/spec/networks/-", "value": {"name": "InternalApi", "nameLower": "internal_api","subnets": [{"name": "internal_api", "vlan": 20, "attachConfiguration": "br-osp", "ipv6": {"allocationEnd": "fd00:fd00:fd00:2000:ffff:ffff:ffff:fffe", "allocationStart": "fd00:fd00:fd00:2000::10", "cidr": "fd00:fd00:fd00:2000::/64"}}]}}]' + namespaced: true diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/10-assert.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/10-assert.yaml new file mode 100644 index 00000000..c444fb0e --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/10-assert.yaml @@ -0,0 +1,164 @@ +# +# Check for: +# +# - 1 OpenStackNetConfig +# - 1 OpenStackMACAddress +# - 1 TestAssert +# + +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNetConfig +metadata: + finalizers: + - openstacknetconfig.osp-director.openstack.org + name: openstacknetconfig + namespace: openstack +spec: + attachConfigurations: + br-osp: + nodeNetworkConfigurationPolicy: + desiredState: + interfaces: + - bridge: + options: + stp: + enabled: false + port: + - name: enp7s0 + description: Linux bridge with enp7s0 as a port + mtu: 1500 + name: br-osp + state: up + type: linux-bridge + nodeSelector: + node-role.kubernetes.io/worker: "" + nodeSriovConfigurationPolicy: + desiredState: + deviceType: vfio-pci + mtu: 9000 + numVfs: 0 + port: "" + spoofCheck: "on" + trust: "off" + dnsServers: [] + domainName: localdomain + networks: + - isControlPlane: true + mtu: 1500 + name: Control + nameLower: ctlplane + subnets: + - attachConfiguration: br-osp + ipv4: + allocationEnd: "" + allocationStart: "" + cidr: "" + gateway: "" + routes: [] + ipv6: + allocationEnd: 2001:db8:fd00:2000:ffff:ffff:ffff:fffe + allocationStart: 2001:db8:fd00:2000::100 + cidr: 2001:db8:fd00:2000::/64 + gateway: 2001:db8:fd00:2000::1 + routes: [] + name: ctlplane + vlan: 0 + vip: true + - isControlPlane: false + mtu: 1500 + name: InternalApi + nameLower: internal_api + subnets: + - attachConfiguration: br-osp + ipv4: + allocationEnd: "" + allocationStart: "" + cidr: "" + gateway: "" + routes: [] + ipv6: + allocationEnd: fd00:fd00:fd00:2000:ffff:ffff:ffff:fffe + allocationStart: fd00:fd00:fd00:2000::10 + cidr: fd00:fd00:fd00:2000::/64 + gateway: "" + routes: [] + name: internal_api + vlan: 20 + vip: true + ovnBridgeMacMappings: + physNetworks: + - macPrefix: fa:16:3a + name: datacentre + preserveReservations: false + reservations: + controller-1: + ipReservations: + ctlplane: 2001:db8:fd00:2000::41 + macReservations: {} + controller-2: + ipReservations: + ctlplane: 2001:db8:fd00:2000::42 + macReservations: {} + controlplane: + ipReservations: + ctlplane: 2001:db8:fd00:2000::10 + macReservations: {} + openstackclient-0: + ipReservations: + ctlplane: 2001:db8:fd00:2000::251 + macReservations: {} +status: + provisioningStatus: + attachDesiredCount: 1 + attachReadyCount: 1 + netDesiredCount: 2 + netReadyCount: 2 + physNetDesiredCount: 1 + physNetReadyCount: 1 + reason: OpenStackNetConfig openstacknetconfig all resources configured + state: Configured +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNet +metadata: + name: internalapi + namespace: openstack +spec: + allocationEnd: fd00:fd00:fd00:2000:ffff:ffff:ffff:fffe + allocationStart: fd00:fd00:fd00:2000::10 + attachConfiguration: br-osp + cidr: fd00:fd00:fd00:2000::/64 + domainName: internalapi.localdomain + gateway: "" + mtu: 1500 + name: InternalApi + nameLower: internal_api + roleReservations: {} + routes: [] + vip: true + vlan: 20 +status: + conditions: + - message: OpenStackNet internalapi has been successfully configured on targeted node(s) + reason: OpenStackNet internalapi has been successfully configured on targeted node(s) + status: "True" + type: Configured + currentState: Configured + reservations: {} + reservedIpCount: 0 +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +timeout: 10 +namespaced: true +commands: + - script: | + set -x + # should return the new reservation for the added physnet + reservation=$(oc get -n openstack osmacaddr openstacknetconfig -o json | jq .spec.roleReservations.Controller.reservations | jq -r 'to_entries | map(select(.key == "controller-2"))[0] | .value.reservations.datacentre2'| wc -l) + if [ $reservation -eq 1 ]; then + exit 0 + else + exit 1 + fi + diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/11-add_network_to_vmrole.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/11-add_network_to_vmrole.yaml new file mode 100644 index 00000000..4c38a473 --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/11-add_network_to_vmrole.yaml @@ -0,0 +1,10 @@ +# +# Add new network definition to spec.networks +# + +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: | + oc patch -n openstack osctlplane overcloud --type='json' -p='[{"op": "add", "path": "/spec/virtualMachineRoles/controller/networks/-", "value": "internal_api"}]' + namespaced: true diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/11-assert.yaml b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/11-assert.yaml new file mode 100644 index 00000000..52979522 --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/11-assert.yaml @@ -0,0 +1,276 @@ +# +# Check for: +# +# - 1 OpenStackNetConfig +# - 2 OpenStackNet +# - 1 OpenStackVMset +# + +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNetConfig +metadata: + name: openstacknetconfig + namespace: openstack +spec: + attachConfigurations: + br-osp: + nodeNetworkConfigurationPolicy: + desiredState: + interfaces: + - bridge: + options: + stp: + enabled: false + port: + - name: enp7s0 + description: Linux bridge with enp7s0 as a port + mtu: 1500 + name: br-osp + state: up + type: linux-bridge + nodeSelector: + node-role.kubernetes.io/worker: "" + nodeSriovConfigurationPolicy: + desiredState: + deviceType: vfio-pci + mtu: 9000 + numVfs: 0 + port: "" + spoofCheck: "on" + trust: "off" + dnsServers: [] + domainName: localdomain + networks: + - isControlPlane: true + mtu: 1500 + name: Control + nameLower: ctlplane + subnets: + - attachConfiguration: br-osp + ipv4: + allocationEnd: "" + allocationStart: "" + cidr: "" + gateway: "" + routes: [] + ipv6: + allocationEnd: 2001:db8:fd00:2000:ffff:ffff:ffff:fffe + allocationStart: 2001:db8:fd00:2000::100 + cidr: 2001:db8:fd00:2000::/64 + gateway: 2001:db8:fd00:2000::1 + routes: [] + name: ctlplane + vlan: 0 + vip: true + - isControlPlane: false + mtu: 1500 + name: InternalApi + nameLower: internal_api + subnets: + - attachConfiguration: br-osp + ipv4: + allocationEnd: "" + allocationStart: "" + cidr: "" + gateway: "" + routes: [] + ipv6: + allocationEnd: fd00:fd00:fd00:2000:ffff:ffff:ffff:fffe + allocationStart: fd00:fd00:fd00:2000::10 + cidr: fd00:fd00:fd00:2000::/64 + gateway: "" + routes: [] + name: internal_api + vlan: 20 + vip: true + ovnBridgeMacMappings: + physNetworks: + - macPrefix: fa:16:3a + name: datacentre + reservations: + controller-1: + ipReservations: + ctlplane: 2001:db8:fd00:2000::41 + macReservations: {} + controller-2: + ipReservations: + ctlplane: 2001:db8:fd00:2000::42 + macReservations: {} + controlplane: + ipReservations: + ctlplane: 2001:db8:fd00:2000::10 + macReservations: {} + openstackclient-0: + ipReservations: + ctlplane: 2001:db8:fd00:2000::251 + macReservations: {} +status: + hosts: + controller-0: + ipaddresses: {} + ovnBridgeMacAdresses: {} + controller-1: + ipaddresses: {} + ovnBridgeMacAdresses: {} + controller-2: + ipaddresses: + ctlplane: 2001:db8:fd00:2000::42/64 + internal_api: fd00:fd00:fd00:2000::11/64 + controlplane: + ipaddresses: + ctlplane: 2001:db8:fd00:2000::10/64 + internal_api: fd00:fd00:fd00:2000::10/64 + ovnBridgeMacAdresses: {} + openstackclient-0: + ipaddresses: + ctlplane: 2001:db8:fd00:2000::251/64 + ovnBridgeMacAdresses: {} + provisioningStatus: + attachDesiredCount: 1 + attachReadyCount: 1 + netDesiredCount: 2 + netReadyCount: 2 + physNetDesiredCount: 1 + physNetReadyCount: 1 + reason: OpenStackNetConfig openstacknetconfig all resources configured + state: Configured +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNet +metadata: + name: ctlplane + namespace: openstack +spec: + allocationEnd: 2001:db8:fd00:2000:ffff:ffff:ffff:fffe + allocationStart: 2001:db8:fd00:2000::100 + attachConfiguration: br-osp + cidr: 2001:db8:fd00:2000::/64 + domainName: ctlplane.localdomain + gateway: 2001:db8:fd00:2000::1 + mtu: 1500 + name: Control + nameLower: ctlplane + roleReservations: + ControlPlane: + addToPredictableIPs: true + reservations: + - deleted: false + hostname: controlplane + ip: 2001:db8:fd00:2000::10 + vip: true + Controller: + addToPredictableIPs: true + reservations: + - deleted: false + hostname: controller-2 + ip: 2001:db8:fd00:2000::42 + vip: false + OpenstackClientopenstackclient: + addToPredictableIPs: false + reservations: + - deleted: false + hostname: openstackclient-0 + ip: 2001:db8:fd00:2000::251 + vip: false + routes: [] + vip: true + vlan: 0 +status: + currentState: Configured + reservations: + controller-2: + deleted: false + ip: 2001:db8:fd00:2000::42 + controlplane: + deleted: false + ip: 2001:db8:fd00:2000::10 + openstackclient-0: + deleted: false + ip: 2001:db8:fd00:2000::251 + reservedIpCount: 3 +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNet +metadata: + name: internalapi + namespace: openstack +spec: + allocationEnd: fd00:fd00:fd00:2000:ffff:ffff:ffff:fffe + allocationStart: fd00:fd00:fd00:2000::10 + attachConfiguration: br-osp + cidr: fd00:fd00:fd00:2000::/64 + domainName: internalapi.localdomain + gateway: "" + mtu: 1500 + name: InternalApi + nameLower: internal_api + roleReservations: + ControlPlane: + addToPredictableIPs: true + reservations: + - deleted: false + hostname: controlplane + ip: fd00:fd00:fd00:2000::10 + vip: true + Controller: + addToPredictableIPs: true + reservations: + - deleted: false + hostname: controller-2 + ip: fd00:fd00:fd00:2000::11 + vip: false + routes: [] + vip: true + vlan: 20 +status: + currentState: Configured + reservations: + controller-2: + deleted: false + ip: fd00:fd00:fd00:2000::11 + controlplane: + deleted: false + ip: fd00:fd00:fd00:2000::10 + reservedIpCount: 2 +--- +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackVMSet +metadata: + name: controller + namespace: openstack +spec: + baseImageVolumeName: controller-base-img + cores: 6 + ctlplaneInterface: enp2s0 + deploymentSSHSecret: osp-controlplane-ssh-keys + diskSize: 50 + domainName: ostest.test.metalkube.org + isTripleoRole: true + memory: 20 + networks: + - ctlplane + - internal_api + passwordSecret: userpassword + roleName: Controller + storageAccessMode: ReadWriteMany + storageClass: host-nfs-storageclass + storageVolumeMode: Filesystem + vmCount: 1 +status: + baseImageDVReady: true + provisioningStatus: + readyCount: 1 + reason: All requested VirtualMachines have been provisioned + state: Provisioned + vmHosts: + controller-2: + annotatedForDeletion: false + ctlplaneIP: "" + hostRef: controller-2 + hostname: controller-2 + ipaddresses: + ctlplane: 2001:db8:fd00:2000::42/64 + internal_api: fd00:fd00:fd00:2000::11/64 + networkDataSecretName: controller-controller-2-networkdata + provisioningState: Provisioned + userDataSecretName: controller-cloudinit diff --git a/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/README.md b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/README.md new file mode 100644 index 00000000..a852943c --- /dev/null +++ b/tests/kuttl/tests/openstacknetconfig_ip_reservation_ipv6/README.md @@ -0,0 +1,14 @@ +Q: WHAT IS TESTED HERE? + +A: +- create osnetcfg with no static reservation +- add static reservation for controller-0 +- scale up to 1 controller ctlplane +- Run webhook fail tests + - add static reservation with wrong IP format + - add static reservation with dupe IP +- add good additional reservation +- scale ctlplane nodes +- scale down node to verify reservation persist +- set persist to false to verify reservations for deleted nodes are gone +- add a new network diff --git a/tests/kuttl/tests/openstackprovisionserver_unique_port/01-assert.yaml b/tests/kuttl/tests/openstackprovisionserver_unique_port/01-assert.yaml index 5faae385..48f1a4f0 100644 --- a/tests/kuttl/tests/openstackprovisionserver_unique_port/01-assert.yaml +++ b/tests/kuttl/tests/openstackprovisionserver_unique_port/01-assert.yaml @@ -10,7 +10,7 @@ metadata: name: openstack namespace: openstack spec: - apacheImageUrl: registry.redhat.io/rhel8/httpd-24@sha256:d63a22b930f0309a8bb160b452147e81ceb1d3fd3df2d78f0a30e763e1d6f0c4 + apacheImageUrl: registry.redhat.io/rhel8/httpd-24@sha256:87d58041da70f094e685511f86f8a83e9b2a67424fcf8cf2530ff071f566350b baseImageUrl: http://192.168.111.1/images/rhel-guest-image-8.4-992.x86_64.qcow2 downloaderImageUrl: registry.redhat.io/rhosp-rhel8-tech-preview/osp-director-downloader@sha256:dadca151e8712eef8b206b69722c558b2aac035a4a3c52e705bf69c26d649567 port: 8080 diff --git a/tests/kuttl/tests/openstackprovisionserver_unique_port/02-assert.yaml b/tests/kuttl/tests/openstackprovisionserver_unique_port/02-assert.yaml index a2fd8e39..b7806523 100644 --- a/tests/kuttl/tests/openstackprovisionserver_unique_port/02-assert.yaml +++ b/tests/kuttl/tests/openstackprovisionserver_unique_port/02-assert.yaml @@ -10,7 +10,7 @@ metadata: name: goodprov namespace: openstack spec: - apacheImageUrl: registry.redhat.io/rhel8/httpd-24@sha256:d63a22b930f0309a8bb160b452147e81ceb1d3fd3df2d78f0a30e763e1d6f0c4 + apacheImageUrl: registry.redhat.io/rhel8/httpd-24@sha256:87d58041da70f094e685511f86f8a83e9b2a67424fcf8cf2530ff071f566350b baseImageUrl: http://192.168.111.1/images/rhel-guest-image-8.4-992.x86_64.qcow2 downloaderImageUrl: registry.redhat.io/rhosp-rhel8-tech-preview/osp-director-downloader@sha256:dadca151e8712eef8b206b69722c558b2aac035a4a3c52e705bf69c26d649567 port: 8081 diff --git a/tests/kuttl/tests/openstackprovisionserver_unique_port/06-assert.yaml b/tests/kuttl/tests/openstackprovisionserver_unique_port/06-assert.yaml index 068a65f7..b7703682 100644 --- a/tests/kuttl/tests/openstackprovisionserver_unique_port/06-assert.yaml +++ b/tests/kuttl/tests/openstackprovisionserver_unique_port/06-assert.yaml @@ -10,7 +10,7 @@ metadata: name: compute-provisionserver namespace: openstack spec: - apacheImageUrl: registry.redhat.io/rhel8/httpd-24@sha256:d63a22b930f0309a8bb160b452147e81ceb1d3fd3df2d78f0a30e763e1d6f0c4 + apacheImageUrl: registry.redhat.io/rhel8/httpd-24@sha256:87d58041da70f094e685511f86f8a83e9b2a67424fcf8cf2530ff071f566350b baseImageUrl: http://192.168.111.1/images/rhel-guest-image-8.4-992.x86_64.qcow2 downloaderImageUrl: registry.redhat.io/rhosp-rhel8-tech-preview/osp-director-downloader@sha256:dadca151e8712eef8b206b69722c558b2aac035a4a3c52e705bf69c26d649567 port: 6190 diff --git a/tests/kuttl/tests/openstackprovisionserver_unique_port/07-assert.yaml b/tests/kuttl/tests/openstackprovisionserver_unique_port/07-assert.yaml index b28c6c60..cfd19926 100644 --- a/tests/kuttl/tests/openstackprovisionserver_unique_port/07-assert.yaml +++ b/tests/kuttl/tests/openstackprovisionserver_unique_port/07-assert.yaml @@ -10,7 +10,7 @@ metadata: name: compute2-provisionserver namespace: openstack spec: - apacheImageUrl: registry.redhat.io/rhel8/httpd-24@sha256:d63a22b930f0309a8bb160b452147e81ceb1d3fd3df2d78f0a30e763e1d6f0c4 + apacheImageUrl: registry.redhat.io/rhel8/httpd-24@sha256:87d58041da70f094e685511f86f8a83e9b2a67424fcf8cf2530ff071f566350b baseImageUrl: http://192.168.111.1/images/rhel-guest-image-8.4-992.x86_64.qcow2 downloaderImageUrl: registry.redhat.io/rhosp-rhel8-tech-preview/osp-director-downloader@sha256:dadca151e8712eef8b206b69722c558b2aac035a4a3c52e705bf69c26d649567 port: 6191 diff --git a/tests/kuttl/tests/ovnBridgeMacMappings/02-add_static_reservation.yaml b/tests/kuttl/tests/ovnBridgeMacMappings/02-add_static_reservation.yaml index 3d48cd42..eddab24c 100644 --- a/tests/kuttl/tests/ovnBridgeMacMappings/02-add_static_reservation.yaml +++ b/tests/kuttl/tests/ovnBridgeMacMappings/02-add_static_reservation.yaml @@ -6,5 +6,8 @@ apiVersion: kuttl.dev/v1beta1 kind: TestStep commands: - command: | - oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "add", "path": "/spec/ovnBridgeMacMappings/staticReservations", "value": {"controller-0": {"reservations":{"datacentre": "fa:16:3a:aa:aa:aa" }}}}]' + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "add", "path": "/spec/reservations/controller-0", "value": {"ipReservations":{}, "macReservations": {}}}]' + namespaced: true + - command: | + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "add", "path": "/spec/reservations/controller-0/macReservations", "value": {"datacentre": "fa:16:3a:aa:aa:aa" }}]' namespaced: true diff --git a/tests/kuttl/tests/ovnBridgeMacMappings/02-assert.yaml b/tests/kuttl/tests/ovnBridgeMacMappings/02-assert.yaml index 39e5beb9..64676095 100644 --- a/tests/kuttl/tests/ovnBridgeMacMappings/02-assert.yaml +++ b/tests/kuttl/tests/ovnBridgeMacMappings/02-assert.yaml @@ -71,12 +71,20 @@ spec: physNetworks: - macPrefix: fa:16:3a name: datacentre - staticReservations: - controller-0: - deleted: false - reservations: - datacentre: fa:16:3a:aa:aa:aa preserveReservations: true + reservations: + controller-0: + ipReservations: {} + macReservations: + datacentre: fa:16:3a:aa:aa:aa + controlplane: + ipReservations: + ctlplane: 192.168.25.10 + macReservations: {} + openstackclient-0: + ipReservations: + ctlplane: 192.168.25.251 + macReservations: {} status: provisioningStatus: attachDesiredCount: 1 diff --git a/tests/kuttl/tests/ovnBridgeMacMappings/03-assert.yaml b/tests/kuttl/tests/ovnBridgeMacMappings/03-assert.yaml index 216099ab..2bfabe5b 100644 --- a/tests/kuttl/tests/ovnBridgeMacMappings/03-assert.yaml +++ b/tests/kuttl/tests/ovnBridgeMacMappings/03-assert.yaml @@ -15,7 +15,6 @@ metadata: - openstacknetconfig.osp-director.openstack.org name: openstacknetconfig namespace: openstack -spec: spec: attachConfigurations: br-osp: @@ -71,15 +70,23 @@ spec: physNetworks: - macPrefix: fa:16:3a name: datacentre - staticReservations: - controller-0: - deleted: false - reservations: - datacentre: fa:16:3a:aa:aa:aa - controller-1: - deleted: false - reservations: {} preserveReservations: true + reservations: + controller-0: + ipReservations: {} + macReservations: + datacentre: fa:16:3a:aa:aa:aa + controller-1: + ipReservations: {} + macReservations: {} + openstackclient-0: + ipReservations: + ctlplane: 192.168.25.251 + macReservations: {} + controlplane: + ipReservations: + ctlplane: 192.168.25.10 + macReservations: {} status: provisioningStatus: attachDesiredCount: 1 diff --git a/tests/kuttl/tests/ovnBridgeMacMappings/03-webhook_validations.yaml b/tests/kuttl/tests/ovnBridgeMacMappings/03-webhook_validations.yaml index 5ee44c64..66651be8 100644 --- a/tests/kuttl/tests/ovnBridgeMacMappings/03-webhook_validations.yaml +++ b/tests/kuttl/tests/ovnBridgeMacMappings/03-webhook_validations.yaml @@ -10,20 +10,20 @@ kind: TestStep commands: - command: | # change MAC of current reservation - oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "replace", "path": "/spec/ovnBridgeMacMappings/staticReservations/controller-0/reservations/datacentre", "value": "fa:16:3a:aa:aa:bb"}]' + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "replace", "path": "/spec/reservations/controller-0/macReservations/datacentre", "value": "fa:16:3a:aa:aa:bb"}]' namespaced: true ignoreFailure: true - command: | - # add new empty reservation - oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "add", "path": "/spec/ovnBridgeMacMappings/staticReservations/controller-1", "value": {"reservations":{}}}]' + # add new empty reservation for controller-1 + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "add", "path": "/spec/reservations/controller-1", "value": {"ipReservations":{}, "macReservations": {}}}]' namespaced: true - command: | # add static reservation with dupe MAC - oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "add", "path": "/spec/ovnBridgeMacMappings/staticReservations/controller-1", "value": {"reservations":{"datacentre": "fa:16:3a:aa:aa:aa" }}}]' + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "replace", "path": "/spec/reservations/controller-1/macReservations/datacentre", "value": "fa:16:3a:aa:aa:aa"}]' namespaced: true ignoreFailure: true - command: | # add static reservation with wrong MAC format - oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "add", "path": "/spec/ovnBridgeMacMappings/staticReservations/controller-1", "value": {"reservations":{"datacentre": "fa:16:3a:aa:aa" }}}]' + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "add", "path": "/spec/reservations/controller-1/macReservations/datacentre", "value": "fa:16:3a:aa:aa" }]' namespaced: true ignoreFailure: true diff --git a/tests/kuttl/tests/ovnBridgeMacMappings/04-add_second_reservation.yaml b/tests/kuttl/tests/ovnBridgeMacMappings/04-add_second_reservation.yaml index bd402b23..528d913c 100644 --- a/tests/kuttl/tests/ovnBridgeMacMappings/04-add_second_reservation.yaml +++ b/tests/kuttl/tests/ovnBridgeMacMappings/04-add_second_reservation.yaml @@ -6,12 +6,12 @@ apiVersion: kuttl.dev/v1beta1 kind: TestStep commands: - command: | - oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "add", "path": "/spec/ovnBridgeMacMappings/staticReservations/controller-1/reservations", "value": {"datacentre": "fa:16:3a:aa:aa:bb"}}]' + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "replace", "path": "/spec/reservations/controller-1/macReservations/datacentre", "value": "fa:16:3a:aa:aa:bb"}]' namespaced: true - command: | - # add new empty reservation - oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "add", "path": "/spec/ovnBridgeMacMappings/staticReservations/controller-2", "value": {"reservations":{}}}]' + # add new empty reservation for controller-2 + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "add", "path": "/spec/reservations/controller-2", "value": {"ipReservations":{}, "macReservations": {}}}]' namespaced: true - command: | - oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "add", "path": "/spec/ovnBridgeMacMappings/staticReservations/controller-2/reservations", "value": {"datacentre": "fa:16:3a:aa:aa:cc"}}]' + oc patch -n openstack osnetcfg openstacknetconfig --type='json' -p='[{"op": "replace", "path": "/spec/reservations/controller-2/macReservations/datacentre", "value": "fa:16:3a:aa:aa:cc"}]' namespaced: true diff --git a/tests/kuttl/tests/ovnBridgeMacMappings/04-assert.yaml b/tests/kuttl/tests/ovnBridgeMacMappings/04-assert.yaml index 037d00fa..0b9ff49d 100644 --- a/tests/kuttl/tests/ovnBridgeMacMappings/04-assert.yaml +++ b/tests/kuttl/tests/ovnBridgeMacMappings/04-assert.yaml @@ -71,20 +71,28 @@ spec: physNetworks: - macPrefix: fa:16:3a name: datacentre - staticReservations: - controller-0: - deleted: false - reservations: - datacentre: fa:16:3a:aa:aa:aa - controller-1: - deleted: false - reservations: - datacentre: fa:16:3a:aa:aa:bb - controller-2: - deleted: false - reservations: - datacentre: fa:16:3a:aa:aa:cc preserveReservations: true + reservations: + controller-0: + ipReservations: {} + macReservations: + datacentre: fa:16:3a:aa:aa:aa + controller-1: + ipReservations: {} + macReservations: + datacentre: fa:16:3a:aa:aa:bb + controller-2: + ipReservations: {} + macReservations: + datacentre: fa:16:3a:aa:aa:cc + openstackclient-0: + ipReservations: + ctlplane: 192.168.25.251 + macReservations: {} + controlplane: + ipReservations: + ctlplane: 192.168.25.10 + macReservations: {} status: provisioningStatus: attachDesiredCount: 1 diff --git a/tests/kuttl/tests/ovnBridgeMacMappings/06-assert.yaml b/tests/kuttl/tests/ovnBridgeMacMappings/06-assert.yaml index 56ca5167..757740bd 100644 --- a/tests/kuttl/tests/ovnBridgeMacMappings/06-assert.yaml +++ b/tests/kuttl/tests/ovnBridgeMacMappings/06-assert.yaml @@ -1,6 +1,7 @@ # # Check for: # +# - 1 OpenStackNetConfig # - 1 OpenStackControlPlane # - 1 OpenStackVMSet # - 1 OpenStackClient @@ -9,6 +10,126 @@ # - 1 OpenStackMACAddress # +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNetConfig +metadata: + finalizers: + - openstacknetconfig.osp-director.openstack.org + name: openstacknetconfig + namespace: openstack +spec: +spec: + attachConfigurations: + br-osp: + nodeNetworkConfigurationPolicy: + desiredState: + interfaces: + - bridge: + options: + stp: + enabled: false + port: + - name: enp7s0 + description: Linux bridge with enp7s0 as a port + mtu: 1500 + name: br-osp + state: up + type: linux-bridge + nodeSelector: + node-role.kubernetes.io/worker: "" + nodeSriovConfigurationPolicy: + desiredState: + deviceType: vfio-pci + mtu: 9000 + numVfs: 0 + port: "" + spoofCheck: "on" + trust: "off" + dnsServers: [] + domainName: localdomain + networks: + - isControlPlane: true + mtu: 1500 + name: Control + nameLower: ctlplane + subnets: + - attachConfiguration: br-osp + ipv4: + allocationEnd: 192.168.25.250 + allocationStart: 192.168.25.100 + cidr: 192.168.25.0/24 + gateway: 192.168.25.1 + routes: [] + ipv6: + allocationEnd: "" + allocationStart: "" + cidr: "" + gateway: "" + routes: [] + name: ctlplane + vlan: 0 + vip: true + ovnBridgeMacMappings: + physNetworks: + - macPrefix: fa:16:3a + name: datacentre + preserveReservations: true + reservations: + controller-0: + ipReservations: {} + macReservations: + datacentre: fa:16:3a:aa:aa:aa + controller-1: + ipReservations: {} + macReservations: + datacentre: fa:16:3a:aa:aa:bb + controller-2: + ipReservations: {} + macReservations: + datacentre: fa:16:3a:aa:aa:cc + controlplane: + ipReservations: + ctlplane: 192.168.25.10 + macReservations: {} + openstackclient-0: + ipReservations: + ctlplane: 192.168.25.251 + macReservations: {} +status: + hosts: + controller-0: + ipaddresses: + ctlplane: 192.168.25.100/24 + ovnBridgeMacAdresses: + datacentre: fa:16:3a:aa:aa:aa + controller-1: + ipaddresses: + ctlplane: 192.168.25.101/24 + ovnBridgeMacAdresses: + datacentre: fa:16:3a:aa:aa:bb + controller-2: + ipaddresses: + ctlplane: 192.168.25.102/24 + ovnBridgeMacAdresses: + datacentre: fa:16:3a:aa:aa:cc + controlplane: + ipaddresses: + ctlplane: 192.168.25.10/24 + ovnBridgeMacAdresses: {} + openstackclient-0: + ipaddresses: + ctlplane: 192.168.25.251/24 + ovnBridgeMacAdresses: {} + provisioningStatus: + attachDesiredCount: 1 + attachReadyCount: 1 + netDesiredCount: 1 + netReadyCount: 1 + physNetDesiredCount: 1 + physNetReadyCount: 1 + reason: OpenStackNetConfig openstacknetconfig all resources configured + state: Configured +--- apiVersion: osp-director.openstack.org/v1beta1 kind: OpenStackControlPlane metadata: @@ -51,7 +172,7 @@ status: hostRef: controlplane hostname: controlplane ipaddresses: - ctlplane: 192.168.25.100/24 + ctlplane: 192.168.25.10/24 provisioningState: Provisioned --- apiVersion: osp-director.openstack.org/v1beta1 @@ -89,7 +210,7 @@ status: hostRef: controller-0 hostname: controller-0 ipaddresses: - ctlplane: 192.168.25.102/24 + ctlplane: 192.168.25.100/24 networkDataSecretName: controller-controller-0-networkdata provisioningState: Provisioned userDataSecretName: controller-cloudinit @@ -99,7 +220,7 @@ status: hostRef: controller-1 hostname: controller-1 ipaddresses: - ctlplane: 192.168.25.103/24 + ctlplane: 192.168.25.101/24 networkDataSecretName: controller-controller-1-networkdata provisioningState: Provisioned userDataSecretName: controller-cloudinit @@ -109,7 +230,7 @@ status: hostRef: controller-2 hostname: controller-2 ipaddresses: - ctlplane: 192.168.25.104/24 + ctlplane: 192.168.25.102/24 networkDataSecretName: controller-controller-2-networkdata provisioningState: Provisioned userDataSecretName: controller-cloudinit @@ -137,7 +258,7 @@ status: hostRef: openstackclient-0 hostname: openstackclient-0 ipaddresses: - ctlplane: 192.168.25.101/24 + ctlplane: 192.168.25.251/24 provisioningState: Provisioned --- apiVersion: osp-director.openstack.org/v1beta1 @@ -171,29 +292,29 @@ spec: reservations: - deleted: false hostname: controlplane - ip: 192.168.25.100 + ip: 192.168.25.10 vip: true Controller: addToPredictableIPs: true reservations: - deleted: false hostname: controller-0 - ip: 192.168.25.102 + ip: 192.168.25.100 vip: false - deleted: false hostname: controller-1 - ip: 192.168.25.103 + ip: 192.168.25.101 vip: false - deleted: false hostname: controller-2 - ip: 192.168.25.104 + ip: 192.168.25.102 vip: false OpenstackClientopenstackclient: addToPredictableIPs: false reservations: - deleted: false hostname: openstackclient-0 - ip: 192.168.25.101 + ip: 192.168.25.251 vip: false routes: [] vip: true @@ -203,19 +324,19 @@ status: reservations: controller-0: deleted: false - ip: 192.168.25.102 + ip: 192.168.25.100 controller-1: deleted: false - ip: 192.168.25.103 + ip: 192.168.25.101 controller-2: deleted: false - ip: 192.168.25.104 + ip: 192.168.25.102 controlplane: deleted: false - ip: 192.168.25.100 + ip: 192.168.25.10 openstackclient-0: deleted: false - ip: 192.168.25.101 + ip: 192.168.25.251 reservedIpCount: 5 --- apiVersion: v1 diff --git a/tests/kuttl/tests/ovnBridgeMacMappings/07-assert.yaml b/tests/kuttl/tests/ovnBridgeMacMappings/07-assert.yaml index 83a63d7d..354bb387 100644 --- a/tests/kuttl/tests/ovnBridgeMacMappings/07-assert.yaml +++ b/tests/kuttl/tests/ovnBridgeMacMappings/07-assert.yaml @@ -9,6 +9,116 @@ # - 1 OpenStackMACAddress # +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNetConfig +metadata: + finalizers: + - openstacknetconfig.osp-director.openstack.org + name: openstacknetconfig + namespace: openstack +spec: +spec: + attachConfigurations: + br-osp: + nodeNetworkConfigurationPolicy: + desiredState: + interfaces: + - bridge: + options: + stp: + enabled: false + port: + - name: enp7s0 + description: Linux bridge with enp7s0 as a port + mtu: 1500 + name: br-osp + state: up + type: linux-bridge + nodeSelector: + node-role.kubernetes.io/worker: "" + nodeSriovConfigurationPolicy: + desiredState: + deviceType: vfio-pci + mtu: 9000 + numVfs: 0 + port: "" + spoofCheck: "on" + trust: "off" + dnsServers: [] + domainName: localdomain + networks: + - isControlPlane: true + mtu: 1500 + name: Control + nameLower: ctlplane + subnets: + - attachConfiguration: br-osp + ipv4: + allocationEnd: 192.168.25.250 + allocationStart: 192.168.25.100 + cidr: 192.168.25.0/24 + gateway: 192.168.25.1 + routes: [] + ipv6: + allocationEnd: "" + allocationStart: "" + cidr: "" + gateway: "" + routes: [] + name: ctlplane + vlan: 0 + vip: true + ovnBridgeMacMappings: + physNetworks: + - macPrefix: fa:16:3a + name: datacentre + preserveReservations: true + reservations: + controller-0: + ipReservations: {} + macReservations: + datacentre: fa:16:3a:aa:aa:aa + controller-1: + ipReservations: {} + macReservations: + datacentre: fa:16:3a:aa:aa:bb + controller-2: + ipReservations: {} + macReservations: + datacentre: fa:16:3a:aa:aa:cc + controlplane: + ipReservations: + ctlplane: 192.168.25.10 + macReservations: {} + openstackclient-0: + ipReservations: + ctlplane: 192.168.25.251 + macReservations: {} +status: + hosts: + controller-2: + ipaddresses: + ctlplane: 192.168.25.102/24 + ovnBridgeMacAdresses: + datacentre: fa:16:3a:aa:aa:cc + controlplane: + ipaddresses: + ctlplane: 192.168.25.10/24 + ovnBridgeMacAdresses: {} + openstackclient-0: + ipaddresses: + ctlplane: 192.168.25.251/24 + ovnBridgeMacAdresses: {} + provisioningStatus: + attachDesiredCount: 1 + attachReadyCount: 1 + netDesiredCount: 1 + netReadyCount: 1 + physNetDesiredCount: 1 + physNetReadyCount: 1 + reason: OpenStackNetConfig openstacknetconfig all resources configured + state: Configured +--- apiVersion: osp-director.openstack.org/v1beta1 kind: OpenStackControlPlane metadata: @@ -51,7 +161,7 @@ status: hostRef: controlplane hostname: controlplane ipaddresses: - ctlplane: 192.168.25.100/24 + ctlplane: 192.168.25.10/24 provisioningState: Provisioned --- apiVersion: osp-director.openstack.org/v1beta1 @@ -89,7 +199,7 @@ status: hostRef: controller-2 hostname: controller-2 ipaddresses: - ctlplane: 192.168.25.104/24 + ctlplane: 192.168.25.102/24 networkDataSecretName: controller-controller-2-networkdata provisioningState: Provisioned userDataSecretName: controller-cloudinit @@ -117,7 +227,7 @@ status: hostRef: openstackclient-0 hostname: openstackclient-0 ipaddresses: - ctlplane: 192.168.25.101/24 + ctlplane: 192.168.25.251/24 provisioningState: Provisioned --- apiVersion: osp-director.openstack.org/v1beta1 @@ -151,29 +261,29 @@ spec: reservations: - deleted: false hostname: controlplane - ip: 192.168.25.100 + ip: 192.168.25.10 vip: true Controller: addToPredictableIPs: true reservations: - deleted: true hostname: controller-0 - ip: 192.168.25.102 + ip: 192.168.25.100 vip: false - deleted: true hostname: controller-1 - ip: 192.168.25.103 + ip: 192.168.25.101 vip: false - deleted: false hostname: controller-2 - ip: 192.168.25.104 + ip: 192.168.25.102 vip: false OpenstackClientopenstackclient: addToPredictableIPs: false reservations: - deleted: false hostname: openstackclient-0 - ip: 192.168.25.101 + ip: 192.168.25.251 vip: false routes: [] vip: true @@ -183,19 +293,19 @@ status: reservations: controller-0: deleted: true - ip: 192.168.25.102 + ip: 192.168.25.100 controller-1: deleted: true - ip: 192.168.25.103 + ip: 192.168.25.101 controller-2: deleted: false - ip: 192.168.25.104 + ip: 192.168.25.102 controlplane: deleted: false - ip: 192.168.25.100 + ip: 192.168.25.10 openstackclient-0: deleted: false - ip: 192.168.25.101 + ip: 192.168.25.251 reservedIpCount: 5 --- apiVersion: v1 diff --git a/tests/kuttl/tests/ovnBridgeMacMappings/08-assert.yaml b/tests/kuttl/tests/ovnBridgeMacMappings/08-assert.yaml index 183083f9..839865f3 100644 --- a/tests/kuttl/tests/ovnBridgeMacMappings/08-assert.yaml +++ b/tests/kuttl/tests/ovnBridgeMacMappings/08-assert.yaml @@ -9,6 +9,116 @@ # - 1 OpenStackMACAddress # +apiVersion: osp-director.openstack.org/v1beta1 +kind: OpenStackNetConfig +metadata: + finalizers: + - openstacknetconfig.osp-director.openstack.org + name: openstacknetconfig + namespace: openstack +spec: +spec: + attachConfigurations: + br-osp: + nodeNetworkConfigurationPolicy: + desiredState: + interfaces: + - bridge: + options: + stp: + enabled: false + port: + - name: enp7s0 + description: Linux bridge with enp7s0 as a port + mtu: 1500 + name: br-osp + state: up + type: linux-bridge + nodeSelector: + node-role.kubernetes.io/worker: "" + nodeSriovConfigurationPolicy: + desiredState: + deviceType: vfio-pci + mtu: 9000 + numVfs: 0 + port: "" + spoofCheck: "on" + trust: "off" + dnsServers: [] + domainName: localdomain + networks: + - isControlPlane: true + mtu: 1500 + name: Control + nameLower: ctlplane + subnets: + - attachConfiguration: br-osp + ipv4: + allocationEnd: 192.168.25.250 + allocationStart: 192.168.25.100 + cidr: 192.168.25.0/24 + gateway: 192.168.25.1 + routes: [] + ipv6: + allocationEnd: "" + allocationStart: "" + cidr: "" + gateway: "" + routes: [] + name: ctlplane + vlan: 0 + vip: true + ovnBridgeMacMappings: + physNetworks: + - macPrefix: fa:16:3a + name: datacentre + preserveReservations: false + reservations: + controller-0: + ipReservations: {} + macReservations: + datacentre: fa:16:3a:aa:aa:aa + controller-1: + ipReservations: {} + macReservations: + datacentre: fa:16:3a:aa:aa:bb + controller-2: + ipReservations: {} + macReservations: + datacentre: fa:16:3a:aa:aa:cc + controlplane: + ipReservations: + ctlplane: 192.168.25.10 + macReservations: {} + openstackclient-0: + ipReservations: + ctlplane: 192.168.25.251 + macReservations: {} +status: + hosts: + controller-2: + ipaddresses: + ctlplane: 192.168.25.102/24 + ovnBridgeMacAdresses: + datacentre: fa:16:3a:aa:aa:cc + controlplane: + ipaddresses: + ctlplane: 192.168.25.10/24 + ovnBridgeMacAdresses: {} + openstackclient-0: + ipaddresses: + ctlplane: 192.168.25.251/24 + ovnBridgeMacAdresses: {} + provisioningStatus: + attachDesiredCount: 1 + attachReadyCount: 1 + netDesiredCount: 1 + netReadyCount: 1 + physNetDesiredCount: 1 + physNetReadyCount: 1 + reason: OpenStackNetConfig openstacknetconfig all resources configured + state: Configured +--- apiVersion: osp-director.openstack.org/v1beta1 kind: OpenStackControlPlane metadata: @@ -51,7 +161,7 @@ status: hostRef: controlplane hostname: controlplane ipaddresses: - ctlplane: 192.168.25.100/24 + ctlplane: 192.168.25.10/24 provisioningState: Provisioned --- apiVersion: osp-director.openstack.org/v1beta1 @@ -89,7 +199,7 @@ status: hostRef: controller-2 hostname: controller-2 ipaddresses: - ctlplane: 192.168.25.104/24 + ctlplane: 192.168.25.102/24 networkDataSecretName: controller-controller-2-networkdata provisioningState: Provisioned userDataSecretName: controller-cloudinit @@ -117,7 +227,7 @@ status: hostRef: openstackclient-0 hostname: openstackclient-0 ipaddresses: - ctlplane: 192.168.25.101/24 + ctlplane: 192.168.25.251/24 provisioningState: Provisioned --- apiVersion: osp-director.openstack.org/v1beta1 @@ -151,21 +261,21 @@ spec: reservations: - deleted: false hostname: controlplane - ip: 192.168.25.100 + ip: 192.168.25.10 vip: true Controller: addToPredictableIPs: true reservations: - deleted: false hostname: controller-2 - ip: 192.168.25.104 + ip: 192.168.25.102 vip: false OpenstackClientopenstackclient: addToPredictableIPs: false reservations: - deleted: false hostname: openstackclient-0 - ip: 192.168.25.101 + ip: 192.168.25.251 vip: false routes: [] vip: true @@ -175,13 +285,13 @@ status: reservations: controller-2: deleted: false - ip: 192.168.25.104 + ip: 192.168.25.102 controlplane: deleted: false - ip: 192.168.25.100 + ip: 192.168.25.10 openstackclient-0: deleted: false - ip: 192.168.25.101 + ip: 192.168.25.251 reservedIpCount: 3 --- apiVersion: v1 diff --git a/tests/kuttl/tests/ovnBridgeMacMappings/09-assert.yaml b/tests/kuttl/tests/ovnBridgeMacMappings/09-assert.yaml index 76c310e5..ff63393f 100644 --- a/tests/kuttl/tests/ovnBridgeMacMappings/09-assert.yaml +++ b/tests/kuttl/tests/ovnBridgeMacMappings/09-assert.yaml @@ -13,7 +13,6 @@ metadata: - openstacknetconfig.osp-director.openstack.org name: openstacknetconfig namespace: openstack -spec: spec: attachConfigurations: br-osp: @@ -71,20 +70,28 @@ spec: name: datacentre - macPrefix: fa:16:3b name: datacentre2 - staticReservations: - controller-0: - deleted: false - reservations: - datacentre: fa:16:3a:aa:aa:aa - controller-1: - deleted: false - reservations: - datacentre: fa:16:3a:aa:aa:bb - controller-2: - deleted: false - reservations: - datacentre: fa:16:3a:aa:aa:cc preserveReservations: false + reservations: + controller-0: + ipReservations: {} + macReservations: + datacentre: fa:16:3a:aa:aa:aa + controller-1: + ipReservations: {} + macReservations: + datacentre: fa:16:3a:aa:aa:bb + controller-2: + ipReservations: {} + macReservations: + datacentre: fa:16:3a:aa:aa:cc + controlplane: + ipReservations: + ctlplane: 192.168.25.10 + macReservations: {} + openstackclient-0: + ipReservations: + ctlplane: 192.168.25.251 + macReservations: {} status: provisioningStatus: attachDesiredCount: 1 diff --git a/tests/kuttl/tests/unique_role_name/03-assert.yaml b/tests/kuttl/tests/unique_role_name/03-assert.yaml index b4981f2c..98c2ae99 100644 --- a/tests/kuttl/tests/unique_role_name/03-assert.yaml +++ b/tests/kuttl/tests/unique_role_name/03-assert.yaml @@ -36,5 +36,5 @@ status: hostRef: somecustomrole-0 hostname: somecustomrole-0 ipaddresses: - ctlplane: 192.168.25.102/24 + ctlplane: 192.168.25.100/24 provisioningState: Provisioned