Skip to content

Commit aaa7c55

Browse files
committed
cyborg: Implement CyborgConductor controller reconcile loop
Add full reconcile logic for the CyborgConductor CR: - Validate input from the config secret created by the Cyborg controller - Generate conductor config from templates (00-default.conf) - Create a StatefulSet to run cyborg-conductor pods - Track readiness (ReadyCount, conditions, hash, topology) - Expose IsReady and topology helpers on CyborgConductor type - Update CyborgConductorStatus with structured conditions and hash - Extend Cyborg controller to propagate conductor and check readiness upwards - Add functional tests for the conductor reconcile loop Assisted-By: Claude Signed-off-by: Alfredo Moralejo <amoralej@redhat.com>
1 parent a938ea4 commit aaa7c55

15 files changed

Lines changed: 2060 additions & 68 deletions

api/bases/cyborg.openstack.org_cyborgconductors.yaml

Lines changed: 100 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,16 @@ spec:
1414
singular: cyborgconductor
1515
scope: Namespaced
1616
versions:
17-
- name: v1beta1
17+
- additionalPrinterColumns:
18+
- description: Status
19+
jsonPath: .status.conditions[0].status
20+
name: Status
21+
type: string
22+
- description: Message
23+
jsonPath: .status.conditions[0].message
24+
name: Message
25+
type: string
26+
name: v1beta1
1827
schema:
1928
openAPIV3Schema:
2029
description: CyborgConductor is the Schema for the cyborgconductors API.
@@ -40,8 +49,12 @@ spec:
4049
description: CyborgConductorSpec defines the desired state of CyborgConductor.
4150
properties:
4251
configSecret:
43-
description: ConfigSecret - containing all the configuration needed
44-
provided by Cyborg object
52+
description: |-
53+
Secret is the name of the sub-level secret containing all required data
54+
(transport URL, DB creds, keystone auth, service password, etc.)
55+
type: string
56+
containerImage:
57+
description: ContainerImage is the container image URL for cyborg-conductor
4558
type: string
4659
customServiceConfig:
4760
description: |-
@@ -124,6 +137,17 @@ spec:
124137
More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
125138
type: object
126139
type: object
140+
serviceAccount:
141+
description: ServiceAccount used by the conductor pods
142+
type: string
143+
tls:
144+
description: TLS - Parameters related to the TLS
145+
properties:
146+
caBundleSecretName:
147+
description: CaBundleSecretName - holding the CA certs in a pre-created
148+
bundle file
149+
type: string
150+
type: object
127151
topologyRef:
128152
description: |-
129153
TopologyRef to apply the Topology defined by the associated CR referenced
@@ -143,9 +167,82 @@ spec:
143167
type: object
144168
required:
145169
- configSecret
170+
- containerImage
171+
- serviceAccount
146172
type: object
147173
status:
148174
description: CyborgConductorStatus defines the observed state of CyborgConductor.
175+
properties:
176+
conditions:
177+
description: Conditions
178+
items:
179+
description: Condition defines an observation of a API resource
180+
operational state.
181+
properties:
182+
lastTransitionTime:
183+
description: |-
184+
Last time the condition transitioned from one status to another.
185+
This should be when the underlying condition changed. If that is not known, then using the time when
186+
the API field changed is acceptable.
187+
format: date-time
188+
type: string
189+
message:
190+
description: A human readable message indicating details about
191+
the transition.
192+
type: string
193+
reason:
194+
description: The reason for the condition's last transition
195+
in CamelCase.
196+
type: string
197+
severity:
198+
description: |-
199+
Severity provides a classification of Reason code, so the current situation is immediately
200+
understandable and could act accordingly.
201+
It is meant for situations where Status=False and it should be indicated if it is just
202+
informational, warning (next reconciliation might fix it) or an error (e.g. DB create issue
203+
and no actions to automatically resolve the issue can/should be done).
204+
For conditions where Status=Unknown or Status=True the Severity should be SeverityNone.
205+
type: string
206+
status:
207+
description: Status of the condition, one of True, False, Unknown.
208+
type: string
209+
type:
210+
description: Type of condition in CamelCase.
211+
type: string
212+
required:
213+
- lastTransitionTime
214+
- status
215+
- type
216+
type: object
217+
type: array
218+
hash:
219+
additionalProperties:
220+
type: string
221+
description: Hash - Map of hashes to track config changes
222+
type: object
223+
lastAppliedTopology:
224+
description: LastAppliedTopology - the last applied Topology
225+
properties:
226+
name:
227+
description: Name - The Topology CR name that the Service references
228+
type: string
229+
namespace:
230+
description: |-
231+
Namespace - The Namespace to fetch the Topology CR referenced
232+
NOTE: Namespace currently points by default to the same namespace where
233+
the Service is deployed. Customizing the namespace is not supported and
234+
webhooks prevent editing this field to a value different from the
235+
current project
236+
type: string
237+
type: object
238+
observedGeneration:
239+
description: ObservedGeneration - the most recent generation observed
240+
format: int64
241+
type: integer
242+
readyCount:
243+
description: ReadyCount defines the number of replicas ready
244+
format: int32
245+
type: integer
149246
type: object
150247
type: object
151248
served: true

api/cyborg/v1beta1/conditions.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ const (
5050
// CyborgConductorReadyInitMessage -
5151
CyborgConductorReadyInitMessage = "CyborgConductor not started"
5252

53+
// CyborgConductorReadyErrorMessage -
54+
CyborgConductorReadyErrorMessage = "CyborgConductor error occurred %s"
55+
5356
// CyborgApplicationCredentialSecretErrorMessage -
5457
CyborgApplicationCredentialSecretErrorMessage = "Error with application credential secret"
5558
)

api/cyborg/v1beta1/cyborgconductor_types.go

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,12 @@ package v1beta1
1818

1919
import (
2020
topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1"
21+
"github.com/openstack-k8s-operators/lib-common/modules/common/condition"
22+
"github.com/openstack-k8s-operators/lib-common/modules/common/tls"
2123
corev1 "k8s.io/api/core/v1"
2224
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2325
)
2426

25-
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
26-
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
27-
2827
// CyborgConductorTemplate defines the input parameters specified by the user to
2928
// create a CyborgConductor via higher level CRDs.
3029
type CyborgConductorTemplate struct {
@@ -59,24 +58,49 @@ type CyborgConductorTemplate struct {
5958

6059
// CyborgConductorSpec defines the desired state of CyborgConductor.
6160
type CyborgConductorSpec struct {
62-
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
63-
// Important: Run "make" to regenerate code after modifying this file
64-
6561
CyborgConductorTemplate `json:",inline"`
6662

6763
// +kubebuilder:validation:Required
68-
// ConfigSecret - containing all the configuration needed provided by Cyborg object
64+
// Secret is the name of the sub-level secret containing all required data
65+
// (transport URL, DB creds, keystone auth, service password, etc.)
6966
ConfigSecret string `json:"configSecret"`
67+
68+
// +kubebuilder:validation:Required
69+
// ContainerImage is the container image URL for cyborg-conductor
70+
ContainerImage string `json:"containerImage"`
71+
72+
// +kubebuilder:validation:Required
73+
// ServiceAccount used by the conductor pods
74+
ServiceAccount string `json:"serviceAccount"`
75+
76+
// +kubebuilder:validation:Optional
77+
// +operator-sdk:csv:customresourcedefinitions:type=spec
78+
// TLS - Parameters related to the TLS
79+
TLS tls.Ca `json:"tls,omitempty"`
7080
}
7181

7282
// CyborgConductorStatus defines the observed state of CyborgConductor.
7383
type CyborgConductorStatus struct {
74-
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
75-
// Important: Run "make" to regenerate code after modifying this file
84+
// ReadyCount defines the number of replicas ready
85+
ReadyCount int32 `json:"readyCount,omitempty"`
86+
87+
// Conditions
88+
Conditions condition.Conditions `json:"conditions,omitempty" optional:"true"`
89+
90+
// ObservedGeneration - the most recent generation observed
91+
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
92+
93+
// Hash - Map of hashes to track config changes
94+
Hash map[string]string `json:"hash,omitempty"`
95+
96+
// LastAppliedTopology - the last applied Topology
97+
LastAppliedTopology *topologyv1.TopoRef `json:"lastAppliedTopology,omitempty"`
7698
}
7799

78100
// +kubebuilder:object:root=true
79101
// +kubebuilder:subresource:status
102+
// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[0].status",description="Status"
103+
// +kubebuilder:printcolumn:name="Message",type="string",JSONPath=".status.conditions[0].message",description="Message"
80104

81105
// CyborgConductor is the Schema for the cyborgconductors API.
82106
type CyborgConductor struct {
@@ -96,6 +120,26 @@ type CyborgConductorList struct {
96120
Items []CyborgConductor `json:"items"`
97121
}
98122

123+
// IsReady returns true if the ReadyCondition is true
124+
func (instance *CyborgConductor) IsReady() bool {
125+
return instance.Status.Conditions.IsTrue(condition.ReadyCondition)
126+
}
127+
128+
// GetSpecTopologyRef returns the TopologyRef defined in the Spec
129+
func (instance *CyborgConductor) GetSpecTopologyRef() *topologyv1.TopoRef {
130+
return instance.Spec.TopologyRef
131+
}
132+
133+
// GetLastAppliedTopology returns the LastAppliedTopology from the Status
134+
func (instance *CyborgConductor) GetLastAppliedTopology() *topologyv1.TopoRef {
135+
return instance.Status.LastAppliedTopology
136+
}
137+
138+
// SetLastAppliedTopology sets the LastAppliedTopology value in the Status
139+
func (instance *CyborgConductor) SetLastAppliedTopology(topologyRef *topologyv1.TopoRef) {
140+
instance.Status.LastAppliedTopology = topologyRef
141+
}
142+
99143
func init() {
100144
SchemeBuilder.Register(&CyborgConductor{}, &CyborgConductorList{})
101145
}

api/cyborg/v1beta1/zz_generated.deepcopy.go

Lines changed: 21 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)