diff --git a/meta/io.murano.lib.networks.Neutron/Classes/NewNetwork.yaml b/meta/io.murano.lib.networks.Neutron/Classes/NewNetwork.yaml index fdbdcf91..38dd0480 100644 --- a/meta/io.murano.lib.networks.Neutron/Classes/NewNetwork.yaml +++ b/meta/io.murano.lib.networks.Neutron/Classes/NewNetwork.yaml @@ -51,6 +51,9 @@ Workflow: Arguments: - instance: Contract: $.class(res:Instance).notNull() + - assignFloatingIp: + Contract: $.bool().notNull() + Default: false Body: - $.ensureNetworkConfigured() - $portname: $instance.name + '-port-to-' + $.id() @@ -67,6 +70,33 @@ Workflow: - Ref: $portname - $.environment.stack.updateTemplate($template) + - If: $assignFloatingIp + Then: + - $extNetId: $.netExplorer.getExternalNetworkIdForRouter($.externalRouterId) + - If: $extNetId != null + Then: + - $fip_name: $instance.name + '-FloatingIP-' + $.id() + - $template: + Resources: + $fip_name: + Type: 'OS::Neutron::FloatingIP' + Properties: + floating_network_id: $extNetId + $instance.name + '-FloatingIpAssoc-' + $.id(): + Type: 'OS::Neutron::FloatingIPAssociation' + Properties: + floatingip_id: + Ref: $fip_name + port_id: + Ref: $portname + Outputs: + $instance.name + '-FloatingIPaddress': + Value: + Fn::GetAtt: + - $fip_name + - floating_ip_address + Description: Floating IP assigned + - $.environment.stack.updateTemplate($template) ensureNetworkConfigured: Body: @@ -127,5 +157,3 @@ Workflow: router_id: $.externalRouterId subnet_id: {Ref: $.subnet_res_name} - $.environment.stack.updateTemplate($template) - - diff --git a/meta/io.murano/Classes/resources/Instance.yaml b/meta/io.murano/Classes/resources/Instance.yaml index 761b99d4..66d40168 100644 --- a/meta/io.murano/Classes/resources/Instance.yaml +++ b/meta/io.murano/Classes/resources/Instance.yaml @@ -29,6 +29,12 @@ Properties: useEnvironmentNetwork: true useFlatNetwork: false customNetworks: [] + assignFloatingIp: + Contract: $.bool().notNull() + Default: false + floatingIpAddress: + Contract: $.string() + Usage: Out Workflow: initialize: @@ -64,7 +70,7 @@ Workflow: - $.environment.stack.push() - $outputs: $.environment.stack.output() - $.ipAddresses: $outputs.get(format('{0}-PublicIp', $this.name)) - + - $.floatingIpAddress: $outputs.get(format('{0}-FloatingIPaddress', $this.name)) - $.environment.instanceNotifier.trackApplication($this) joinNet: @@ -74,7 +80,13 @@ Workflow: Body: - If: $net != null Then: - $net.addHostToNetwork($) + - If: $.assignFloatingIp and (not bool($.getAttr(fipAssigned))) + Then: + - $assignFip: true + - $.setAttr(fipAssigned, true) + Else: + - $assignFip: false + - $net.addHostToNetwork($, $assignFip) destroy: Body: diff --git a/muranoapi/engine/system/net_explorer.py b/muranoapi/engine/system/net_explorer.py index d566130c..996d82d6 100644 --- a/muranoapi/engine/system/net_explorer.py +++ b/muranoapi/engine/system/net_explorer.py @@ -102,6 +102,33 @@ class NetworkExplorer(murano_object.MuranoObject): def getDefaultDns(self): return self._settings.default_dns + # noinspection PyPep8Naming + def getExternalNetworkIdForRouter(self, routerId): + router = self._neutron.show_router(routerId).get('router') + if not router or 'external_gateway_info' not in router: + return None + return router['external_gateway_info'].get('network_id') + + # noinspection PyPep8Naming + def getExternalNetworkIdForNetwork(self, networkId): + network = self._neutron.show_network(networkId).get('network') + if network.get('router:external', False): + return networkId + + # Get router interfaces of the network + router_ports = self._neutron.list_ports( + **{'device_owner': 'network:router_interface', + 'network_id': networkId}).get('ports') + + # For each router this network is connected to + # check if the router has external_gateway set + for router_port in router_ports: + ext_net_id = self.getExternalNetworkIdForRouter( + router_port.get('device_id')) + if ext_net_id: + return ext_net_id + return None + def _get_cidrs_taken_by_router(self, router_id): if not router_id: return []