]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/cephadm: store contianer registry credentials in config-key 44658/head
authorDaniel Pivonka <dpivonka@redhat.com>
Wed, 10 Nov 2021 16:18:06 +0000 (11:18 -0500)
committerAdam King <adking@redhat.com>
Thu, 17 Feb 2022 05:22:39 +0000 (00:22 -0500)
Signed-off-by: Daniel Pivonka <dpivonka@redhat.com>
(cherry picked from commit 2c29286b370b1079a35e0e0d47c33a7dabab3468)

Conflicts:
src/pybind/mgr/cephadm/module.py
src/pybind/mgr/cephadm/serve.py

doc/cephadm/install.rst
qa/suites/orch/cephadm/mgr-nfs-upgrade/4-final.yaml
src/cephadm/cephadm
src/pybind/mgr/cephadm/migrations.py
src/pybind/mgr/cephadm/module.py
src/pybind/mgr/cephadm/serve.py
src/pybind/mgr/cephadm/tests/test_cephadm.py

index e4806c43d03db2e7fdf7bc7b3aa7740059cb1de1..e9272a55f518adfc0237344734e530f02575234d 100644 (file)
@@ -213,17 +213,13 @@ available options.
   designate with this option must have passwordless sudo access.
 
 * If you are using a container on an authenticated registry that requires
-  login, you may add the three arguments:
-  #. ``--registry-url <url of registry>``
-
-  #. ``--registry-username <username of account on registry>``
+  login, you may add the argument:
 
-  #. ``--registry-password <password of account on registry>`` 
+  * ``--registry-json <path to json file>`` 
 
-  OR
+  example contents of JSON file with login info::
 
-  * ``--registry-json <json file with login info>`` 
+      {"url":"REGISTRY_URL", "username":"REGISTRY_USERNAME", "password":"REGISTRY_PASSWORD"}
   
   Cephadm will attempt to log in to this registry so it can pull your container
   and then store the login info in its config database. Other hosts added to
index b1957d9d62880f3febb0fc9eba88a800ac994f5b..2a834ead4c06909bc60ece482b02a6d999679c32 100644 (file)
@@ -7,4 +7,4 @@ tasks:
       - ceph nfs cluster ls | grep foo
       - ceph nfs export ls foo --detailed
       - rados -p .nfs --all ls -
-      - ceph config get mgr mgr/cephadm/migration_current | grep 4
+      - ceph config get mgr mgr/cephadm/migration_current | grep 5
index bddcd46c82c3793026814d28b26a4d2780681e52..ff816b0cb328ddc178fd6ad23109bf5d9455c25c 100755 (executable)
@@ -4585,9 +4585,8 @@ def command_bootstrap(ctx):
         prepare_ssh(ctx, cli, wait_for_mgr_restart)
 
     if ctx.registry_url and ctx.registry_username and ctx.registry_password:
-        cli(['config', 'set', 'mgr', 'mgr/cephadm/registry_url', ctx.registry_url, '--force'])
-        cli(['config', 'set', 'mgr', 'mgr/cephadm/registry_username', ctx.registry_username, '--force'])
-        cli(['config', 'set', 'mgr', 'mgr/cephadm/registry_password', ctx.registry_password, '--force'])
+        registry_credentials = {'url': ctx.registry_url, 'username': ctx.registry_username, 'password': ctx.registry_password}
+        cli(['config-key', 'set', 'mgr/cephadm/registry_credentials', json.dumps(registry_credentials)])
 
     cli(['config', 'set', 'mgr', 'mgr/cephadm/container_init', str(ctx.container_init), '--force'])
 
index 35c7f371c0ada7127a7b378a1d4a551d498dccaf..f4a3056b2f00140f414be29589bda4dc4480d5e4 100644 (file)
@@ -12,7 +12,7 @@ from orchestrator import OrchestratorError, DaemonDescription
 if TYPE_CHECKING:
     from .module import CephadmOrchestrator
 
-LAST_MIGRATION = 4
+LAST_MIGRATION = 5
 
 logger = logging.getLogger(__name__)
 
@@ -72,6 +72,10 @@ class Migrations:
             if self.migrate_3_4():
                 self.set(4)
 
+        if self.mgr.migration_current == 4:
+            if self.migrate_4_5():
+                self.set(5)
+
     def migrate_0_1(self) -> bool:
         """
         Migration 0 -> 1
@@ -279,6 +283,38 @@ class Migrations:
             )
         return True
 
+    def migrate_4_5(self) -> bool:
+        registry_url = self.mgr.get_module_option('registry_url')
+        registry_username = self.mgr.get_module_option('registry_username')
+        registry_password = self.mgr.get_module_option('registry_password')
+        if registry_url and registry_username and registry_password:
+
+            registry_credentials = {'url': registry_url,
+                                    'username': registry_username, 'password': registry_password}
+            self.mgr.set_store('registry_credentials', json.dumps(registry_credentials))
+
+            self.mgr.set_module_option('registry_url', None)
+            self.mgr.check_mon_command({
+                'prefix': 'config rm',
+                'who': 'mgr',
+                'key': 'mgr/cephadm/registry_url',
+            })
+            self.mgr.set_module_option('registry_username', None)
+            self.mgr.check_mon_command({
+                'prefix': 'config rm',
+                'who': 'mgr',
+                'key': 'mgr/cephadm/registry_username',
+            })
+            self.mgr.set_module_option('registry_password', None)
+            self.mgr.check_mon_command({
+                'prefix': 'config rm',
+                'who': 'mgr',
+                'key': 'mgr/cephadm/registry_password',
+            })
+
+            self.mgr.log.info('Done migrating registry login info')
+        return True
+
 
 def queue_migrate_nfs_spec(mgr: "CephadmOrchestrator", spec_dict: Dict[Any, Any]) -> None:
     """
index 250d477a76fb1b3dd8dc30868bb04994d34da528..0b7a3edd2f8e72badd6ec3f6f370ce2a24ab3c44 100644 (file)
@@ -297,6 +297,7 @@ class CephadmOrchestrator(orchestrator.Orchestrator, MgrModule,
             default='*',
             desc='PlacementSpec describing on which hosts to manage /etc/ceph/ceph.conf',
         ),
+        # not used anymore
         Option(
             'registry_url',
             type='str',
@@ -315,6 +316,7 @@ class CephadmOrchestrator(orchestrator.Orchestrator, MgrModule,
             default=None,
             desc='Custom repository password'
         ),
+        ####
         Option(
             'registry_insecure',
             type='bool',
@@ -923,14 +925,12 @@ class CephadmOrchestrator(orchestrator.Orchestrator, MgrModule,
         if not (url and username and password) and (inbuf is None or len(inbuf) == 0):
             return -errno.EINVAL, "", ("Invalid arguments. Please provide arguments <url> <username> <password> "
                                        "or -i <login credentials json file>")
-        elif not (url and username and password):
+        elif (url and username and password):
+            registry_json = {'url': url, 'username': username, 'password': password}
+        else:
             assert isinstance(inbuf, str)
-            login_info = json.loads(inbuf)
-            if "url" in login_info and "username" in login_info and "password" in login_info:
-                url = login_info["url"]
-                username = login_info["username"]
-                password = login_info["password"]
-            else:
+            registry_json = json.loads(inbuf)
+            if "url" not in registry_json or "username" not in registry_json or "password" not in registry_json:
                 return -errno.EINVAL, "", ("json provided for custom registry login did not include all necessary fields. "
                                            "Please setup json file as\n"
                                            "{\n"
@@ -938,6 +938,7 @@ class CephadmOrchestrator(orchestrator.Orchestrator, MgrModule,
                                            " \"username\": \"REGISTRY_USERNAME\",\n"
                                            " \"password\": \"REGISTRY_PASSWORD\"\n"
                                            "}\n")
+
         # verify login info works by attempting login on random host
         host = None
         for host_name in self.inventory.keys():
@@ -945,14 +946,12 @@ class CephadmOrchestrator(orchestrator.Orchestrator, MgrModule,
             break
         if not host:
             raise OrchestratorError('no hosts defined')
-        r = CephadmServe(self)._registry_login(host, url, username, password)
+        r = CephadmServe(self)._registry_login(host, registry_json)
         if r is not None:
             return 1, '', r
         # if logins succeeded, store info
         self.log.debug("Host logins successful. Storing login info.")
-        self.set_module_option('registry_url', url)
-        self.set_module_option('registry_username', username)
-        self.set_module_option('registry_password', password)
+        self.set_store('registry_credentials', json.dumps(registry_json))
         # distribute new login info to all hosts
         self.cache.distribute_new_registry_login_info()
         return 0, "registry login scheduled", ''
index 482456a3903e5bfca601a68fe548c8be7e1c4873..939b50bd30b9abdff01e46296b0bd0611937efe3 100644 (file)
@@ -205,10 +205,10 @@ class CephadmServe:
                 if r:
                     failures.append(r)
 
-            if self.mgr.cache.host_needs_registry_login(host) and self.mgr.registry_url:
+            if self.mgr.cache.host_needs_registry_login(host) and self.mgr.get_store('registry_credentials'):
                 self.log.debug(f"Logging `{host}` into custom registry")
-                r = self._registry_login(host, self.mgr.registry_url,
-                                         self.mgr.registry_username, self.mgr.registry_password)
+                r = self._registry_login(
+                    host, json.loads(str(self.mgr.get_store('registry_credentials'))))
                 if r:
                     bad_hosts.append(r)
 
@@ -1093,8 +1093,8 @@ class CephadmServe:
                     eca = None
 
                 if self.mgr.cache.host_needs_registry_login(daemon_spec.host) and self.mgr.registry_url:
-                    self._registry_login(daemon_spec.host, self.mgr.registry_url,
-                                         self.mgr.registry_username, self.mgr.registry_password)
+                    self._registry_login(daemon_spec.host,
+                                         json.loads(str(self.mgr.get_store('registry_credentials'))))
 
                 self.log.info('%s daemon %s on %s' % (
                     'Reconfiguring' if reconfig else 'Deploying',
@@ -1325,8 +1325,8 @@ class CephadmServe:
         if not host:
             raise OrchestratorError('no hosts defined')
         if self.mgr.cache.host_needs_registry_login(host) and self.mgr.registry_url:
-            self._registry_login(host, self.mgr.registry_url,
-                                 self.mgr.registry_username, self.mgr.registry_password)
+            self._registry_login(host,
+                                 json.loads(str(self.mgr.get_store('registry_credentials'))))
 
         pullargs: List[str] = []
         if self.mgr.registry_insecure:
@@ -1343,19 +1343,15 @@ class CephadmServe:
         return r
 
     # function responsible for logging single host into custom registry
-    def _registry_login(self, host: str, url: Optional[str], username: Optional[str], password: Optional[str]) -> Optional[str]:
-        self.log.debug(f"Attempting to log host {host} into custom registry @ {url}")
+    def _registry_login(self, host: str, registry_json: Dict[str, str]) -> Optional[str]:
+        self.log.debug(
+            f"Attempting to log host {host} into custom registry @ {registry_json['url']}")
         # want to pass info over stdin rather than through normal list of args
-        args_str = json.dumps({
-            'url': url,
-            'username': username,
-            'password': password,
-        })
         out, err, code = self._run_cephadm(
             host, 'mon', 'registry-login',
-            ['--registry-json', '-'], stdin=args_str, error_ok=True)
+            ['--registry-json', '-'], stdin=json.dumps(registry_json), error_ok=True)
         if code:
-            return f"Host {host} failed to login to {url} as {username} with given password"
+            return f"Host {host} failed to login to {registry_json['url']} as {registry_json['username']} with given password"
         return None
 
     def _deploy_cephadm_binary(self, host: str) -> None:
index 3bd67695438b0562daf064d246cab20adc7cf6a2..0cefe8c9bf84086188e461a89ca97f8e2db68442 100644 (file)
@@ -1550,9 +1550,8 @@ class TestCephadm(object):
     @mock.patch("cephadm.serve.CephadmServe._run_cephadm")
     def test_registry_login(self, _run_cephadm, cephadm_module: CephadmOrchestrator):
         def check_registry_credentials(url, username, password):
-            assert cephadm_module.get_module_option('registry_url') == url
-            assert cephadm_module.get_module_option('registry_username') == username
-            assert cephadm_module.get_module_option('registry_password') == password
+            assert json.loads(cephadm_module.get_store('registry_credentials')) == {
+                'url': url, 'username': username, 'password': password}
 
         _run_cephadm.return_value = '{}', '', 0
         with with_host(cephadm_module, 'test'):