Reputation: 503
We are trying to update the image: field in Kubernetes YAML manifests by dynamically appending an IP address (10.20.30.40/
) to the image URL, except in certain cases. Specifically, we have three scenarios to consider:
Scenario 1: Image starting with an IP address
Condition: If the image: field starts with an IP address (e.g., 10.20.30.40/
), we do not modify it.
Example:
image: 10.20.30.40/ml-pipeline/argoexec:v3.4.16-license-compliance
Scenario 2: Image not starting with an IP address
Condition: If the image: field does not start with an IP address, we append the Oxy IP (10.20.30.40/) to the image URL. Example:
image: ml-pipeline/workflow-controller:v3.4.16-license-compliance
After modification:
image: 10.20.30.40/ml-pipeline/workflow-controller:v3.4.16-license-compliance
Scenario 3: Image with Ansible variable
Condition: If the image: field contains an Ansible variable (e.g., {{ ... }}
), it should stay as it is because the image URL is dynamically calculated based on the variable.
Example:
image: "{{ .ProxyImage }}"
This should not be modified by appending IP.
All three samples in this YAML
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
internal.kpt.dev/upstream-identifier: apps|Deployment|default|workflow-controller
labels:
application-crd-id: kubeflow-pipelines
name: workflow-controller
namespace: kubeflow
spec:
selector:
matchLabels:
app: workflow-controller
application-crd-id: kubeflow-pipelines
template:
metadata:
labels:
app: workflow-controller
application-crd-id: kubeflow-pipelines
spec:
containers:
- args:
- --configmap
- workflow-controller-configmap
- --executor-image
- 10.20.30.40/ml-pipeline/argoexec:v3.4.16-license-compliance # Scenario 1 (No change)
command:
- workflow-controller
image: ml-pipeline/workflow-controller:v3.4.16-license-compliance # Scenario 2 (Should be modified)
name: workflow-controller
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
app: metacontroller
application-crd-id: kubeflow-pipelines
kustomize.component: metacontroller
name: metacontroller
namespace: kubeflow
spec:
replicas: 1
selector:
matchLabels:
app: metacontroller
application-crd-id: kubeflow-pipelines
kustomize.component: metacontroller
serviceName: ""
template:
metadata:
annotations:
sidecar.istio.io/inject: "false"
labels:
app: metacontroller
application-crd-id: kubeflow-pipelines
kustomize.component: metacontroller
spec:
containers:
- command:
- /usr/bin/metacontroller
image: "{{ .ProxyImage }}" # Scenario 3 (No change)
name: metacontroller
The Ansible code I am trying and its not able to fix for 3rd scenario
---
- name: Prepend Oxy IP to images without special characters or Jinja2 templates
hosts: localhost
become: true
vars:
kubeflow_dir_path: "/home/manifest" # Define the manifest directory
oxy_ip: "10.20.30.40" # Define the Oxy server IP
tasks:
- name: Find YAML files in the manifest directory
ansible.builtin.find:
paths: "{{ kubeflow_dir_path }}"
patterns: "*.yaml"
recurse: yes
register: yaml_files
- name: Prepend Oxy IP to images that don't start with a string in quotes (excluding Jinja2 logic)
ansible.builtin.shell: |
find "{{ kubeflow_dir_path }}" -type f \( -name "*.yaml" -o -name "*.yml" \) -exec \
sed -i '/^\s*image:/ { /^[{].*image:/! s/\(image:\s\)\([a-zA-Z0-9._-]*\/\)\?\([^\/]*\)/\1{{ oxy_ip }}\/\3/ } }' {} +
register: replace_output
- name: Display the list of files that were modified
ansible.builtin.debug:
var: replace_output.stdout
Upvotes: 0
Views: 60
Reputation: 12124
The following minimal example would just work on the provided cases
m1.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
internal.kpt.dev/upstream-identifier: apps|Deployment|default|workflow-controller
labels:
application-crd-id: kubeflow-pipelines
name: workflow-controller
namespace: kubeflow
spec:
selector:
matchLabels:
app: workflow-controller
application-crd-id: kubeflow-pipelines
template:
metadata:
labels:
app: workflow-controller
application-crd-id: kubeflow-pipelines
spec:
containers:
- args:
- --configmap
- workflow-controller-configmap
- --executor-image
- 192.0.2.254/ml-pipeline/argoexec:v3.4.16-license-compliancie
command:
- workflow-controller
image: ml-pipeline/workflow-controller:v3.4.16-license-compliance
name: workflow-controller
m2.yaml
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
app: metacontroller
application-crd-id: kubeflow-pipelines
kustomize.component: metacontroller
name: metacontroller
namespace: kubeflow
spec:
replicas: 1
selector:
matchLabels:
app: metacontroller
application-crd-id: kubeflow-pipelines
kustomize.component: metacontroller
serviceName: ""
template:
metadata:
annotations:
sidecar.istio.io/inject: "false"
labels:
app: metacontroller
application-crd-id: kubeflow-pipelines
kustomize.component: metacontroller
spec:
containers:
- command:
- /usr/bin/metacontroller
image: "{{ .ProxyImage }}"
name: metacontroller
oxy.yml
---
- name: Prepend Oxy IP to images without special characters or Jinja2 templates
hosts: localhost
become: false
gather_facts: false
vars:
oxy_ip: "192.0.2.1"
strYML: "{{ lookup('file', 'm1.yaml') }}"
tasks:
- name: Show from AnsibleUnsafeText
debug:
msg: "{{ strYML | from_yaml }}"
- debug:
msg: "{{ oxy_ip}}/{{ image }}"
when:
- not image is search('ProxyImage')
- not image is search(oxy_ip)
vars:
image: "{{ ((strYML | from_yaml).spec.template.spec.containers | first).image }}"
will result into an output of
TASK [debug] **************************************************************
ok: [localhost] =>
msg: 192.0.2.1/ml-pipeline/workflow-controller:v3.4.16-license-compliance
But one need to adopt the approach. Depending on what should be achieved there would be a lot of corner cases to cover, as well error handling necessary.
Upvotes: 0