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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
197 changes: 197 additions & 0 deletions apis/bases/core.openstack.org_openstackversions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,203 @@ spec:
glanceWsgi:
type: string
type: object
trackedCustomImages:
additionalProperties:
properties:
agentImage:
type: string
ansibleeeImage:
type: string
aodhAPIImage:
type: string
aodhEvaluatorImage:
type: string
aodhListenerImage:
type: string
aodhNotifierImage:
type: string
apacheImage:
type: string
barbicanAPIImage:
type: string
barbicanKeystoneListenerImage:
type: string
barbicanWorkerImage:
type: string
ceilometerCentralImage:
type: string
ceilometerComputeImage:
type: string
ceilometerIpmiImage:
type: string
ceilometerMysqldExporterImage:
type: string
ceilometerNotificationImage:
type: string
ceilometerSgcoreImage:
type: string
cinderAPIImage:
type: string
cinderBackupImage:
type: string
cinderSchedulerImage:
type: string
cinderVolumeImages:
additionalProperties:
type: string
type: object
designateAPIImage:
type: string
designateBackendbind9Image:
type: string
designateCentralImage:
type: string
designateMdnsImage:
type: string
designateProducerImage:
type: string
designateUnboundImage:
type: string
designateWorkerImage:
type: string
edpmFrrImage:
type: string
edpmIscsidImage:
type: string
edpmKeplerImage:
type: string
edpmLogrotateCrondImage:
type: string
edpmMultipathdImage:
type: string
edpmNeutronDhcpAgentImage:
type: string
edpmNeutronMetadataAgentImage:
type: string
edpmNeutronOvnAgentImage:
type: string
edpmNeutronSriovAgentImage:
type: string
edpmNodeExporterImage:
type: string
edpmOpenstackNetworkExporterImage:
type: string
edpmOvnBgpAgentImage:
type: string
edpmPodmanExporterImage:
type: string
glanceAPIImage:
type: string
heatAPIImage:
type: string
heatCfnapiImage:
type: string
heatEngineImage:
type: string
horizonImage:
type: string
infraDnsmasqImage:
type: string
infraMemcachedImage:
type: string
infraRedisImage:
type: string
ironicAPIImage:
type: string
ironicConductorImage:
type: string
ironicInspectorImage:
type: string
ironicNeutronAgentImage:
type: string
ironicPxeImage:
type: string
ironicPythonAgentImage:
type: string
keystoneAPIImage:
type: string
ksmImage:
type: string
manilaAPIImage:
type: string
manilaSchedulerImage:
type: string
manilaShareImages:
additionalProperties:
type: string
type: object
mariadbImage:
type: string
netUtilsImage:
type: string
neutronAPIImage:
type: string
novaAPIImage:
type: string
novaComputeImage:
type: string
novaConductorImage:
type: string
novaNovncImage:
type: string
novaSchedulerImage:
type: string
octaviaAPIImage:
type: string
octaviaHealthmanagerImage:
type: string
octaviaHousekeepingImage:
type: string
octaviaRsyslogImage:
type: string
octaviaWorkerImage:
type: string
openstackClientImage:
type: string
openstackNetworkExporterImage:
type: string
osContainerImage:
type: string
ovnControllerImage:
type: string
ovnControllerOvsImage:
type: string
ovnNbDbclusterImage:
type: string
ovnNorthdImage:
type: string
ovnSbDbclusterImage:
type: string
placementAPIImage:
type: string
rabbitmqImage:
type: string
swiftAccountImage:
type: string
swiftContainerImage:
type: string
swiftObjectImage:
type: string
swiftProxyImage:
type: string
telemetryNodeExporterImage:
type: string
testAnsibletestImage:
type: string
testHorizontestImage:
type: string
testTempestImage:
type: string
testTobikoImage:
type: string
watcherAPIImage:
type: string
watcherApplierImage:
type: string
watcherDecisionEngineImage:
type: string
type: object
type: object
type: object
type: object
served: true
Expand Down
92 changes: 92 additions & 0 deletions apis/core/v1beta1/openstackversion_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package v1beta1

import (
"context"
"reflect"
"regexp"

condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition"
Expand Down Expand Up @@ -198,6 +199,9 @@ type OpenStackVersionStatus struct {
// ServiceDefaults - struct that contains current defaults for OSP services
ServiceDefaults ServiceDefaults `json:"serviceDefaults,omitempty"`

// TrackedCustomImages tracks CustomContainerImages used for each version to detect changes
TrackedCustomImages map[string]CustomContainerImages `json:"trackedCustomImages,omitempty"`

//ObservedGeneration - the most recent generation observed for this object.
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
}
Expand Down Expand Up @@ -288,3 +292,91 @@ func GetOpenStackVersions(namespace string, k8sClient client.Client) (*OpenStack

return versionList, nil
}

// isContainerTemplateEmpty checks if all fields in a ContainerTemplate are nil
func isContainerTemplateEmpty(ct ContainerTemplate) bool {
v := reflect.ValueOf(ct)
numFields := v.NumField()
for i := 0; i < numFields; i++ {
field := v.Field(i)
// Check if field is a pointer and not nil
if field.Kind() == reflect.Ptr && !field.IsNil() {
return false
}
}
return true
}

// customContainerImagesModified compares two CustomContainerImages and returns true if they are different
func customContainerImagesAllModified(a, b CustomContainerImages) bool {
if !containerTemplateEqual(a.ContainerTemplate, b.ContainerTemplate) {
return true
}

if !stringMapEqual(a.CinderVolumeImages, b.CinderVolumeImages) {
return true
}

if !stringMapEqual(a.ManilaShareImages, b.ManilaShareImages) {
return true
}

// If all fields are equal, return false (not modified)
return false
}

// containerTemplateEqual compares two ContainerTemplate structs for equality using reflection
func containerTemplateEqual(a, b ContainerTemplate) bool {
va := reflect.ValueOf(a)
vb := reflect.ValueOf(b)

numFields := va.NumField()
for i := 0; i < numFields; i++ {
fieldA := va.Field(i)
fieldB := vb.Field(i)

// Both fields should be *string type
if fieldA.Kind() != reflect.Ptr || fieldB.Kind() != reflect.Ptr {
continue
}

if fieldA.IsNil() && fieldB.IsNil() {
continue
}
if fieldA.IsNil() || fieldB.IsNil() {
return false
}
if fieldA.Elem().String() != fieldB.Elem().String() {
return false
}
}

return true
}

// stringPtrEqual compares two string pointers for equality
func stringPtrEqual(a, b *string) bool {
if a == nil && b == nil {
return true
}
if a == nil || b == nil {
return false
}
return *a == *b
}

// stringMapEqual compares two string maps for equality
func stringMapEqual(a, b map[string]*string) bool {
if len(a) != len(b) {
return false
}

for key, valueA := range a {
valueB, exists := b[key]
if !exists || !stringPtrEqual(valueA, valueB) {
return false
}
}

return true
}
Loading