Skip to content

Commit 4137610

Browse files
Merge pull request #1059 from bshephar/ansibleee-refactor
Ansibleee refactor
2 parents cbcb33f + 9480ff4 commit 4137610

File tree

2 files changed

+237
-157
lines changed

2 files changed

+237
-157
lines changed

pkg/dataplane/util/ansible_execution.go

Lines changed: 202 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,6 @@ func AnsibleExecution(
4949
nodeSet client.Object,
5050
) error {
5151
var err error
52-
var cmdLineArguments strings.Builder
53-
var inventoryVolume corev1.Volume
54-
var inventoryName string
55-
var inventoryMountPath string
56-
var sshKeyName string
57-
var sshKeyMountPath string
58-
var sshKeyMountSubPath string
59-
60-
const jobRestartPolicy string = "OnFailure"
61-
62-
ansibleEEMounts := storage.VolMounts{}
6352

6453
executionName, labels := GetAnsibleExecutionNameAndLabels(service, deployment.GetName(), nodeSet.GetName())
6554

@@ -85,151 +74,11 @@ func AnsibleExecution(
8574
return fmt.Errorf("failed to create NetworkAttachment annotation. Error: %w", err)
8675
}
8776

88-
if aeeSpec.DNSConfig != nil {
89-
ansibleEE.DNSConfig = aeeSpec.DNSConfig
90-
}
91-
if len(aeeSpec.OpenStackAnsibleEERunnerImage) > 0 {
92-
ansibleEE.Image = aeeSpec.OpenStackAnsibleEERunnerImage
93-
} else {
94-
ansibleEE.Image = *dataplanev1.ContainerImageDefaults.AnsibleeeImage
95-
}
96-
if len(aeeSpec.ExtraVars) > 0 {
97-
ansibleEE.ExtraVars = aeeSpec.ExtraVars
98-
}
99-
if len(aeeSpec.AnsibleTags) > 0 {
100-
fmt.Fprintf(&cmdLineArguments, "--tags %s ", aeeSpec.AnsibleTags)
101-
}
102-
if len(aeeSpec.AnsibleLimit) > 0 {
103-
fmt.Fprintf(&cmdLineArguments, "--limit %s ", aeeSpec.AnsibleLimit)
104-
}
105-
if len(aeeSpec.AnsibleSkipTags) > 0 {
106-
fmt.Fprintf(&cmdLineArguments, "--skip-tags %s ", aeeSpec.AnsibleSkipTags)
107-
}
108-
if len(aeeSpec.ServiceAccountName) > 0 {
109-
ansibleEE.ServiceAccountName = aeeSpec.ServiceAccountName
110-
}
111-
if cmdLineArguments.Len() > 0 {
112-
ansibleEE.CmdLine = strings.TrimSpace(cmdLineArguments.String())
113-
}
114-
115-
if len(service.Spec.PlaybookContents) > 0 {
116-
ansibleEE.PlaybookContents = service.Spec.PlaybookContents
117-
}
118-
if len(service.Spec.Playbook) > 0 {
119-
ansibleEE.Playbook = service.Spec.Playbook
120-
}
121-
ansibleEE.BackoffLimit = deployment.Spec.BackoffLimit
122-
ansibleEE.RestartPolicy = jobRestartPolicy
123-
124-
// If we have a service that ought to be deployed everywhere
125-
// substitute the existing play target with 'all'
126-
// Check if we have ExtraVars before accessing it
127-
if ansibleEE.ExtraVars == nil {
128-
ansibleEE.ExtraVars = make(map[string]json.RawMessage)
129-
}
130-
if service.Spec.DeployOnAllNodeSets {
131-
ansibleEE.ExtraVars["edpm_override_hosts"] = json.RawMessage([]byte("\"all\""))
132-
} else {
133-
ansibleEE.ExtraVars["edpm_override_hosts"] = json.RawMessage([]byte(fmt.Sprintf("\"%s\"", nodeSet.GetName())))
134-
}
135-
if service.Spec.EDPMServiceType != "" {
136-
ansibleEE.ExtraVars["edpm_service_type"] = json.RawMessage([]byte(fmt.Sprintf("\"%s\"", service.Spec.EDPMServiceType)))
137-
} else {
138-
ansibleEE.ExtraVars["edpm_service_type"] = json.RawMessage([]byte(fmt.Sprintf("\"%s\"", service.Name)))
139-
}
140-
141-
if len(deployment.Spec.ServicesOverride) > 0 {
142-
ansibleEE.ExtraVars["edpm_services_override"] = json.RawMessage([]byte(fmt.Sprintf("\"%s\"", deployment.Spec.ServicesOverride)))
143-
}
144-
145-
// Sort keys of the ssh secret map
146-
sshKeys := make([]string, 0)
147-
for k := range sshKeySecrets {
148-
sshKeys = append(sshKeys, k)
149-
}
150-
sort.Strings(sshKeys)
151-
152-
for _, sshKeyNodeName := range sshKeys {
153-
sshKeySecret := sshKeySecrets[sshKeyNodeName]
154-
if service.Spec.DeployOnAllNodeSets {
155-
sshKeyName = fmt.Sprintf("ssh-key-%s", sshKeyNodeName)
156-
sshKeyMountSubPath = fmt.Sprintf("ssh_key_%s", sshKeyNodeName)
157-
sshKeyMountPath = fmt.Sprintf("/runner/env/ssh_key/%s", sshKeyMountSubPath)
158-
} else {
159-
if sshKeyNodeName != nodeSet.GetName() {
160-
continue
161-
}
162-
sshKeyName = "ssh-key"
163-
sshKeyMountSubPath = "ssh_key"
164-
sshKeyMountPath = "/runner/env/ssh_key"
165-
}
166-
sshKeyVolume := corev1.Volume{
167-
Name: sshKeyName,
168-
VolumeSource: corev1.VolumeSource{
169-
Secret: &corev1.SecretVolumeSource{
170-
SecretName: sshKeySecret,
171-
Items: []corev1.KeyToPath{
172-
{
173-
Key: "ssh-privatekey",
174-
Path: sshKeyMountSubPath,
175-
},
176-
},
177-
},
178-
},
179-
}
180-
sshKeyMount := corev1.VolumeMount{
181-
Name: sshKeyName,
182-
MountPath: sshKeyMountPath,
183-
SubPath: sshKeyMountSubPath,
184-
}
185-
// Mount ssh secrets
186-
ansibleEEMounts.Mounts = append(ansibleEEMounts.Mounts, sshKeyMount)
187-
ansibleEEMounts.Volumes = append(ansibleEEMounts.Volumes, sshKeyVolume)
188-
}
189-
190-
// order the inventory keys otherwise it could lead to changing order and mount order changing
191-
invKeys := make([]string, 0)
192-
for k := range inventorySecrets {
193-
invKeys = append(invKeys, k)
194-
}
195-
sort.Strings(invKeys)
77+
ansibleEE.BuildAeeJobSpec(aeeSpec, deployment, service, nodeSet)
19678

197-
// Mounting inventory and secrets
198-
for inventoryIndex, nodeName := range invKeys {
199-
if service.Spec.DeployOnAllNodeSets {
200-
inventoryName = fmt.Sprintf("inventory-%d", inventoryIndex)
201-
inventoryMountPath = fmt.Sprintf("/runner/inventory/%s", inventoryName)
202-
} else {
203-
if nodeName != nodeSet.GetName() {
204-
continue
205-
}
206-
inventoryName = "inventory"
207-
inventoryMountPath = "/runner/inventory/hosts"
208-
}
209-
210-
inventoryVolume = corev1.Volume{
211-
Name: inventoryName,
212-
VolumeSource: corev1.VolumeSource{
213-
Secret: &corev1.SecretVolumeSource{
214-
SecretName: inventorySecrets[nodeName],
215-
Items: []corev1.KeyToPath{
216-
{
217-
Key: "inventory",
218-
Path: inventoryName,
219-
},
220-
},
221-
},
222-
},
223-
}
224-
inventoryMount := corev1.VolumeMount{
225-
Name: inventoryName,
226-
MountPath: inventoryMountPath,
227-
SubPath: inventoryName,
228-
}
229-
// Inventory mount
230-
ansibleEEMounts.Mounts = append(ansibleEEMounts.Mounts, inventoryMount)
231-
ansibleEEMounts.Volumes = append(ansibleEEMounts.Volumes, inventoryVolume)
232-
}
79+
ansibleEEMounts := storage.VolMounts{}
80+
SetAeeSSHMounts(nodeSet, service, sshKeySecrets, &ansibleEEMounts)
81+
SetAeeInvMounts(nodeSet, service, inventorySecrets, &ansibleEEMounts)
23382

23483
ansibleEE.ExtraMounts = append(aeeSpec.ExtraMounts, []storage.VolMounts{ansibleEEMounts}...)
23584
ansibleEE.Env = aeeSpec.Env
@@ -260,7 +109,8 @@ func AnsibleExecution(
260109
// "openstackdataplanenodeset": <nodeSetName>,
261110
// If none or more than one is found, return nil and error
262111
func GetAnsibleExecution(ctx context.Context,
263-
helper *helper.Helper, obj client.Object, labelSelector map[string]string) (*batchv1.Job, error) {
112+
helper *helper.Helper, obj client.Object, labelSelector map[string]string,
113+
) (*batchv1.Job, error) {
264114
var err error
265115
ansibleEEs := &batchv1.JobList{}
266116

@@ -303,7 +153,8 @@ func getAnsibleExecutionNamePrefix(serviceName string) string {
303153
// GetAnsibleExecutionNameAndLabels Name and Labels of AnsibleEE
304154
func GetAnsibleExecutionNameAndLabels(service *dataplanev1.OpenStackDataPlaneService,
305155
deploymentName string,
306-
nodeSetName string) (string, map[string]string) {
156+
nodeSetName string,
157+
) (string, map[string]string) {
307158
executionName := fmt.Sprintf("%s-%s", getAnsibleExecutionNamePrefix(service.Name), deploymentName)
308159
if !service.Spec.DeployOnAllNodeSets {
309160
executionName = fmt.Sprintf("%s-%s", executionName, nodeSetName)
@@ -320,3 +171,197 @@ func GetAnsibleExecutionNameAndLabels(service *dataplanev1.OpenStackDataPlaneSer
320171
}
321172
return executionName, labels
322173
}
174+
175+
func (a *EEJob) BuildAeeJobSpec(
176+
aeeSpec *dataplanev1.AnsibleEESpec,
177+
deployment *dataplanev1.OpenStackDataPlaneDeployment,
178+
service *dataplanev1.OpenStackDataPlaneService,
179+
nodeSet client.Object,
180+
) {
181+
const jobRestartPolicy string = "OnFailure"
182+
183+
if aeeSpec.DNSConfig != nil {
184+
a.DNSConfig = aeeSpec.DNSConfig
185+
}
186+
if len(aeeSpec.ServiceAccountName) > 0 {
187+
a.ServiceAccountName = aeeSpec.ServiceAccountName
188+
}
189+
190+
if len(service.Spec.PlaybookContents) > 0 {
191+
a.PlaybookContents = service.Spec.PlaybookContents
192+
}
193+
if len(service.Spec.Playbook) > 0 {
194+
a.Playbook = service.Spec.Playbook
195+
}
196+
197+
a.BackoffLimit = deployment.Spec.BackoffLimit
198+
a.RestartPolicy = jobRestartPolicy
199+
a.FormatAEECmdLineArguments(aeeSpec)
200+
a.FormatAEEExtraVars(aeeSpec, service, deployment, nodeSet)
201+
a.DetermineAeeImage(aeeSpec)
202+
}
203+
204+
func (a *EEJob) FormatAEECmdLineArguments(aeeSpec *dataplanev1.AnsibleEESpec) {
205+
var cmdLineArguments strings.Builder
206+
207+
if len(aeeSpec.AnsibleTags) > 0 {
208+
fmt.Fprintf(&cmdLineArguments, "--tags %s ", aeeSpec.AnsibleTags)
209+
}
210+
if len(aeeSpec.AnsibleLimit) > 0 {
211+
fmt.Fprintf(&cmdLineArguments, "--limit %s ", aeeSpec.AnsibleLimit)
212+
}
213+
if len(aeeSpec.AnsibleSkipTags) > 0 {
214+
fmt.Fprintf(&cmdLineArguments, "--skip-tags %s ", aeeSpec.AnsibleSkipTags)
215+
}
216+
217+
if cmdLineArguments.Len() > 0 {
218+
a.CmdLine = strings.TrimSpace(cmdLineArguments.String())
219+
}
220+
}
221+
222+
func (a *EEJob) FormatAEEExtraVars(
223+
aeeSpec *dataplanev1.AnsibleEESpec,
224+
service *dataplanev1.OpenStackDataPlaneService,
225+
deployment *dataplanev1.OpenStackDataPlaneDeployment,
226+
nodeSet client.Object,
227+
) {
228+
if len(aeeSpec.ExtraVars) > 0 {
229+
a.ExtraVars = aeeSpec.ExtraVars
230+
}
231+
232+
// If we have a service that ought to be deployed everywhere
233+
// substitute the existing play target with 'all'
234+
// Check if we have ExtraVars before accessing it
235+
if a.ExtraVars == nil {
236+
a.ExtraVars = make(map[string]json.RawMessage)
237+
}
238+
if service.Spec.DeployOnAllNodeSets {
239+
a.ExtraVars["edpm_override_hosts"] = json.RawMessage([]byte("\"all\""))
240+
} else {
241+
a.ExtraVars["edpm_override_hosts"] = json.RawMessage([]byte(fmt.Sprintf("\"%s\"", nodeSet.GetName())))
242+
}
243+
if service.Spec.EDPMServiceType != "" {
244+
a.ExtraVars["edpm_service_type"] = json.RawMessage([]byte(fmt.Sprintf("\"%s\"", service.Spec.EDPMServiceType)))
245+
} else {
246+
a.ExtraVars["edpm_service_type"] = json.RawMessage([]byte(fmt.Sprintf("\"%s\"", service.Name)))
247+
}
248+
249+
if len(deployment.Spec.ServicesOverride) > 0 {
250+
a.ExtraVars["edpm_services_override"] = json.RawMessage([]byte(fmt.Sprintf("\"%s\"", deployment.Spec.ServicesOverride)))
251+
}
252+
}
253+
254+
func (a *EEJob) DetermineAeeImage(aeeSpec *dataplanev1.AnsibleEESpec) {
255+
if len(aeeSpec.OpenStackAnsibleEERunnerImage) > 0 {
256+
a.Image = aeeSpec.OpenStackAnsibleEERunnerImage
257+
} else {
258+
a.Image = *dataplanev1.ContainerImageDefaults.AnsibleeeImage
259+
}
260+
}
261+
262+
// SetAeeSshMounts - Using the information provided from the NodeSet, Service and AnsibleEE Spec. We determine the required
263+
// ssh key mounts that are required for the Ansible Execution Job. This function takes a pointer to the storage.VolMounts
264+
// struct and updates them as per the required ssh key related mounts.
265+
func SetAeeSSHMounts(
266+
nodeSet client.Object,
267+
service *dataplanev1.OpenStackDataPlaneService,
268+
sshKeySecrets map[string]string,
269+
ansibleEEMounts *storage.VolMounts,
270+
) {
271+
var (
272+
sshKeyName string
273+
sshKeyMountPath string
274+
sshKeyMountSubPath string
275+
)
276+
277+
// Sort keys of the ssh secret map
278+
sshKeys := make([]string, 0)
279+
for k := range sshKeySecrets {
280+
sshKeys = append(sshKeys, k)
281+
}
282+
sort.Strings(sshKeys)
283+
284+
for _, sshKeyNodeName := range sshKeys {
285+
sshKeySecret := sshKeySecrets[sshKeyNodeName]
286+
if service.Spec.DeployOnAllNodeSets {
287+
sshKeyName = fmt.Sprintf("ssh-key-%s", sshKeyNodeName)
288+
sshKeyMountSubPath = fmt.Sprintf("ssh_key_%s", sshKeyNodeName)
289+
sshKeyMountPath = fmt.Sprintf("/runner/env/ssh_key/%s", sshKeyMountSubPath)
290+
} else {
291+
if sshKeyNodeName != nodeSet.GetName() {
292+
continue
293+
}
294+
sshKeyName = "ssh-key"
295+
sshKeyMountSubPath = "ssh_key"
296+
sshKeyMountPath = "/runner/env/ssh_key"
297+
}
298+
299+
CreateVolume(ansibleEEMounts, sshKeyName, sshKeyMountSubPath, sshKeySecret, "ssh-privatekey")
300+
CreateVolumeMount(ansibleEEMounts, sshKeyName, sshKeyMountPath, sshKeyMountSubPath)
301+
}
302+
}
303+
304+
func SetAeeInvMounts(
305+
nodeSet client.Object,
306+
service *dataplanev1.OpenStackDataPlaneService,
307+
inventorySecrets map[string]string,
308+
ansibleEEMounts *storage.VolMounts,
309+
) {
310+
var (
311+
inventoryName string
312+
inventoryMountPath string
313+
)
314+
315+
// order the inventory keys otherwise it could lead to changing order and mount order changing
316+
invKeys := make([]string, 0)
317+
for k := range inventorySecrets {
318+
invKeys = append(invKeys, k)
319+
}
320+
sort.Strings(invKeys)
321+
322+
// Mounting inventory and secrets
323+
for inventoryIndex, nodeName := range invKeys {
324+
if service.Spec.DeployOnAllNodeSets {
325+
inventoryName = fmt.Sprintf("inventory-%d", inventoryIndex)
326+
inventoryMountPath = fmt.Sprintf("/runner/inventory/%s", inventoryName)
327+
} else {
328+
if nodeName != nodeSet.GetName() {
329+
continue
330+
}
331+
inventoryName = "inventory"
332+
inventoryMountPath = "/runner/inventory/hosts"
333+
}
334+
335+
CreateVolume(ansibleEEMounts, inventoryName, inventoryName, inventorySecrets[nodeName], "inventory")
336+
CreateVolumeMount(ansibleEEMounts, inventoryName, inventoryMountPath, inventoryName)
337+
}
338+
}
339+
340+
func CreateVolume(ansibleEEMounts *storage.VolMounts, volumeName string, volumeMountPath string, secretName string, keyToPathKey string) {
341+
volume := corev1.Volume{
342+
Name: volumeName,
343+
VolumeSource: corev1.VolumeSource{
344+
Secret: &corev1.SecretVolumeSource{
345+
SecretName: secretName,
346+
Items: []corev1.KeyToPath{
347+
{
348+
Key: keyToPathKey,
349+
Path: volumeMountPath,
350+
},
351+
},
352+
},
353+
},
354+
}
355+
356+
ansibleEEMounts.Volumes = append(ansibleEEMounts.Volumes, volume)
357+
}
358+
359+
func CreateVolumeMount(ansibleEEMounts *storage.VolMounts, volumeMountName string, volumeMountPath string, volumeMountSubPath string) {
360+
volumeMount := corev1.VolumeMount{
361+
Name: volumeMountName,
362+
MountPath: volumeMountPath,
363+
SubPath: volumeMountSubPath,
364+
}
365+
366+
ansibleEEMounts.Mounts = append(ansibleEEMounts.Mounts, volumeMount)
367+
}

0 commit comments

Comments
 (0)