Make API Proxy optional and avoid replacing existing SSH Keys in the provisioner 27/9427/10
authorDavid Garcia <david.garcia@canonical.com>
Thu, 16 Jul 2020 10:37:13 +0000 (12:37 +0200)
committerDavid Garcia <david.garcia@canonical.com>
Fri, 17 Jul 2020 12:12:01 +0000 (14:12 +0200)
- Fixes bug 1154
- Fixes bug 1083
Change-Id: I0ee5e092f5ff205089c2b80ece9f4262572d58d2
Signed-off-by: David Garcia <david.garcia@canonical.com>
n2vc/k8s_juju_conn.py
n2vc/libjuju.py
n2vc/n2vc_juju_conn.py
n2vc/provisioner.py

index 313e878..a0bf3cf 100644 (file)
@@ -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
         """
         :param credentials dict: A dictionary containing the k8s credentials
         :returns: A boolean if the cluster is running locally
         """
+
         creds = yaml.safe_load(credentials)
         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"]:
             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
                         return True
 
         return False
index 22ba182..cb24a3e 100644 (file)
@@ -408,7 +408,7 @@ class Libjuju:
                     connection=connection,
                     nonce=params.nonce,
                     machine_id=machine_id,
                     connection=connection,
                     nonce=params.nonce,
                     machine_id=machine_id,
-                    api=self.api_proxy,
+                    proxy=self.api_proxy,
                 )
             )
 
                 )
             )
 
index ed53da4..690d3be 100644 (file)
@@ -166,14 +166,14 @@ class N2VCJujuConnector(N2VCConnector):
         if self.ca_cert:
             self.ca_cert = base64_to_cacert(vca_config["ca_cert"])
 
         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(
             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
 
             )
             self.api_proxy = None
 
@@ -377,10 +377,6 @@ class N2VCJujuConnector(N2VCConnector):
 
         # register machine on juju
         try:
 
         # 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(
             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,
                 connection=connection,
                 nonce=params.nonce,
                 machine_id=machine_id,
-                api=self.api_proxy,
+                proxy=self.api_proxy,
             )
         )
 
             )
         )
 
index fbb16ca..fea7a12 100644 (file)
@@ -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
 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'
 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
 
 
         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 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
         """
 
         :return: bool: If the initialization was successful
         """
@@ -288,39 +288,40 @@ class AsyncSSHProvisioner:
             - 127.0.0.1:17070
             - '[::1]:17070'
         """
             - 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)
 
         # self.log.debug("Running configure script")
         await self._run_configure_script(results.script)