예제 #1
0
 def handler(self, obj, namespace=None):
     apiver, kind, _ = validator.validate(obj)
     if kind == 'Template':
         return self._process_template(apiver, kind, action, obj,
                                       namespace)
     else:
         return func(self, obj, namespace)
예제 #2
0
    def create(self, obj, namespace=DEFAULT_NAMESPACE):
        """Create an object from the Kubernetes cluster."""
        apiver, kind, name = validator.validate(obj)
        namespace = validator.check_namespace(obj, namespace)
        url = self._generate_url(apiver, kind, namespace)

        resp = self.request('post', url, data=obj)

        logger.info('%s `%s` successfully created', kind.capitalize(), name)

        return resp
예제 #3
0
    def replace(self, obj, namespace=DEFAULT_NAMESPACE):
        """Replace a resource on the Kubernetes cluster."""
        apiver, kind, name = validator.validate(obj)
        namespace = validator.check_namespace(obj, namespace)
        url = self._generate_url(apiver, kind, namespace, name)

        resp = self.request('put', url, data=obj)

        logger.info('%s `%s` successfully replaced', kind.capitalize(), name)

        return resp
예제 #4
0
    def _process_template(self, apiver, kind, method, obj, namespace):
        url = self._generate_url(apiver, kind, namespace)
        data = self.request('post', url, data=obj) or {}

        for o in data.get('objects', []):
            apiver, kind, name = validator.validate(o)
            object_url = self._generate_url(apiver, kind, namespace)
            self.request(method, object_url, data=o)
            logger.debug('%sd template object: %s', method, name)

        logger.debug('Processed template with %d objects successfully',
                     len(data.get('objects', [])))
        return data
예제 #5
0
    def test_create_replace_modify(self):
        try:
            self.client.create(SIMPLE_POD, NAMESPACE)
            self.client.modify(PATCH_POD, NAMESPACE)

            # give the scheduler a chance to complete the scheduling
            # so that the server side content stablizes otherwise
            # there will be a 409 or 422 related error.
            time.sleep(5)
            apiver, kind, name = validator.validate(SIMPLE_POD)
            url = self.client._generate_url(apiver, kind, NAMESPACE, name)
            obj = self.client.request('get', url)
            print(json.dumps(obj))
            obj['metadata']['labels'].update(REPLACE_POD)
            print(json.dumps(obj))
            self.client.replace(obj, NAMESPACE)
        except Exception as err:
            self.fail('replace/modify pod failed unexpectedly: {}'.format(err))
예제 #6
0
    def modify(self, partial, namespace=DEFAULT_NAMESPACE):
        """Modify a resource.

        The partial object provided will be strategically merged with the existing
        resource content. The top level meta data is required to enable modifying
        the correct resource instance.

        :param dict partial: changes to be applied to existing resource content
        :param str namespace: object name and auth scope, such as for teams and projects
        """
        apiver, kind, name = validator.validate(partial)
        namespace = validator.check_namespace(partial, namespace)
        url = self._generate_url(apiver, kind, namespace, name)

        headers = {'Content-Type': 'application/strategic-merge-patch+json'}
        resp = self.request('patch', url, data=partial, headers=headers)

        logger.info('%s `%s` successfully modified', kind.capitalize(), name)

        return resp
예제 #7
0
    def scale(self, obj, namespace=DEFAULT_NAMESPACE, replicas=0):
        """Scale replicas up or down.

        By default we scale back down to 0. This function takes an object and scales said
        object down to a specified value on the Kubernetes cluster

        :param dict obj: Object of the artifact being modified
        :param str namesapce: Namespace of the kubernetes cluster to be used
        :param int replicas: Default 0, size of the amount of replicas to scale
        """
        apiver, kind, name = validator.validate(obj)
        namespace = validator.check_namespace(obj, namespace)
        url = self._generate_url(apiver, kind, namespace, name)

        headers = {'Content-Type': 'application/json-patch+json'}
        patch = [{
            'op': 'replace',
            'path': '/spec/replicas',
            'value': replicas
        }]
        self.request('patch', url, data=patch, headers=headers)

        logger.info('`%s` successfully scaled to %s', name, replicas)
예제 #8
0
    def delete(self, obj, namespace=DEFAULT_NAMESPACE):
        """Delete an object from the Kubernetes cluster.

        .. note::

            Replication controllers must scale to 0 in order to delete pods.
            Kubernetes 1.3 will implement server-side cascading deletion, but
            until then, it's mandatory to scale to 0
            https://github.com/kubernetes/kubernetes/blob/master/docs/proposals/garbage-collection.md

        :param dict obj: Object of the artifact being modified
        :param str namesapce: Namespace of the kubernetes cluster to be used
        """
        apiver, kind, name = validator.validate(obj)
        namespace = validator.check_namespace(obj, namespace)
        url = self._generate_url(apiver, kind, namespace, name)

        if kind in ['ReplicationController']:
            self.scale(obj, namespace)
        resp = self.request('delete', url)

        logger.info('%s `%s` successfully deleted', kind.capitalize(), name)

        return resp
예제 #9
0
 def test_validate_no_object(self):
     with self.assertRaises(KubeShiftError):
         validator.validate(None)
예제 #10
0
 def test_validate_success(self):
     api_version, kind, name = validator.validate(
         {'apiVersion': 'v1', 'kind': 'Pod', 'metadata': {'name': 'test'}})
     self.assertEqual(api_version, 'v1')
     self.assertEqual(kind, 'Pod')
     self.assertEqual(name, 'test')
예제 #11
0
 def test_validate_no_metadata_name_attr(self):
     with self.assertRaises(KubeShiftError):
         validator.validate({'apiVersion': 'v1', 'kind': 'Pod'})
예제 #12
0
 def test_validate_no_kind_attr(self):
     with self.assertRaises(KubeShiftError):
         validator.validate({'apiVersion': 'v1'})
예제 #13
0
 def test_validate_no_version_attr(self):
     with self.assertRaises(KubeShiftError):
         validator.validate({'kind': 'Pod'})
예제 #14
0
 def test_validate_not_dict(self):
     with self.assertRaises(KubeShiftError):
         validator.validate('')