]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/pybind/mgr/cephadm/services/ingress.py
update ceph source to reef 18.2.1
[ceph.git] / ceph / src / pybind / mgr / cephadm / services / ingress.py
index 7523bc086cee667a64f0c1e1ba6d1e4c4187f2ed..55be3045466abe3c9d130b2cabc8c871bec2fb73 100644 (file)
@@ -165,6 +165,14 @@ class IngressService(CephService):
             ]
 
         host_ip = daemon_spec.ip or self.mgr.inventory.get_addr(daemon_spec.host)
+        server_opts = []
+        if spec.enable_haproxy_protocol:
+            server_opts.append("send-proxy-v2")
+        logger.debug("enabled default server opts: %r", server_opts)
+        ip = '*' if spec.virtual_ips_list else str(spec.virtual_ip).split('/')[0] or daemon_spec.ip or '*'
+        frontend_port = daemon_spec.ports[0] if daemon_spec.ports else spec.frontend_port
+        if ip != '*' and frontend_port:
+            daemon_spec.port_ips = {str(frontend_port): ip}
         haproxy_conf = self.mgr.template.render(
             'services/ingress/haproxy.cfg.j2',
             {
@@ -174,10 +182,11 @@ class IngressService(CephService):
                 'servers': servers,
                 'user': spec.monitor_user or 'admin',
                 'password': password,
-                'ip': "*" if spec.virtual_ips_list else str(spec.virtual_ip).split('/')[0] or daemon_spec.ip or '*',
-                'frontend_port': daemon_spec.ports[0] if daemon_spec.ports else spec.frontend_port,
+                'ip': ip,
+                'frontend_port': frontend_port,
                 'monitor_port': daemon_spec.ports[1] if daemon_spec.ports else spec.monitor_port,
-                'local_host_ip': host_ip
+                'local_host_ip': host_ip,
+                'default_server_opts': server_opts,
             }
         )
         config_files = {
@@ -242,38 +251,35 @@ class IngressService(CephService):
         host = daemon_spec.host
         hosts = sorted(list(set([host] + [str(d.hostname) for d in daemons])))
 
-        # interface
-        bare_ips = []
-        if spec.virtual_ip:
-            bare_ips.append(str(spec.virtual_ip).split('/')[0])
-        elif spec.virtual_ips_list:
-            bare_ips = [str(vip).split('/')[0] for vip in spec.virtual_ips_list]
-        interface = None
-        for bare_ip in bare_ips:
+        def _get_valid_interface_and_ip(vip: str, host: str) -> Tuple[str, str]:
+            # interface
+            bare_ip = ipaddress.ip_interface(vip).ip
+            host_ip = ''
+            interface = None
             for subnet, ifaces in self.mgr.cache.networks.get(host, {}).items():
                 if ifaces and ipaddress.ip_address(bare_ip) in ipaddress.ip_network(subnet):
                     interface = list(ifaces.keys())[0]
+                    host_ip = ifaces[interface][0]
                     logger.info(
                         f'{bare_ip} is in {subnet} on {host} interface {interface}'
                     )
                     break
-            else:  # nobreak
-                continue
-            break
-        # try to find interface by matching spec.virtual_interface_networks
-        if not interface and spec.virtual_interface_networks:
-            for subnet, ifaces in self.mgr.cache.networks.get(host, {}).items():
-                if subnet in spec.virtual_interface_networks:
-                    interface = list(ifaces.keys())[0]
-                    logger.info(
-                        f'{spec.virtual_ip} will be configured on {host} interface '
-                        f'{interface} (which has guiding subnet {subnet})'
-                    )
-                    break
-        if not interface:
-            raise OrchestratorError(
-                f"Unable to identify interface for {spec.virtual_ip} on {host}"
-            )
+            # try to find interface by matching spec.virtual_interface_networks
+            if not interface and spec.virtual_interface_networks:
+                for subnet, ifaces in self.mgr.cache.networks.get(host, {}).items():
+                    if subnet in spec.virtual_interface_networks:
+                        interface = list(ifaces.keys())[0]
+                        host_ip = ifaces[interface][0]
+                        logger.info(
+                            f'{spec.virtual_ip} will be configured on {host} interface '
+                            f'{interface} (which is in subnet {subnet})'
+                        )
+                        break
+            if not interface:
+                raise OrchestratorError(
+                    f"Unable to identify interface for {spec.virtual_ip} on {host}"
+                )
+            return interface, host_ip
 
         # script to monitor health
         script = '/usr/bin/false'
@@ -318,7 +324,36 @@ class IngressService(CephService):
         # other_ips in conf file and converter to ips
         if host in hosts:
             hosts.remove(host)
-        other_ips = [utils.resolve_ip(self.mgr.inventory.get_addr(h)) for h in hosts]
+        host_ips: List[str] = []
+        other_ips: List[List[str]] = []
+        interfaces: List[str] = []
+        for vip in virtual_ips:
+            interface, ip = _get_valid_interface_and_ip(vip, host)
+            host_ips.append(ip)
+            interfaces.append(interface)
+            ips: List[str] = []
+            for h in hosts:
+                _, ip = _get_valid_interface_and_ip(vip, h)
+                ips.append(ip)
+            other_ips.append(ips)
+
+        # Use interface as vrrp_interface for vrrp traffic if vrrp_interface_network not set on the spec
+        vrrp_interfaces: List[str] = []
+        if not spec.vrrp_interface_network:
+            vrrp_interfaces = interfaces
+        else:
+            for subnet, ifaces in self.mgr.cache.networks.get(host, {}).items():
+                if subnet == spec.vrrp_interface_network:
+                    vrrp_interface = [list(ifaces.keys())[0]] * len(interfaces)
+                    logger.info(
+                        f'vrrp will be configured on {host} interface '
+                        f'{vrrp_interface} (which is in subnet {subnet})'
+                    )
+                    break
+            else:
+                raise OrchestratorError(
+                    f"Unable to identify vrrp interface for {spec.vrrp_interface_network} on {host}"
+                )
 
         keepalived_conf = self.mgr.template.render(
             'services/ingress/keepalived.conf.j2',
@@ -326,12 +361,14 @@ class IngressService(CephService):
                 'spec': spec,
                 'script': script,
                 'password': password,
-                'interface': interface,
+                'interfaces': interfaces,
+                'vrrp_interfaces': vrrp_interfaces,
                 'virtual_ips': virtual_ips,
+                'first_virtual_router_id': spec.first_virtual_router_id,
                 'states': states,
                 'priorities': priorities,
                 'other_ips': other_ips,
-                'host_ip': utils.resolve_ip(self.mgr.inventory.get_addr(host)),
+                'host_ips': host_ips,
             }
         )