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
2 changes: 1 addition & 1 deletion input/telemetry_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ powerscale_configurations:

# Path to the CSM Observability (Karavi Observability) values.yaml file
# Required when powerscale_configurations.powerscale_telemetry_support: true
# Reference: https://raw.githubusercontent.com/dell/helm-charts/refs/heads/release-v1.16.3/charts/karavi-observability/values.yaml
# Reference: https://raw.githubusercontent.com/dell/helm-charts/refs/heads/release-v1.17.1/charts/karavi-observability/values.yaml
csm_observability_values_file_path: ""

# --------------------------------------------------------------------------
Expand Down
9 changes: 7 additions & 2 deletions input_validation/validate_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@
tags:
- always
tasks:
- name: Enable subscription check when validate_config.yml is run directly
ansible.builtin.set_fact:
run_subscription_check: true
when: run_subscription_check is not defined and omnia_run_tags is not defined

- name: Run subscription validation tasks
when: "'local_repo' in (omnia_run_tags | default(ansible_run_tags | default([]) | list)) or 'all' in (ansible_run_tags | default([]) | list)"
block:
Expand Down Expand Up @@ -94,7 +99,7 @@
ansible.builtin.include_role:
name: validate_subscription
tasks_from: check_rhel_subscription.yml
when: "'local_repo' in (hostvars['localhost']['omnia_run_tags'] | default([]))"
when: "hostvars['localhost']['run_subscription_check'] | default(false) | bool"

- name: Configure RHEL repository URLs
hosts: localhost
Expand All @@ -107,7 +112,7 @@
ansible.builtin.include_role:
name: validate_subscription
tasks_from: configure_rhel_os_urls.yml
when: "'local_repo' in (omnia_run_tags | default([]))"
when: "run_subscription_check | default(false) | bool"

- name: Validate omnia input config
hosts: localhost
Expand Down
4 changes: 4 additions & 0 deletions local_repo/local_repo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
omnia_run_tags: "{{ (ansible_run_tags | default([]) | list + ['local_repo']) | unique }}"
cacheable: true

- name: Enable subscription check for local_repo
ansible.builtin.set_fact:
run_subscription_check: true

- name: Include metadata vars
ansible.builtin.include_vars: "/opt/omnia/.data/oim_metadata.yml"
register: include_metadata
Expand Down
61 changes: 21 additions & 40 deletions upgrade/roles/upgrade_telemetry/tasks/apply_victoria_crs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,38 +55,11 @@
# and the operator creates new ones. To preserve IPs, we inject loadBalancerIP
# directly into the VMCluster CR's serviceSpec BEFORE applying, so the operator
# creates services with the correct IPs from the start (no race condition).
- name: Create LoadBalancer IP injection script
ansible.builtin.copy:
dest: /tmp/inject_vm_lb_ips.py
mode: "0755"
content: |
#!/usr/bin/env python3
import yaml
import sys
manifest_path = sys.argv[1]
vmselect_ip = sys.argv[2] if len(sys.argv) > 2 and sys.argv[2] else ""
vminsert_ip = sys.argv[3] if len(sys.argv) > 3 and sys.argv[3] else ""
with open(manifest_path) as f:
doc = yaml.safe_load(f)
spec = doc.get("spec", {})
changed = False
if vmselect_ip and "vmselect" in spec:
svc = spec["vmselect"].setdefault("serviceSpec", {}).setdefault("spec", {})
if svc.get("loadBalancerIP") != vmselect_ip:
svc["loadBalancerIP"] = vmselect_ip
changed = True
if vminsert_ip and "vminsert" in spec:
svc = spec["vminsert"].setdefault("serviceSpec", {}).setdefault("spec", {})
if svc.get("loadBalancerIP") != vminsert_ip:
svc["loadBalancerIP"] = vminsert_ip
changed = True
if changed:
with open(manifest_path, "w") as f:
yaml.dump(doc, f, default_flow_style=False, sort_keys=False)
print("Injected vmselect=" + vmselect_ip + " vminsert=" + vminsert_ip)
else:
print("IPs already present - no change needed")
sys.exit(0 if changed else 2)
- name: Stage LoadBalancer IP injection script
ansible.builtin.template:
src: inject_vm_lb_ips.py.j2
dest: "{{ ip_inject_script_path }}"
mode: "{{ executable_mode }}"
delegate_to: "{{ kube_vip }}"
connection: ssh
when:
Expand All @@ -95,7 +68,7 @@
- name: Inject preserved LoadBalancer IPs into VMCluster manifest
ansible.builtin.command:
cmd: >-
python3 /tmp/inject_vm_lb_ips.py
python3 {{ ip_inject_script_path }}
"{{ telemetry_deploy_dir }}/deployments/victoria-operator-vmcluster.yaml"
"{{ preserved_vmselect_ip | default('') }}"
"{{ preserved_vminsert_ip | default('') }}"
Expand All @@ -109,7 +82,7 @@

- name: Clean up LoadBalancer IP injection script
ansible.builtin.file:
path: /tmp/inject_vm_lb_ips.py
path: "{{ ip_inject_script_path }}"
state: absent
delegate_to: "{{ kube_vip }}"
connection: ssh
Expand Down Expand Up @@ -148,7 +121,9 @@
kubectl -n {{ telemetry_namespace }} get svc vminsert-{{ new_vmcluster_name }} \
-o jsonpath='{.status.loadBalancer.ingress[0].ip}' 2>/dev/null || echo ""
register: vminsert_lb_ip
until: vminsert_lb_ip.stdout | trim | length > 0
until: >
(vminsert_lb_ip is defined) and
((vminsert_lb_ip.stdout | default('') | trim | length) > 0)
retries: "{{ lb_ip_wait_retries }}"
delay: "{{ lb_ip_wait_delay }}"
changed_when: false
Expand All @@ -161,7 +136,9 @@
kubectl -n {{ telemetry_namespace }} get svc vmselect-{{ new_vmcluster_name }} \
-o jsonpath='{.status.loadBalancer.ingress[0].ip}' 2>/dev/null || echo ""
register: vmselect_lb_ip
until: vmselect_lb_ip.stdout | trim | length > 0
until: >
(vmselect_lb_ip is defined) and
((vmselect_lb_ip.stdout | default('') | trim | length) > 0)
retries: "{{ lb_ip_wait_retries }}"
delay: "{{ lb_ip_wait_delay }}"
changed_when: false
Expand Down Expand Up @@ -218,7 +195,9 @@
kubectl -n {{ telemetry_namespace }} get svc vminsert-{{ new_vmcluster_name }} \
-o jsonpath='{.status.loadBalancer.ingress[0].ip}' 2>/dev/null || echo ""
register: vminsert_lb_ip
until: vminsert_lb_ip.stdout | trim | length > 0
until: >
(vminsert_lb_ip is defined) and
((vminsert_lb_ip.stdout | default('') | trim | length) > 0)
retries: "{{ lb_ip_wait_retries }}"
delay: "{{ lb_ip_wait_delay }}"
changed_when: false
Expand All @@ -231,7 +210,9 @@
kubectl -n {{ telemetry_namespace }} get svc vmselect-{{ new_vmcluster_name }} \
-o jsonpath='{.status.loadBalancer.ingress[0].ip}' 2>/dev/null || echo ""
register: vmselect_lb_ip
until: vmselect_lb_ip.stdout | trim | length > 0
until: >
(vmselect_lb_ip is defined) and
((vmselect_lb_ip.stdout | default('') | trim | length) > 0)
retries: "{{ lb_ip_wait_retries }}"
delay: "{{ lb_ip_wait_delay }}"
changed_when: false
Expand All @@ -247,8 +228,8 @@
ansible.builtin.debug:
msg: "{{ victoria_lb_ip_reclaim_failed }}"
when: >-
(vminsert_lb_ip is defined and vminsert_lb_ip.stdout is defined and vminsert_lb_ip.stdout | trim | length == 0) or
(vmselect_lb_ip is defined and vmselect_lb_ip.stdout is defined and vmselect_lb_ip.stdout | trim | length == 0)
(vminsert_lb_ip is defined and vminsert_lb_ip.stdout | default('') | trim | length == 0) or
(vmselect_lb_ip is defined and vmselect_lb_ip.stdout | default('') | trim | length == 0)

# ── Apply scrape and agent CRs ──
- name: Check for VMScrape manifest
Expand Down
50 changes: 50 additions & 0 deletions upgrade/roles/upgrade_telemetry/templates/inject_vm_lb_ips.py.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/usr/bin/env python3

# Copyright 2026 Dell Inc. or its subsidiaries. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Find services in the telemetry namespace that are holding LoadBalancer IPs
# which should belong to VMCluster services (vminsert/vmselect).
# This can happen when MetalLB reassigns freed IPs to other services
# before the VMCluster services are created by the operator.
#
# Usage: bash find_ip_conflict_svcs.sh
# Output: One service name per line (services holding conflicting IPs)

import yaml
import sys
manifest_path = sys.argv[1]
vmselect_ip = sys.argv[2] if len(sys.argv) > 2 and sys.argv[2] else ""
vminsert_ip = sys.argv[3] if len(sys.argv) > 3 and sys.argv[3] else ""
with open(manifest_path) as f:
doc = yaml.safe_load(f)
spec = doc.get("spec", {})
changed = False
if vmselect_ip and "vmselect" in spec:
svc = spec["vmselect"].setdefault("serviceSpec", {}).setdefault("spec", {})
if svc.get("loadBalancerIP") != vmselect_ip:
svc["loadBalancerIP"] = vmselect_ip
changed = True
if vminsert_ip and "vminsert" in spec:
svc = spec["vminsert"].setdefault("serviceSpec", {}).setdefault("spec", {})
if svc.get("loadBalancerIP") != vminsert_ip:
svc["loadBalancerIP"] = vminsert_ip
changed = True
if changed:
with open(manifest_path, "w") as f:
yaml.dump(doc, f, default_flow_style=False, sort_keys=False)
print("Injected vmselect=" + vmselect_ip + " vminsert=" + vminsert_ip)
else:
print("IPs already present - no change needed")
sys.exit(0 if changed else 2)
1 change: 1 addition & 0 deletions upgrade/roles/upgrade_telemetry/vars/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ idrac_rollout_delay: 30
lb_ip_wait_retries: 30
lb_ip_wait_delay: 5
ip_conflict_script_path: /tmp/find_ip_conflict_svcs.sh
ip_inject_script_path: /tmp/inject_vm_lb_ips.py

# Victoria operator configuration
# victoria_operator_pkg is loaded dynamically from service_k8s JSON in include_required_input.yml
Expand Down
Loading