Example #1
0
    def delete(self, cascade=False):
        if self.name is None:
            raise SyntaxError('K8sObject: name: [ {0} ] must be set to DELETE the object.'.format(self.name))

        url = '{base}/{name}'.format(base=self.base_url, name=self.name)

        delete_opts = DeleteOptions()
        delete_opts.orphan_dependents = not cascade

        state = self.request(method='DELETE', url=url, data=delete_opts.serialize())

        if not state.get('success'):
            status = state.get('status', '')
            reason = state.get('data', dict()).get('message', None)
            message = 'K8sObject: DELETE failed: HTTP {0} : {1}'.format(status, reason)
            if int(status) == 404:
                raise NotFoundException(message)
            raise BadRequestException(message)

        if state.get('success'):
            start_time = time.time()
            try:
                while True:
                    time.sleep(0.2)
                    self.get_model()
                    elapsed_time = time.time() - start_time
                    if elapsed_time >= self.DELETE_TIMEOUT_SECONDS:
                        raise TimedOutException("Timed out on DELETE object: [ {0} ]".format(self.name))
            except NotFoundException:
                pass

        return self
Example #2
0
    def delete(self, cascade=False):
        if self.name is None:
            raise SyntaxError('K8sObject: name: [ {0} ] must be set to DELETE the object.'.format(self.name))

        url = '{base}/{name}'.format(base=self.base_url, name=self.name)

        delete_opts = DeleteOptions()
        delete_opts.orphan_dependents = not cascade

        state = self.request(method='DELETE', url=url, data=delete_opts.serialize())

        if not state.get('success'):
            status = state.get('status', '')
            reason = state.get('data', dict()).get('message', None)
            message = 'K8sObject: DELETE failed: HTTP {0} : {1}'.format(status, reason)
            if int(status) == 404:
                raise NotFoundException(message)
            raise BadRequestException(message)

        if state.get('success'):
            start_time = time.time()
            try:
                while True:
                    time.sleep(0.2)
                    self.get_model()
                    elapsed_time = time.time() - start_time
                    if elapsed_time >= self.DELETE_TIMEOUT_SECONDS:
                        raise TimedOutException("Timed out on DELETE object: [ {0} ]".format(self.name))
            except NotFoundException:
                pass

        return self
Example #3
0
    def __init__(self, config=None, name=None, obj_type=None):

        if config is not None and not isinstance(config, K8sConfig):
            raise SyntaxError('K8sObject: config: [ {0} ] must be of type K8sConfig.'.format(config.__class__.__name__))
        if config is None:
            config = K8sConfig()
        self.config = config

        if name is None:
            raise SyntaxError('K8sObject: name: [ {0} ] cannot be None.'.format(name))
        if not isinstance(name, str):
            raise SyntaxError('K8sObject: name: [ {0} ] must be a string.'.format(name.__class__.__name__))

        if obj_type is None or not isinstance(obj_type, str):
            raise SyntaxError('K8sObject: obj_type: [ {0} ] must be a string.'.format(obj_type.__class__.__name__))

        if obj_type not in VALID_K8s_OBJS:
            valid = ", ".join(VALID_K8s_OBJS)
            raise SyntaxError('K8sObject: obj_type: [ {0} ] must be in: [ {1} ]'.format(obj_type, valid))

        self.obj_type = obj_type
        self.name = name
        self.model = BaseModel()

        try:
            urls = BaseUrls(version=self.config.version, namespace=self.config.namespace)
            self.base_url = urls.get_base_url(object_type=obj_type)
        except:
            raise Exception('Could not set BaseUrl for type: [ {0} ]'.format(obj_type))
Example #4
0
    def __init__(self, config=None, obj_type=None, name=None):
        valid_objects = ['Pod', 'ReplicationController', 'Secret', 'Service']
        if config is None:
            self.config = K8sConfig()
        else:
            try:
                assert isinstance(config, K8sConfig)
                self.config = config
            except:
                raise SyntaxError('Please define config as a K8sConfig object.')
        if obj_type is None or not isinstance(obj_type, str):
            raise SyntaxError('Please define obj_type as a string.')
        if obj_type not in valid_objects:
            raise SyntaxError('Please make sure object type is in: {my_type}'.format(my_type=', '.join(valid_objects)))
        else:
            self.obj_type = obj_type

        self.name = name

        self.model = BaseModel()
        assert isinstance(self.model, BaseModel)

        try:
            self.base_url = BaseUrls(namespace=self.config.get_namespace()).get_base_url(object_type=obj_type)
        except:
            raise Exception('Cannot import version specific classes')
Example #5
0
 def delete(self):
     if self.name is None:
         raise Exception('Cannot create object without name set first.')
     this_url = '{base}/{name}'.format(base=self.base_url, name=self.name)
     self.model = DeleteOptions(kind='DeleteOptions')
     state = self.request(method='DELETE', url=this_url, data=self.model.get())
     if not state.get('success'):
         message = 'Failed to delete object: {http_data}'\
             .format(http_data=state.get('data', dict()).get('message', None))
         raise Exception(message)
     return self
Example #6
0
    def delete(self):
        if self.name is None:
            raise SyntaxError('K8sObject: name: [ {0} ] must be set to DELETE the object.'.format(self.name))

        url = '{base}/{name}'.format(base=self.base_url, name=self.name)
        self.model = DeleteOptions(kind='DeleteOptions')
        state = self.request(method='DELETE', url=url, data=self.model.get())

        if not state.get('success'):
            status = state.get('status', '')
            reason = state.get('data', dict()).get('message', None)
            message = 'K8sObject: DELETE failed: HTTP {0} : {1}'.format(status, reason)
            if status == 404:
                raise NotFoundException(message)
            raise BadRequestException(message)

        return self
Example #7
0
class K8sObject(object):

    def __init__(self, config=None, name=None, obj_type=None):

        if config is not None and not isinstance(config, K8sConfig):
            raise SyntaxError('K8sObject: config: [ {0} ] must be of type K8sConfig.'.format(config.__class__.__name__))
        if config is None:
            config = K8sConfig()
        self.config = config

        if name is None:
            raise SyntaxError('K8sObject: name: [ {0} ] cannot be None.'.format(name))
        if not isinstance(name, str):
            raise SyntaxError('K8sObject: name: [ {0} ] must be a string.'.format(name.__class__.__name__))

        if obj_type is None or not isinstance(obj_type, str):
            raise SyntaxError('K8sObject: obj_type: [ {0} ] must be a string.'.format(obj_type.__class__.__name__))

        if obj_type not in VALID_K8s_OBJS:
            valid = ", ".join(VALID_K8s_OBJS)
            raise SyntaxError('K8sObject: obj_type: [ {0} ] must be in: [ {1} ]'.format(obj_type, valid))

        self.obj_type = obj_type
        self.name = name
        self.model = BaseModel()

        try:
            urls = BaseUrls(version=self.config.version, namespace=self.config.namespace)
            self.base_url = urls.get_base_url(object_type=obj_type)
        except:
            raise Exception('Could not set BaseUrl for type: [ {0} ]'.format(obj_type))

    def __str__(self):
        return "[ {0} ] named [ {1} ]. Model: [ {2} ]".format(self.obj_type, self.name, self.model.get())

    def as_dict(self):
        return self.model.get()

    def as_json(self):
        return json.dumps(self.model.get())

    def set_name(self, name):
        self.name = name
        if self.model is not None:
            my_method = getattr(self.model, "set_name", None)
            if callable(my_method):
                my_method(name=name)
        return self

    # ------------------------------------------------------------------------------------- remote API calls

    def request(self, method='GET', host=None, url=None, auth=None, cert=None, data=None, token=None, ca_cert=None):
        host = self.config.api_host if host is None else host
        url = self.base_url if url is None else url
        auth = self.config.auth if auth is None else auth
        cert = self.config.cert if cert is None else cert
        token = self.config.token if token is None else token
        ca_cert = self.config.ca_cert if ca_cert is None else ca_cert

        r = HttpRequest(
            method=method,
            host=host,
            url=url,
            auth=auth,
            cert=cert,
            ca_cert=ca_cert,
            data=data,
            token=token
        )
        return r.send()

    def list(self):
        state = self.request(method='GET')
        if not state.get('status'):
            raise Exception('Could not fetch list of objects of type: {this_type}.'.format(this_type=self.obj_type))
        return state.get('data', dict()).get('items', list())

    def get_model(self):
        if self.name is None:
            raise SyntaxError('K8sObject: name: [ {0} ] must be set to fetch the object.'.format(self.name))

        url = '{base}/{name}'.format(base=self.base_url, name=self.name)
        state = self.request(method='GET', url=url)

        if not state.get('success'):
            status = state.get('status', '')
            reason = state.get('data', dict()).get('message', None)
            message = 'K8sObject: GET [ {0}:{1} ] failed: HTTP {2} : {3} '.format(self.obj_type, self.name, status, reason)
            raise NotFoundException(message)

        model = state.get('data')
        return model

    def get_with_params(self, data=None):
        if data is None:
            raise SyntaxError('K8sObject: data: [ {0} ] cannot be None.'.format(data))
        if not isinstance(data, dict):
            raise SyntaxError('K8sObject: data: [ {0} ] must be a dict.'.format(data.__class__.__name__))

        url = '{base}'.format(base=self.base_url)
        state = self.request(method='GET', url=url, data=data)

        return state.get('data', None).get('items', list())

    def create(self):
        if self.name is None:
            raise SyntaxError('K8sObject: name: [ {0} ] must be set to CREATE the object.'.format(self.name))

        url = '{base}'.format(base=self.base_url)
        state = self.request(method='POST', url=url, data=self.model.get())

        if not state.get('success'):
            status = state.get('status', '')
            reason = state.get('data', dict()).get('message', None)
            message = 'K8sObject: CREATE failed : HTTP {0} : {1}'.format(status, reason)
            if int(status) == 422:
                raise UnprocessableEntityException(message)
            raise BadRequestException(message)

        return self

    def update(self):
        if self.name is None:
            raise SyntaxError('K8sObject: name: [ {0} ] must be set to UPDATE the object.'.format(self.name))

        url = '{base}/{name}'.format(base=self.base_url, name=self.name)
        state = self.request(method='PUT', url=url, data=self.model.get())

        if not state.get('success'):
            status = state.get('status', '')
            reason = state.get('data', dict()).get('message', None)
            message = 'K8sObject: UPDATE failed: HTTP {0} : {1}'.format(status, reason)
            raise BadRequestException(message)

        return self

    def delete(self):
        if self.name is None:
            raise SyntaxError('K8sObject: name: [ {0} ] must be set to DELETE the object.'.format(self.name))

        url = '{base}/{name}'.format(base=self.base_url, name=self.name)
        self.model = DeleteOptions(kind='DeleteOptions')
        state = self.request(method='DELETE', url=url, data=self.model.get())

        if not state.get('success'):
            status = state.get('status', '')
            reason = state.get('data', dict()).get('message', None)
            message = 'K8sObject: DELETE failed: HTTP {0} : {1}'.format(status, reason)
            if status == 404:
                raise NotFoundException(message)
            raise BadRequestException(message)

        return self
Example #8
0
class K8sObject(object):

    def __init__(self, config=None, name=None, obj_type=None):
        super(K8sObject, self).__init__()

        if config is not None and not isinstance(config, K8sConfig):
            raise SyntaxError('K8sObject: config: [ {0} ] must be of type K8sConfig.'.format(config.__class__.__name__))
        if config is None:
            config = K8sConfig()
        self.config = config

        if name is None:
            raise SyntaxError('K8sObject: name: [ {0} ] cannot be None.'.format(name))
        if not isinstance(name, str):
            raise SyntaxError('K8sObject: name: [ {0} ] must be a string.'.format(name.__class__.__name__))

        if obj_type is None or not isinstance(obj_type, str):
            raise SyntaxError('K8sObject: obj_type: [ {0} ] must be a string.'.format(obj_type.__class__.__name__))

        if obj_type not in VALID_K8s_OBJS:
            valid = ", ".join(VALID_K8s_OBJS)
            raise SyntaxError('K8sObject: obj_type: [ {0} ] must be in: [ {1} ]'.format(obj_type, valid))

        self.obj_type = obj_type
        self.name = name
        self.model = BaseModel()

        try:
            urls = BaseUrls(api_version=self.config.version, namespace=self.config.namespace)
            self.base_url = urls.get_base_url(object_type=obj_type)
        except:
            raise Exception('Could not set BaseUrl for type: [ {0} ]'.format(obj_type))

    def __str__(self):
        return "{0}".format(self.model.get())

    def __eq__(self, other):
        # see https://github.com/kubernetes/kubernetes/blob/release-1.3/docs/design/identifiers.md
        if isinstance(other, self.__class__):
            # Uniquely name (via a name) an object across space.
            return self.config.namespace == other.config.namespace \
                   and self.name == other.name
        return NotImplemented

    # ------------------------------------------------------------------------------------- representations

    def as_dict(self):
        return self.model.get()

    def as_json(self):
        return json.dumps(self.model.get())

    # ------------------------------------------------------------------------------------- set name

    def set_name(self, name):
        self.name = name
        if self.model is not None:
            meth = getattr(self.model, "set_name", None)
            if callable(meth):
                meth(name=name)
        return self

    # ------------------------------------------------------------------------------------- remote API calls

    def request(self, method='GET', host=None, url=None, auth=None, cert=None,
                data=None, token=None, ca_cert=None, ca_cert_data=None):

        host = self.config.api_host if host is None else host
        url = self.base_url if url is None else url
        auth = self.config.auth if auth is None else auth
        cert = self.config.cert if cert is None else cert
        token = self.config.token if token is None else token
        ca_cert = self.config.ca_cert if ca_cert is None else ca_cert
        ca_cert_data = self.config.ca_cert_data if ca_cert_data is None else ca_cert_data

        r = HttpRequest(
            method=method,
            host=host,
            url=url,
            auth=auth,
            cert=cert,
            ca_cert=ca_cert,
            ca_cert_data=ca_cert_data,
            data=data,
            token=token
        )

        try:
            return r.send()
        except IOError as err:
            raise BadRequestException('K8sObject: IOError: {0}'.format(err))

    def list(self):
        state = self.request(method='GET')
        if not state.get('status'):
            raise Exception('K8sObject: Could not fetch list of objects of type: [ {0} ]'.format(self.obj_type))
        if not state.get('success'):
            status = state.get('status', '')
            state_data = state.get('data', dict())
            reason = state_data['message'] if 'message' in state_data else state_data
            message = 'K8sObject: CREATE failed : HTTP {0} : {1}'.format(status, reason)
            if int(status) == 401:
                raise UnauthorizedException(message)
            if int(status) == 409:
                raise AlreadyExistsException(message)
            if int(status) == 422:
                raise UnprocessableEntityException(message)
            raise BadRequestException(message)
        return state.get('data', dict()).get('items', list())

    def get_model(self):
        if self.name is None:
            raise SyntaxError('K8sObject: name: [ {0} ] must be set to fetch the object.'.format(self.name))

        url = '{base}/{name}'.format(base=self.base_url, name=self.name)
        state = self.request(method='GET', url=url)

        if not state.get('success'):
            status = state.get('status', '')
            reason = state.get('data', dict()).get('message', None)
            message = 'K8sObject: GET [ {0}:{1} ] failed: HTTP {2} : {3} '.format(self.obj_type, self.name, status, reason)
            raise NotFoundException(message)

        model = state.get('data')
        return model

    def get_with_params(self, data=None):
        if data is None:
            raise SyntaxError('K8sObject: data: [ {0} ] cannot be None.'.format(data))
        if not isinstance(data, dict):
            raise SyntaxError('K8sObject: data: [ {0} ] must be a dict.'.format(data.__class__.__name__))

        url = '{base}'.format(base=self.base_url)
        state = self.request(method='GET', url=url, data=data)
        return state.get('data', None).get('items', list())

    def create(self):
        if self.name is None:
            raise SyntaxError('K8sObject: name: [ {0} ] must be set to CREATE the object.'.format(self.name))

        url = '{base}'.format(base=self.base_url)
        state = self.request(method='POST', url=url, data=self.model.get())

        if not state.get('success'):
            status = state.get('status', '')
            state_data = state.get('data', dict())
            reason = state_data['message'] if 'message' in state_data else state_data
            message = 'K8sObject: CREATE failed : HTTP {0} : {1}'.format(status, reason)
            if int(status) == 401:
                raise UnauthorizedException(message)
            if int(status) == 409:
                raise AlreadyExistsException(message)
            if int(status) == 422:
                raise UnprocessableEntityException(message)
            raise BadRequestException(message)
        return self

    def update(self):
        if self.name is None:
            raise SyntaxError('K8sObject: name: [ {0} ] must be set to UPDATE the object.'.format(self.name))

        url = '{base}/{name}'.format(base=self.base_url, name=self.name)
        state = self.request(method='PUT', url=url, data=self.model.get())

        if not state.get('success'):
            status = state.get('status', '')
            reason = state.get('data', dict()).get('message', None)
            message = 'K8sObject: UPDATE failed: HTTP {0} : {1}'.format(status, reason)
            if int(status) == 404:
                raise NotFoundException(message)
            if int(status) == 422:
                raise UnprocessableEntityException(message)
            raise BadRequestException(message)

        return self

    def delete(self):
        if self.name is None:
            raise SyntaxError('K8sObject: name: [ {0} ] must be set to DELETE the object.'.format(self.name))

        url = '{base}/{name}'.format(base=self.base_url, name=self.name)
        self.model = DeleteOptions(kind='DeleteOptions')
        state = self.request(method='DELETE', url=url, data=self.model.get())

        if not state.get('success'):
            status = state.get('status', '')
            reason = state.get('data', dict()).get('message', None)
            message = 'K8sObject: DELETE failed: HTTP {0} : {1}'.format(status, reason)
            if int(status) == 404:
                raise NotFoundException(message)
            raise BadRequestException(message)

        return self
Example #9
0
class K8sObject(object):
    def __init__(self, config=None, obj_type=None, name=None):
        valid_objects = ['Pod', 'ReplicationController', 'Secret', 'Service']
        if config is None:
            self.config = K8sConfig()
        else:
            try:
                assert isinstance(config, K8sConfig)
                self.config = config
            except:
                raise SyntaxError('Please define config as a K8sConfig object.')
        if obj_type is None or not isinstance(obj_type, str):
            raise SyntaxError('Please define obj_type as a string.')
        if obj_type not in valid_objects:
            raise SyntaxError('Please make sure object type is in: {my_type}'.format(my_type=', '.join(valid_objects)))
        else:
            self.obj_type = obj_type

        self.name = name

        self.model = BaseModel()
        assert isinstance(self.model, BaseModel)

        try:
            self.base_url = BaseUrls(namespace=self.config.get_namespace()).get_base_url(object_type=obj_type)
        except:
            raise Exception('Cannot import version specific classes')

    def __str__(self):
        return "Kubernetes {obj_type} named {name}. Definition: {model}"\
            .format(obj_type=self.obj_type, name=self.name, model=self.model.get())

    def as_dict(self):
        return self.model.get()

    def as_json(self):
        return json.dumps(self.model.get())

    def get_name(self):
        return self.name

    def set_name(self, name):
        self.name = name
        if self.model is not None:
            my_method = getattr(self.model, "set_name", None)
            if callable(my_method):
                my_method(name=name)
        return self

    def request(self, method='GET', host=None, url=None, auth=None, data=None, token=None):
        # default parameters
        host = self.config.get_api_host() if host is None else host
        url = self.base_url if url is None else url
        auth = self.config.auth if auth is None else auth
        token = self.config.token if token is None else token

        return HttpRequest(method=method, host=host, url=url, auth=auth, data=data, token=token).send()

    def list(self):
        state = self.request(method='GET')
        if not state.get('status'):
            raise Exception('Could not fetch list of objects of type: {this_type}.'.format(this_type=self.obj_type))
        return state.get('data', dict()).get('items', list())

    def get_model(self):
        if self.name is None:
            raise Exception('Cannot fetch object without name set first.')
        this_url = '{base}/{name}'.format(base=self.base_url, name=self.name)
        state = self.request(method='GET', url=this_url)
        if state.get('success'):
            model = state.get('data')
        else:
            message = 'Failed to fetch object definition for {resource_type} {name}. HTTP-{code}'\
                .format(name=self.name, resource_type=self.obj_type, code=state.get('status', ''))
            raise NotFoundException(message)
        return model

    def get_with_params(self, data):
        if not isinstance(data, dict):
            raise SyntaxError('data must be a dict of parameters to be encoded in the URL.')
        this_url = '{base}'.format(base=self.base_url)
        state = self.request(method='GET', url=this_url, data=data)
        return state.get('data', None).get('items', list())

    def create(self):
        if self.name is None:
            raise Exception('Cannot create object without name set first.')
        this_url = '{base}'.format(base=self.base_url)
        state = self.request(method='POST', url=this_url, data=self.model.get())
        if not state.get('success'):
            message = 'Failed to create object: HTTP-{code} {http_data}'\
                .format(code=state.get('status', ''), http_data=state.get('data', dict()).get('message', None))
            if int(state.get('status', 0)) == 422:
                raise UnprocessableEntityException(message)
            else:
                raise Exception(message)
        return self

    def update(self):
        if self.name is None:
            raise Exception('Cannot create object without name set first.')
        this_url = '{base}/{name}'.format(base=self.base_url, name=self.name)
        state = self.request(method='PUT', url=this_url, data=self.model.get())
        if not state.get('success'):
            message = 'Failed to update object: {http_data}'\
                .format(http_data=state.get('data', dict()).get('message', None))
            raise Exception(message)
        return self

    def delete(self):
        if self.name is None:
            raise Exception('Cannot create object without name set first.')
        this_url = '{base}/{name}'.format(base=self.base_url, name=self.name)
        self.model = DeleteOptions(kind='DeleteOptions')
        state = self.request(method='DELETE', url=this_url, data=self.model.get())
        if not state.get('success'):
            message = 'Failed to delete object: {http_data}'\
                .format(http_data=state.get('data', dict()).get('message', None))
            raise Exception(message)
        return self