diff --git a/playbooks/internal_facts.yml b/playbooks/internal_facts.yml index 9938c1900..5b7bc689c 100644 --- a/playbooks/internal_facts.yml +++ b/playbooks/internal_facts.yml @@ -16,6 +16,8 @@ - name: Gather and compute network facts import_role: name: network_facts + tags: + - always - name: Gather minimal facts setup: gather_subset: '!all' diff --git a/roles/network_facts/defaults/main.yml b/roles/network_facts/defaults/main.yml new file mode 100644 index 000000000..cdd2aea54 --- /dev/null +++ b/roles/network_facts/defaults/main.yml @@ -0,0 +1,5 @@ +--- +# Additional string host to inject into NO_PROXY +additional_no_proxy: "" +additional_no_proxy_list: "{{ additional_no_proxy | split(',') }}" +no_proxy_exclude_workers: false diff --git a/roles/network_facts/tasks/main.yaml b/roles/network_facts/tasks/main.yaml index 2460a982e..27aa6180b 100644 --- a/roles/network_facts/tasks/main.yaml +++ b/roles/network_facts/tasks/main.yaml @@ -1,41 +1,63 @@ --- -- name: Set facts variables - tags: - - always - block: - - name: Gather node IPs - setup: - gather_subset: '!all,!min,network' - filter: "ansible_default_ip*" - when: ansible_default_ipv4 is not defined or ansible_default_ipv6 is not defined - ignore_unreachable: true +- name: Gather node IPs + setup: + gather_subset: '!all,!min,network' + filter: "ansible_default_ip*" + when: ansible_default_ipv4 is not defined or ansible_default_ipv6 is not defined + ignore_unreachable: true - - name: Set computed IPs varables - vars: - fallback_ip: "{{ ansible_default_ipv4.address | d('127.0.0.1') }}" - fallback_ip6: "{{ ansible_default_ipv6.address | d('::1') }}" - # Set 127.0.0.1 as fallback IP if we do not have host facts for host - # ansible_default_ipv4 isn't what you think. - _ipv4: "{{ ip | default(fallback_ip) }}" - _access_ipv4: "{{ access_ip | default(_ipv4) }}" - _ipv6: "{{ ip6 | default(fallback_ip6) }}" - _access_ipv6: "{{ access_ip6 | default(_ipv6) }}" - _access_ips: - - "{{ _access_ipv4 if ipv4_stack }}" - - "{{ _access_ipv6 if ipv6_stack }}" - _ips: - - "{{ _ipv4 if ipv4_stack }}" - - "{{ _ipv6 if ipv6_stack }}" - set_fact: - cacheable: true - main_access_ip: "{{ _access_ipv4 if ipv4_stack else _access_ipv6 }}" - main_ip: "{{ _ipv4 if ipv4_stack else _ipv6 }}" - # Mixed IPs - for dualstack - main_access_ips: "{{ _access_ips | select }}" - main_ips: "{{ _ips | select }}" +- name: Set computed IPs variables + vars: + fallback_ip: "{{ ansible_default_ipv4.address | d('127.0.0.1') }}" + fallback_ip6: "{{ ansible_default_ipv6.address | d('::1') }}" + # Set 127.0.0.1 as fallback IP if we do not have host facts for host + # ansible_default_ipv4 isn't what you think. + _ipv4: "{{ ip | default(fallback_ip) }}" + _access_ipv4: "{{ access_ip | default(_ipv4) }}" + _ipv6: "{{ ip6 | default(fallback_ip6) }}" + _access_ipv6: "{{ access_ip6 | default(_ipv6) }}" + _access_ips: + - "{{ _access_ipv4 if ipv4_stack }}" + - "{{ _access_ipv6 if ipv6_stack }}" + _ips: + - "{{ _ipv4 if ipv4_stack }}" + - "{{ _ipv6 if ipv6_stack }}" + set_fact: + cacheable: true + main_access_ip: "{{ _access_ipv4 if ipv4_stack else _access_ipv6 }}" + main_ip: "{{ _ipv4 if ipv4_stack else _ipv6 }}" + # Mixed IPs - for dualstack + main_access_ips: "{{ _access_ips | select }}" + main_ips: "{{ _ips | select }}" - - name: Set no_proxy - import_tasks: no_proxy.yml - when: - - http_proxy is defined or https_proxy is defined - - no_proxy is not defined +- name: Set no_proxy to all assigned cluster IPs and hostnames + when: + - http_proxy is defined or https_proxy is defined + - no_proxy is not defined + vars: + groups_with_no_proxy: + - kube_control_plane + - "{{ '' if no_proxy_exclude_workers else 'kube_node' }}" # TODO: exclude by a boolean in inventory rather than global variable + - etcd + - calico_rr + hosts_with_no_proxy: "{{ groups_with_no_proxy | select | map('extract', groups) | select('defined') | flatten }}" + _hostnames: "{{ (hosts_with_no_proxy + + (hosts_with_no_proxy | map('extract', hostvars, morekeys=['ansible_hostname']) + | select('defined'))) + | unique }}" + no_proxy_prepare: + - "{{ apiserver_loadbalancer_domain_name | d('') }}" + - "{{ loadbalancer_apiserver.address if loadbalancer_apiserver is defined else '' }}" + - "{{ hosts_with_no_proxy | map('extract', hostvars, morekeys=['main_access_ip']) }}" + - "{{ _hostnames }}" + - "{{ _hostnames | map('regex_replace', '$', '.' + dns_domain ) }}" + - "{{ additional_no_proxy_list }}" + - 127.0.0.1 + - localhost + - "{{ kube_service_subnets }}" + - "{{ kube_pods_subnets }}" + - svc + - "svc.{{ dns_domain }}" + set_fact: + no_proxy: "{{ no_proxy_prepare | select | flatten | unique | join(',') }}" + run_once: true diff --git a/roles/network_facts/tasks/no_proxy.yml b/roles/network_facts/tasks/no_proxy.yml deleted file mode 100644 index b2ad83d3d..000000000 --- a/roles/network_facts/tasks/no_proxy.yml +++ /dev/null @@ -1,40 +0,0 @@ ---- -- name: Set no_proxy to all assigned cluster IPs and hostnames - set_fact: - # noqa: jinja[spacing] - no_proxy_prepare: >- - {%- if loadbalancer_apiserver is defined -%} - {{ apiserver_loadbalancer_domain_name }}, - {{ loadbalancer_apiserver.address | default('') }}, - {%- endif -%} - {%- if no_proxy_exclude_workers | default(false) -%} - {% set cluster_or_control_plane = 'kube_control_plane' %} - {%- else -%} - {% set cluster_or_control_plane = 'k8s_cluster' %} - {%- endif -%} - {%- for item in (groups[cluster_or_control_plane] + groups['etcd'] | default([]) + groups['calico_rr'] | default([])) | unique -%} - {{ hostvars[item]['main_access_ip'] }}, - {%- if item != hostvars[item].get('ansible_hostname', '') -%} - {{ hostvars[item]['ansible_hostname'] }}, - {{ hostvars[item]['ansible_hostname'] }}.{{ dns_domain }}, - {%- endif -%} - {{ item }},{{ item }}.{{ dns_domain }}, - {%- endfor -%} - {%- if additional_no_proxy is defined -%} - {{ additional_no_proxy }}, - {%- endif -%} - 127.0.0.1,localhost,{{ kube_service_subnets }},{{ kube_pods_subnets }},svc,svc.{{ dns_domain }} - delegate_to: localhost - connection: local - delegate_facts: true - become: false - run_once: true - -- name: Populates no_proxy to all hosts - set_fact: - no_proxy: "{{ hostvars.localhost.no_proxy_prepare | select }}" - # noqa: jinja[spacing] - proxy_env: "{{ proxy_env | combine({ - 'no_proxy': hostvars.localhost.no_proxy_prepare, - 'NO_PROXY': hostvars.localhost.no_proxy_prepare - }) }}" diff --git a/tests/files/rockylinux10-cilium.yml b/tests/files/rockylinux10-cilium.yml index afead2a9c..c83ef88ac 100644 --- a/tests/files/rockylinux10-cilium.yml +++ b/tests/files/rockylinux10-cilium.yml @@ -13,3 +13,21 @@ kube_owner: root # Node Feature Discovery node_feature_discovery_enabled: true kube_asymmetric_encryption_algorithm: "ECDSA-P256" + +# Testing no_proxy setup +# The proxy is not intended to be accessed at all, we're only testing +# the no_proxy construction +https_proxy: "http://some-proxy.invalid" +http_proxy: "http://some-proxy.invalid" +additional_no_proxy_list: + - github.com + - githubusercontent.com + - k8s.io + - rockylinux.org + - docker.io + - googleapis.com + - quay.io + - pkg.dev + - amazonaws.com + - cilium.io +skip_http_proxy_on_os_packages: true