Merge "Add ca-rotate command to magnumclient"
This commit is contained in:
		@@ -126,11 +126,14 @@ class Manager(object):
 | 
				
			|||||||
        data = self._format_body_data(body, response_key)
 | 
					        data = self._format_body_data(body, response_key)
 | 
				
			||||||
        return [obj_class(self, res, loaded=True) for res in data if res]
 | 
					        return [obj_class(self, res, loaded=True) for res in data if res]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _update(self, url, body, method='PATCH', response_key=None):
 | 
					    def _update(self, url, body=None, method='PATCH', response_key=None):
 | 
				
			||||||
        resp, body = self.api.json_request(method, url, body=body)
 | 
					 | 
				
			||||||
        # PATCH/PUT requests may not return a body
 | 
					 | 
				
			||||||
        if body:
 | 
					        if body:
 | 
				
			||||||
            return self.resource_class(self, body)
 | 
					            resp, resp_body = self.api.json_request(method, url, body=body)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            resp, resp_body = self.api.raw_request(method, url)
 | 
				
			||||||
 | 
					        # PATCH/PUT requests may not return a body
 | 
				
			||||||
 | 
					        if resp_body:
 | 
				
			||||||
 | 
					            return self.resource_class(self, resp_body)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _delete(self, url):
 | 
					    def _delete(self, url):
 | 
				
			||||||
        self.api.raw_request('DELETE', url)
 | 
					        self.api.raw_request('DELETE', url)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -398,6 +398,11 @@ class ResponseBodyIterator(object):
 | 
				
			|||||||
        while True:
 | 
					        while True:
 | 
				
			||||||
            yield self.next()
 | 
					            yield self.next()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __bool__(self):
 | 
				
			||||||
 | 
					        return hasattr(self, 'items')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    __nonzero__ = __bool__  # Python 2.x compatibility
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def next(self):
 | 
					    def next(self):
 | 
				
			||||||
        chunk = self.resp.read(CHUNKSIZE)
 | 
					        chunk = self.resp.read(CHUNKSIZE)
 | 
				
			||||||
        if chunk:
 | 
					        if chunk:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,6 +52,10 @@ fake_responses = {
 | 
				
			|||||||
        'GET': (
 | 
					        'GET': (
 | 
				
			||||||
            {},
 | 
					            {},
 | 
				
			||||||
            CERT1
 | 
					            CERT1
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        'PATCH': (
 | 
				
			||||||
 | 
					            {},
 | 
				
			||||||
 | 
					            None,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -102,3 +106,10 @@ class CertificateManagerTest(testtools.TestCase):
 | 
				
			|||||||
                                 ','.join(certificates.CREATION_ATTRIBUTES)),
 | 
					                                 ','.join(certificates.CREATION_ATTRIBUTES)),
 | 
				
			||||||
                                self.mgr.create, **create_cert_fail)
 | 
					                                self.mgr.create, **create_cert_fail)
 | 
				
			||||||
        self.assertEqual([], self.api.calls)
 | 
					        self.assertEqual([], self.api.calls)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_rotate_ca(self):
 | 
				
			||||||
 | 
					        self.mgr.rotate_ca(cluster_uuid=CERT1['cluster_uuid'])
 | 
				
			||||||
 | 
					        expect = [
 | 
				
			||||||
 | 
					            ('PATCH', '/v1/certificates/%s' % CERT1['cluster_uuid'], {}, None)
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					        self.assertEqual(expect, self.api.calls)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -142,3 +142,17 @@ class ShellTest(shell_test_base.TestCommandLineArgument):
 | 
				
			|||||||
                          _error_msg)
 | 
					                          _error_msg)
 | 
				
			||||||
        mock_cert_get.assert_not_called()
 | 
					        mock_cert_get.assert_not_called()
 | 
				
			||||||
        mock_cluster_get.assert_not_called()
 | 
					        mock_cluster_get.assert_not_called()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @mock.patch('magnumclient.v1.clusters.ClusterManager.get')
 | 
				
			||||||
 | 
					    @mock.patch('magnumclient.v1.certificates.CertificateManager.rotate_ca')
 | 
				
			||||||
 | 
					    def test_ca_rotate(self, mock_rotate_ca, mock_cluster_get):
 | 
				
			||||||
 | 
					        mockcluster = mock.MagicMock()
 | 
				
			||||||
 | 
					        mockcluster.status = "CREATE_COMPLETE"
 | 
				
			||||||
 | 
					        mockcluster.uuid = "xxx"
 | 
				
			||||||
 | 
					        mock_cluster_get.return_value = mockcluster
 | 
				
			||||||
 | 
					        mock_rotate_ca.return_value = None
 | 
				
			||||||
 | 
					        self._test_arg_success('ca-rotate '
 | 
				
			||||||
 | 
					                               '--cluster xxx')
 | 
				
			||||||
 | 
					        expected_args = {}
 | 
				
			||||||
 | 
					        expected_args['cluster_uuid'] = mockcluster.uuid
 | 
				
			||||||
 | 
					        mock_rotate_ca.assert_called_once_with(**expected_args)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,3 +48,6 @@ class CertificateManager(base.Manager):
 | 
				
			|||||||
                raise exceptions.InvalidAttribute(
 | 
					                raise exceptions.InvalidAttribute(
 | 
				
			||||||
                    "Key must be in %s" % ",".join(CREATION_ATTRIBUTES))
 | 
					                    "Key must be in %s" % ",".join(CREATION_ATTRIBUTES))
 | 
				
			||||||
        return self._create(self._path(), new)
 | 
					        return self._create(self._path(), new)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def rotate_ca(self, **kwargs):
 | 
				
			||||||
 | 
					        return self._update(self._path(id=kwargs['cluster_uuid']))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -84,3 +84,16 @@ def do_ca_sign(cs, args):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    cert = cs.certificates.create(**opts)
 | 
					    cert = cs.certificates.create(**opts)
 | 
				
			||||||
    _show_cert(cert)
 | 
					    _show_cert(cert)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@utils.arg('--cluster',
 | 
				
			||||||
 | 
					           required=False,
 | 
				
			||||||
 | 
					           metavar='<cluster>',
 | 
				
			||||||
 | 
					           help=_('ID or name of the cluster.'))
 | 
				
			||||||
 | 
					def do_ca_rotate(cs, args):
 | 
				
			||||||
 | 
					    """Rotate the CA certificate for a bay or cluster to revoke access."""
 | 
				
			||||||
 | 
					    opts = {
 | 
				
			||||||
 | 
					        'cluster_uuid': _get_target_uuid(cs, args)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cs.certificates.rotate_ca(**opts)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user