fix: ansible 2.19: calico resources final evaluation (#13503)

The bgp changes are a bit verbose, because I chose to reproduce the
exact semantics of the current code, so that the manifest handed to
calicoctl does not contain unset fields (instead of just using defaults
value).

It would be more readable to just accept default value in the
manifests, but might be a problem if there is other writer of the same
Calico resources.
This commit is contained in:
Max Gautier
2026-09-15 08:55:22 +00:00
committed by GitHub
parent 53a30aea58
commit 5af06acee1
3 changed files with 95 additions and 133 deletions
@@ -241,9 +241,6 @@ cilium_identity_allocation_mode: crd
# https://docs.cilium.io/en/stable/concepts/networking/ipam/ # https://docs.cilium.io/en/stable/concepts/networking/ipam/
cilium_ipam_mode: cluster-pool cilium_ipam_mode: cluster-pool
# Determines if calico_rr group exists
peer_with_calico_rr: "{{ 'calico_rr' in groups and groups['calico_rr'] | length > 0 }}"
# Choose data store type for calico: "etcd" or "kdd" (kubernetes datastore) # Choose data store type for calico: "etcd" or "kdd" (kubernetes datastore)
calico_datastore: "kdd" calico_datastore: "kdd"
+88 -130
View File
@@ -191,44 +191,36 @@
ignore_errors: true ignore_errors: true
changed_when: false changed_when: false
- name: Calico | Set kubespray calico network pool
set_fact:
_calico_pool: >
{
"kind": "IPPool",
"apiVersion": "projectcalico.org/v3",
"metadata": {
"name": "{{ calico_pool_name }}",
},
"spec": {
"blockSize": {{ calico_pool_blocksize }},
"cidr": "{{ calico_pool_cidr | default(kube_pods_subnet) }}",
"ipipMode": "{{ calico_ipip_mode }}",
"vxlanMode": "{{ calico_vxlan_mode }}",
"natOutgoing": {{ nat_outgoing | default(false) }}
}
}
- name: Calico | Process calico network pool
when:
- _calico_pool_cmd is success
block:
- name: Calico | Get current calico network pool blocksize
set_fact:
_calico_blocksize: >
{
"spec": {
"blockSize": {{ (_calico_pool_cmd.stdout | from_json).spec.blockSize }}
}
}
- name: Calico | Merge calico network pool
set_fact:
_calico_pool: "{{ _calico_pool_cmd.stdout | from_json | combine(_calico_pool, _calico_blocksize, recursive=True) }}"
- name: Calico | Configure calico network pool - name: Calico | Configure calico network pool
vars:
_calico_blocksize: "{{ {'spec': {'blockSize': (_calico_pool_cmd.stdout | from_json).spec.blockSize } } }}"
# We need to specify the dict inside jinja because otherwhise the blockSize can become a string
# instead of a int and no amount of | int makes it back into and integer
# TODO: use a normal yaml dict after upgrading to ansible-core 2.19, where the issue does not exist
_calico_pool:
kind: "IPPool"
apiVersion: "projectcalico.org/v3"
metadata:
name: "{{ calico_pool_name }}"
spec:
blockSize: "{{ calico_pool_blocksize }}"
cidr: "{{ calico_pool_cidr | default(kube_pods_subnet) }}"
ipipMode: "{{ calico_ipip_mode }}"
vxlanMode: "{{ calico_vxlan_mode }}"
natOutgoing: "{{ nat_outgoing | default(false) }}"
_calico_pool_merged: "{{ (
(_calico_pool_cmd.stdout | from_json)
if _calico_pool_cmd is success else {}
)
| combine(
_calico_pool,
_calico_blocksize if _calico_pool_cmd is success else {},
recursive=True) }}"
# override order is current state < config < blocksize
# because blocksize is immutable, so we always reuse it
command: command:
cmd: "{{ bin_dir }}/calicoctl.sh apply -f -" cmd: "{{ bin_dir }}/calicoctl.sh apply -f -"
stdin: "{{ _calico_pool is string | ternary(_calico_pool, _calico_pool | to_json) }}" stdin: "{{ _calico_pool_merged | to_json }}"
changed_when: false changed_when: false
- name: Calico | Configure Calico IPv6 Pool - name: Calico | Configure Calico IPv6 Pool
@@ -242,66 +234,38 @@
ignore_errors: true ignore_errors: true
changed_when: false changed_when: false
- name: Calico | Set kubespray calico network pool - name: Calico | Configure calico IPv6 network pool
set_fact: vars:
_calico_pool_ipv6: > _calico_blocksize_ipv6: "{{ {'spec': {'blockSize': (_calico_pool_ipv6_cmd.stdout | from_json).spec.blockSize } } }}"
{ # We need to specify the dict inside jinja because otherwhise the blockSize can become a string
"kind": "IPPool", # instead of a int and no amount of | int makes it back into and integer
"apiVersion": "projectcalico.org/v3", # TODO: use a normal yaml dict after upgrading to ansible-core 2.19, where the issue does not exist
"metadata": { _calico_pool_ipv6:
"name": "{{ calico_pool_name }}-ipv6", kind: "IPPool"
}, apiVersion: "projectcalico.org/v3"
"spec": { metadata:
"blockSize": {{ calico_pool_blocksize_ipv6 }}, name: "{{ calico_pool_name }}-ipv6"
"cidr": "{{ calico_pool_cidr_ipv6 | default(kube_pods_subnet_ipv6) }}", spec:
"ipipMode": "{{ calico_ipip_mode_ipv6 }}", blockSize: "{{ calico_pool_blocksize_ipv6 }}"
"vxlanMode": "{{ calico_vxlan_mode_ipv6 }}", cidr: "{{ calico_pool_cidr_ipv6 | default(kube_pods_subnet_ipv6) }}"
"natOutgoing": {{ nat_outgoing_ipv6 | default(false) }} ipipMode: "{{ calico_ipip_mode_ipv6 }}"
} vxlanMode: "{{ calico_vxlan_mode_ipv6 }}"
} natOutgoing: "{{ nat_outgoing_ipv6 | default(false) }}"
_calico_pool_merged_ipv6: "{{ (
- name: Calico | Process calico ipv6 network pool (_calico_pool_ipv6_cmd.stdout | from_json)
when: if _calico_pool_ipv6_cmd is success else {}
- _calico_pool_ipv6_cmd is success )
block: | combine(
- name: Calico | Get current calico ipv6 network pool blocksize _calico_pool_ipv6,
set_fact: _calico_blocksize_ipv6 if _calico_pool_ipv6_cmd is success else {},
_calico_blocksize_ipv6: > recursive=True) }}"
{ # override order is current state < config < blocksize
"spec": { # because blocksize is immutable, so we always reuse it
"blockSize": {{ (_calico_pool_ipv6_cmd.stdout | from_json).spec.blockSize }}
}
}
- name: Calico | Merge calico ipv6 network pool
set_fact:
_calico_pool_ipv6: "{{ _calico_pool_ipv6_cmd.stdout | from_json | combine(_calico_pool_ipv6, _calico_blocksize_ipv6, recursive=True) }}"
- name: Calico | Configure calico ipv6 network pool
command: command:
cmd: "{{ bin_dir }}/calicoctl.sh apply -f -" cmd: "{{ bin_dir }}/calicoctl.sh apply -f -"
stdin: "{{ _calico_pool_ipv6 is string | ternary(_calico_pool_ipv6, _calico_pool_ipv6 | to_json) }}" stdin: "{{ _calico_pool_merged_ipv6 | to_json }}"
changed_when: false changed_when: false
- name: Populate Service External IPs
set_fact:
_service_external_ips: "{{ _service_external_ips | default([]) + [{'cidr': item}] }}"
with_items: "{{ calico_advertise_service_external_ips }}"
run_once: true
- name: Populate Service LoadBalancer IPs
set_fact:
_service_loadbalancer_ips: "{{ _service_loadbalancer_ips | default([]) + [{'cidr': item}] }}"
with_items: "{{ calico_advertise_service_loadbalancer_ips }}"
run_once: true
- name: "Determine nodeToNodeMesh needed state"
set_fact:
nodeToNodeMeshEnabled: "false"
when:
- peer_with_router | default(false) or peer_with_calico_rr | default(false)
- ('k8s_cluster' in group_names)
run_once: true
- name: Calico | Configure Calico BGP - name: Calico | Configure Calico BGP
when: when:
- inventory_hostname == groups['kube_control_plane'][0] - inventory_hostname == groups['kube_control_plane'][0]
@@ -312,46 +276,40 @@
ignore_errors: true ignore_errors: true
changed_when: false changed_when: false
- name: Calico | Set kubespray BGP Configuration
set_fact:
# noqa: jinja[spacing]
_bgp_config: >
{
"kind": "BGPConfiguration",
"apiVersion": "projectcalico.org/v3",
"metadata": {
"name": "default",
},
"spec": {
"listenPort": {{ calico_bgp_listen_port }},
"logSeverityScreen": "Info",
{% if not calico_no_global_as_num | default(false) %}"asNumber": {{ global_as_num }},{% endif %}
"nodeToNodeMeshEnabled": {{ nodeToNodeMeshEnabled | default('true') }} ,
{% if calico_advertise_cluster_ips | default(false) %}
"serviceClusterIPs":
{%- if ipv4_stack and ipv6_stack-%}
[{"cidr": "{{ kube_service_addresses }}", "cidr": "{{ kube_service_addresses_ipv6 }}"}],
{%- elif ipv6_stack-%}
[{"cidr": "{{ kube_service_addresses_ipv6 }}"}],
{%- else -%}
[{"cidr": "{{ kube_service_addresses }}"}],
{%- endif -%}
{% endif %}
{% if calico_advertise_service_loadbalancer_ips | length > 0 %}"serviceLoadBalancerIPs": {{ _service_loadbalancer_ips }},{% endif %}
"serviceExternalIPs": {{ _service_external_ips | default([]) }}
}
}
- name: Calico | Process BGP Configuration
set_fact:
_bgp_config: "{{ _bgp_config_cmd.stdout | from_json | combine(_bgp_config, recursive=True) }}"
when:
- _bgp_config_cmd is success
- name: Calico | Set up BGP Configuration - name: Calico | Set up BGP Configuration
vars:
_service_ips:
- "{{ kube_service_addresses if ipv4_stack else '' }}"
- "{{ kube_service_addresses_ipv6 if ipv6_stack else '' }}"
_cluster_ips:
spec:
serviceClusterIPs: "{{ _service_ips | select | map('community.general.dict_kv', 'cidr') }}"
_lb_ips:
spec:
serviceLoadBalancerIPs: "{{ calico_advertise_service_loadbalancer_ips | map('community.general.dict_kv', 'cidr') }}"
_as_num:
spec:
asNumber: "{{ global_as_num }}"
_bgp_config_base:
kind: "BGPConfiguration"
apiVersion: "projectcalico.org/v3"
metadata:
name: "default"
spec:
listenPort: "{{ calico_bgp_listen_port }}"
logSeverityScreen: "Info"
nodeToNodeMeshEnabled: "{{ not (peer_with_router or peer_with_calico_rr) }}"
serviceExternalIPs: "{{ calico_advertise_service_external_ips | map('community.general.dict_kv', 'cidr') }}"
_bgp_config_merged: "{{ ((_bgp_config_cmd.stdout | from_json) if _bgp_config_cmd is success else {})
| combine(_bgp_config_base,
_cluster_ips if calico_advertise_cluster_ips else {},
_lb_ips if calico_advertise_service_loadbalancer_ips != [] else {},
_as_num if not calico_no_global_as_num else {},
recursive=True)
}}"
command: command:
cmd: "{{ bin_dir }}/calicoctl.sh apply -f -" cmd: "{{ bin_dir }}/calicoctl.sh apply -f -"
stdin: "{{ _bgp_config is string | ternary(_bgp_config, _bgp_config | to_json) }}" stdin: "{{ _bgp_config_merged | to_json }}"
changed_when: false changed_when: false
- name: Calico | Create calico manifests - name: Calico | Create calico manifests
@@ -477,9 +435,9 @@
- name: Calico | Peer with Calico Route Reflector - name: Calico | Peer with Calico Route Reflector
include_tasks: peer_with_calico_rr.yml include_tasks: peer_with_calico_rr.yml
when: when:
- peer_with_calico_rr | default(false) - peer_with_calico_rr
- name: Calico | Peer with the router - name: Calico | Peer with the router
include_tasks: peer_with_router.yml include_tasks: peer_with_router.yml
when: when:
- peer_with_router | default(false) - peer_with_router
@@ -32,11 +32,18 @@ calico_cert_dir: /etc/calico/certs
# Global as_num (/calico/bgp/v1/global/as_num) # Global as_num (/calico/bgp/v1/global/as_num)
global_as_num: "64512" global_as_num: "64512"
calico_no_global_as_num: false
# TODO : deprecate and use undef() or another invalid value in global_as_num for the same meaning
peer_with_router: false
peer_with_calico_rr: "{{ groups.get('calico_rr', []) != [] }}"
# You can set MTU value here. If left undefined or empty, it will # You can set MTU value here. If left undefined or empty, it will
# not be specified in calico CNI config, so Calico will use built-in # not be specified in calico CNI config, so Calico will use built-in
# defaults. The value should be a number, not a string. # defaults. The value should be a number, not a string.
# calico_mtu: 1500 # calico_mtu: 1500
calico_advertise_cluster_ips: false
# Advertise Service External IPs # Advertise Service External IPs
calico_advertise_service_external_ips: [] calico_advertise_service_external_ips: []