Nir Soffer has uploaded a new change for review.

Change subject: ceph: Add option to clear other secrets
......................................................................

ceph: Add option to clear other secrets

Typically engine will add new secrets when activating a Cinder/Ceph
storage domain or when a user add new secret to an active domain. Engine
will remove secrets when deactivating a domain, moving the host to
maintenance, or when a user delete a secret form an active domain.

When host is unreachable when engine try to unregister secrets, the host
will contain stale or unneeded secrets. When the host becomes UP again,
engine would like to register all the secrets required for the current
active storage domains, and clear any other secret.

Change-Id: I476e5aa0bd4a48d1837de09c59597f180fa38823
Signed-off-by: Nir Soffer <[email protected]>
---
M client/vdsClient.py
M tests/vmSecretTests.py
M tests/vmfakelib.py
M vdsm/API.py
M vdsm/rpc/BindingXMLRPC.py
M vdsm/rpc/vdsmapi-schema.json
M vdsm/virt/secret.py
7 files changed, 39 insertions(+), 11 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/53/40853/1

diff --git a/client/vdsClient.py b/client/vdsClient.py
index 776cae1..57d4e1f 100755
--- a/client/vdsClient.py
+++ b/client/vdsClient.py
@@ -1909,10 +1909,12 @@
         return status['status']['code'], status['status']['message']
 
     def registerSecrets(self, args):
-        validateArgTypes(args, [str], requiredArgsNumber=1)
-        with open(args[0]) as f:
+        validateArgTypes(args, [str, utils.tobool], requiredArgsNumber=1)
+        filename = args[0]
+        clear = args[1] if len(args) > 1 else False
+        with open(filename) as f:
             secrets = json.load(f)
-        res = self.s.registerSecrets(secrets)
+        res = self.s.registerSecrets(secrets, clear)
         return res['status']['code'], res['status']['message']
 
     def unregisterSecrets(self, args):
@@ -2788,10 +2790,11 @@
                 'get VMs from external hypervisor'
             )),
         'registerSecrets': (serv.registerSecrets, (
-            '<secrets_file>',
+            '<secrets_file> [<clear>]',
             'Register libvirt secrets from file'
             'Arguments:',
             '    secrets_file:  file contaning secrets in json format',
+            '    clear:         if true, clear other registered secrets',
             'Example:',
             '    vdsClient -s 0 registerSecrets secrets.json',
         )),
diff --git a/tests/vmSecretTests.py b/tests/vmSecretTests.py
index bbde27a..147f13d 100644
--- a/tests/vmSecretTests.py
+++ b/tests/vmSecretTests.py
@@ -184,6 +184,18 @@
         virsec2 = self.connection.secrets[sec2["uuid"]]
         self.assertEqual(sec2["value"], virsec2.value)
 
+    def test_register_clear(self):
+        # Register 2 secrets
+        sec1 = make_secret()
+        secret.register([sec1])
+        sec2 = make_secret()
+        # Rgister new secret, clearing other
+        res = secret.register([sec2], clear=True)
+        self.assertEqual(res, response.success())
+        self.assertNotIn(sec1["uuid"], self.connection.secrets)
+        virsec2 = self.connection.secrets[sec2["uuid"]]
+        self.assertEqual(sec2["value"], virsec2.value)
+
     def test_register_libvirt_error(self):
         def fail(xml):
             raise vmfakelib.Error(libvirt.VIR_ERR_INTERNAL_ERROR)
diff --git a/tests/vmfakelib.py b/tests/vmfakelib.py
index ac78970..842cdf6 100644
--- a/tests/vmfakelib.py
+++ b/tests/vmfakelib.py
@@ -61,6 +61,9 @@
             raise Error(libvirt.VIR_ERR_NO_SECRET)
         return self.secrets[sec_uuid]
 
+    def listAllSecrets(self, flags=0):
+        return self.secrets.values()
+
     def domainEventRegisterAny(self, *arg):
         pass
 
@@ -79,6 +82,9 @@
     def undefine(self):
         del self.con.secrets[self.uuid]
 
+    def UUIDString(self):
+        return self.uuid
+
     def setValue(self, value):
         self.value = value
 
diff --git a/vdsm/API.py b/vdsm/API.py
index 517ab60..ff7adc4 100644
--- a/vdsm/API.py
+++ b/vdsm/API.py
@@ -1408,8 +1408,8 @@
         return v2v.convert_external_vm(uri, username, password, vminfo, jobid,
                                        self._cif.irs)
 
-    def registerSecrets(self, secrets):
-        return secret.register(secrets)
+    def registerSecrets(self, secrets, clear=False):
+        return secret.register(secrets, clear=clear)
 
     def unregisterSecrets(self, uuids):
         return secret.unregister(uuids)
diff --git a/vdsm/rpc/BindingXMLRPC.py b/vdsm/rpc/BindingXMLRPC.py
index 92e57cf..6b0ed30 100644
--- a/vdsm/rpc/BindingXMLRPC.py
+++ b/vdsm/rpc/BindingXMLRPC.py
@@ -368,9 +368,9 @@
         api = API.Global()
         return api.convertExternalVm(uri, username, password, vminfo, jobid)
 
-    def registerSecrets(self, secrets):
+    def registerSecrets(self, secrets, clear=False):
         api = API.Global()
-        return api.registerSecrets(secrets)
+        return api.registerSecrets(secrets, clear=clear)
 
     def unregisterSecrets(self, uuids):
         api = API.Global()
diff --git a/vdsm/rpc/vdsmapi-schema.json b/vdsm/rpc/vdsmapi-schema.json
index 94ac434..dd12a7d 100644
--- a/vdsm/rpc/vdsmapi-schema.json
+++ b/vdsm/rpc/vdsmapi-schema.json
@@ -3939,12 +3939,14 @@
 #
 # Register secrets with libvirt
 #
-# @secrets:     List of SecretInfo maps
+# @secrets:     List of secrets to register
+#
+# @clear:       #optional If true, unregister other registered secrets
 #
 # Since: 4.17.0
 ##
 {'command': {'class': 'Host', 'name': 'registerSecrets'},
-  'data': {'secrets': ['SecretInfo']}}
+  'data': {'secrets': ['SecretInfo'], '*clear': 'bool'}}
 
 ##
 # @Host.unregisterSecrets:
diff --git a/vdsm/virt/secret.py b/vdsm/virt/secret.py
index 7c805e0..d60061e 100644
--- a/vdsm/virt/secret.py
+++ b/vdsm/virt/secret.py
@@ -28,7 +28,7 @@
 from . import vmxml
 
 
-def register(secrets):
+def register(secrets, clear=False):
     try:
         secrets = [Secret(params) for params in secrets]
     except ValueError as e:
@@ -40,6 +40,11 @@
         for secret in secrets:
             logging.info("Registering secret %s", secret)
             secret.register(con)
+        if clear:
+            uuids = frozenset(sec.uuid for sec in secrets)
+            for virSecret in con.listAllSecrets():
+                if virSecret.UUIDString() not in uuids:
+                    virSecret.undefine()
     except libvirt.libvirtError as e:
         logging.error("Could not register secret %s: %s", secret, e)
         return response.error("secretRegisterErr")


-- 
To view, visit https://gerrit.ovirt.org/40853
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I476e5aa0bd4a48d1837de09c59597f180fa38823
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Nir Soffer <[email protected]>
_______________________________________________
vdsm-patches mailing list
[email protected]
https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches

Reply via email to