From 810459632a4fb28e1bde897aaef8775cba342b4b Mon Sep 17 00:00:00 2001 From: David Garcia Date: Thu, 16 Jul 2020 12:37:13 +0200 Subject: [PATCH] Make API Proxy optional and avoid replacing existing SSH Keys in the provisioner - Fixes bug 1154 - Fixes bug 1083 Change-Id: I0ee5e092f5ff205089c2b80ece9f4262572d58d2 Signed-off-by: David Garcia --- n2vc/k8s_juju_conn.py | 7 ++-- n2vc/libjuju.py | 2 +- n2vc/n2vc_juju_conn.py | 10 ++---- n2vc/provisioner.py | 73 +++++++++++++++++++++--------------------- 4 files changed, 44 insertions(+), 48 deletions(-) diff --git a/n2vc/k8s_juju_conn.py b/n2vc/k8s_juju_conn.py index 313e878..a0bf3cf 100644 --- a/n2vc/k8s_juju_conn.py +++ b/n2vc/k8s_juju_conn.py @@ -946,14 +946,13 @@ class K8sJujuConnector(K8sConnector): :param credentials dict: A dictionary containing the k8s credentials :returns: A boolean if the cluster is running locally """ + creds = yaml.safe_load(credentials) - if os.getenv("OSMLCM_VCA_APIPROXY"): - host_ip = os.getenv("OSMLCM_VCA_APIPROXY") - if creds and host_ip: + if creds and os.getenv("OSMLCM_VCA_APIPROXY"): for cluster in creds["clusters"]: if "server" in cluster["cluster"]: - if host_ip in cluster["cluster"]["server"]: + if os.getenv("OSMLCM_VCA_APIPROXY") in cluster["cluster"]["server"]: return True return False diff --git a/n2vc/libjuju.py b/n2vc/libjuju.py index 22ba182..cb24a3e 100644 --- a/n2vc/libjuju.py +++ b/n2vc/libjuju.py @@ -408,7 +408,7 @@ class Libjuju: connection=connection, nonce=params.nonce, machine_id=machine_id, - api=self.api_proxy, + proxy=self.api_proxy, ) ) diff --git a/n2vc/n2vc_juju_conn.py b/n2vc/n2vc_juju_conn.py index ed53da4..690d3be 100644 --- a/n2vc/n2vc_juju_conn.py +++ b/n2vc/n2vc_juju_conn.py @@ -166,14 +166,14 @@ class N2VCJujuConnector(N2VCConnector): if self.ca_cert: self.ca_cert = base64_to_cacert(vca_config["ca_cert"]) - if "api_proxy" in vca_config: + if "api_proxy" in vca_config and vca_config["api_proxy"] != "": self.api_proxy = vca_config["api_proxy"] self.log.debug( "api_proxy for native charms configured: {}".format(self.api_proxy) ) else: self.warning( - "api_proxy is not configured. Support for native charms is disabled" + "api_proxy is not configured" ) self.api_proxy = None @@ -377,10 +377,6 @@ class N2VCJujuConnector(N2VCConnector): # register machine on juju try: - if not self.api_proxy: - msg = "Cannot provision machine: api_proxy is not defined" - self.log.error(msg=msg) - raise N2VCException(message=msg) if not await self.libjuju.model_exists(model_name): await self.libjuju.add_model(model_name, cloud_name=self.cloud) machine_id = await self.libjuju.provision_machine( @@ -1188,7 +1184,7 @@ class N2VCJujuConnector(N2VCConnector): connection=connection, nonce=params.nonce, machine_id=machine_id, - api=self.api_proxy, + proxy=self.api_proxy, ) ) diff --git a/n2vc/provisioner.py b/n2vc/provisioner.py index fbb16ca..fea7a12 100644 --- a/n2vc/provisioner.py +++ b/n2vc/provisioner.py @@ -63,7 +63,7 @@ temp=$(mktemp) echo 'ubuntu ALL=(ALL) NOPASSWD:ALL' > $temp install -m 0440 $temp /etc/sudoers.d/90-juju-ubuntu rm $temp -su ubuntu -c 'install -D -m 0600 /dev/null ~/.ssh/authorized_keys' +su ubuntu -c '[ -f ~/.ssh/authorized_keys ] || install -D -m 0600 /dev/null ~/.ssh/authorized_keys' export authorized_keys="{}" if [ ! -z "$authorized_keys" ]; then su ubuntu -c 'echo $authorized_keys >> ~/.ssh/authorized_keys' @@ -254,12 +254,12 @@ class AsyncSSHProvisioner: return params - async def install_agent(self, connection, nonce, machine_id, api): + async def install_agent(self, connection, nonce, machine_id, proxy=None): """ :param object connection: Connection to Juju API :param str nonce: The nonce machine specification :param str machine_id: The id assigned to the machine - :param str api: IP of the API_PROXY + :param str proxy: IP of the API_PROXY :return: bool: If the initialization was successful """ @@ -288,39 +288,40 @@ class AsyncSSHProvisioner: - 127.0.0.1:17070 - '[::1]:17070' """ - m = re.search(r"apiaddresses:\n- (\d+\.\d+\.\d+\.\d+):17070", results.script) - apiaddress = m.group(1) - - """Add IP Table rule - - In order to route the traffic to the private ip of the Juju controller - we use a DNAT rule to tell the machine that the destination for the - private address is the public address of the machine where the Juju - controller is running in LXD. That machine will have a complimentary - iptables rule, routing traffic to the appropriate LXD container. - """ - - script = IPTABLES_SCRIPT.format(apiaddress, api) - - # Run this in a retry loop, because dpkg may be running and cause the - # script to fail. - retry = 10 - attempts = 0 - delay = 15 - - while attempts <= retry: - try: - attempts += 1 - stdout, stderr = await self._run_configure_script(script) - break - except Exception as e: - self.log.debug("Waiting for dpkg, sleeping {} seconds".format(delay)) - if attempts > retry: - raise e - else: - await asyncio.sleep(delay) - # Slowly back off the retry - delay += 15 + if proxy: + m = re.search(r"apiaddresses:\n- (\d+\.\d+\.\d+\.\d+):17070", results.script) + apiaddress = m.group(1) + + """Add IP Table rule + + In order to route the traffic to the private ip of the Juju controller + we use a DNAT rule to tell the machine that the destination for the + private address is the public address of the machine where the Juju + controller is running in LXD. That machine will have a complimentary + iptables rule, routing traffic to the appropriate LXD container. + """ + + script = IPTABLES_SCRIPT.format(apiaddress, proxy) + + # Run this in a retry loop, because dpkg may be running and cause the + # script to fail. + retry = 10 + attempts = 0 + delay = 15 + + while attempts <= retry: + try: + attempts += 1 + stdout, stderr = await self._run_configure_script(script) + break + except Exception as e: + self.log.debug("Waiting for dpkg, sleeping {} seconds".format(delay)) + if attempts > retry: + raise e + else: + await asyncio.sleep(delay) + # Slowly back off the retry + delay += 15 # self.log.debug("Running configure script") await self._run_configure_script(results.script) -- 2.25.1