Ejemplo n.º 1
0
    def route(self, port=None, name=None, host=None):
        ports = self.xf_ports(self._data['ports'])
        if port is None and len(ports) == 1:
            port = ports[0]
        elif len(ports) == 0:
            raise UserError(
                ValueError("Can't create route on service with no ports!"))
        elif port is None:
            raise UserError(ValueError("Multiple ports available, pick one!"))
        elif Integer().do_check(port, None):
            for p in ports:
                if p._data['port'] == port or p._data['targetPort'] == port:
                    port = p
                    break
        elif String().do_check(port, None):
            for p in ports:
                if p._data['port'] == int(
                        port) or p._data['targetPort'] == int(port):
                    port = p
                    break
                if p._data['name'] == port:
                    port = p
                    break

        if not isinstance(port, ServicePort):
            raise UserError(
                TypeError(
                    "Unknown specification for port {}, please specify something consistent"
                    .format(port)))

        return router.Route(
            port=router.RouteDestPort(targetPort=port._data['name']),
            to=[router.RouteDestService(name=self.name)],
            name=name,
            host=host)
Ejemplo n.º 2
0
 def get_key(self, key):
     if self._data['type'] != 'Opaque':
         raise UserError(TypeError(
             "Can't create key object from non-'Opaque' (Secret) secret type (this is {})".format(self._data['type'])))
     if not key in self._data['secrets']:
         raise UserError(KeyError("Key {} doesn't exist in secret".format(key)))
     return SingleSecret(name=self._data['name'], namespace=self.namespace, key=key)
Ejemplo n.º 3
0
    def check(self, value, path=None):
        if isinstance(value, VarEntity):
            ret = self.do_check(value.validation_value(), path=path)
        else:
            ret = self.do_check(value, path=path)

        if not ret and hasattr(self, 'validation_text'):
            raise UserError(KubeTypeValidationError(value, self.name(), path, self.validation_text))
        elif not ret:
            raise UserError(KubeTypeValidationError(value, self.name(), path, 'Validation failed'))

        return ret
Ejemplo n.º 4
0
 def do_validate(self):
     if self._data['operator'] in ('In', 'NotIn'):
         if self._data['values'] is None or len(self._data['values']) == 0:
             raise UserError(
                 MatchExpressionInvalid(
                     'operator In/NotIn requires nonempty values'))
     else:
         if self._data['values'] is not None and len(
                 self._data['values']) != 0:
             raise UserError(
                 MatchExpressionInvalid(
                     'operator Exists/DoesNotExist requires empty values'))
     return True
Ejemplo n.º 5
0
    def parse_obj(cls, doc):
        if cls is not KubeObj:
            raise ValueError(".parse_obj should only be called as KubeObj.parse_obj(...)")

        if not isinstance(doc, dict) or 'kind' not in doc or 'apiVersion' not in doc:
            raise UserError(ValueError(
                "Document needs to be a dictionary with 'kind' and 'apiVersion' as top-level keys"))

        my_cls = cls.find_class_from_obj(doc)

        if my_cls is not None:
            return my_cls().parser(doc)

        raise UserError(ValueError(
            "Unknown document kind: {}, no corresponding rubiks object found".format(doc['kind'])))
Ejemplo n.º 6
0
    def to_string(self):
        if self._in_validation:
            return "command_output"

        env = {}
        if not self.env_clear:
            env.update(os.environ)
        if self.env is not None:
            for e in self.env:
                env[e] = str(self.env[e])

        p = subprocess.Popen(map(str, self.cmd), close_fds=True, shell=False, cwd=self.cwd, env=env,
                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)

        (out, err) = p.communicate()

        out = out.decode('utf8')
        err = err.decode('utf8')

        if len(err.strip()) != 0:
            print(err.rstrip(), file=sys.stderr)

        if self.rstrip:
            out = out.rstrip()
        if self.eol and out[-1] != '\n':
            out += '\n'

        if self.good_rc is None or rc in self.good_rc:
            return out

        raise UserError(CommandRuntimeException("Command {} ({}) exited with code rc={}".format(
                                                    self.cmd[0], ' '.join(self.cmd), p.returncode)))
Ejemplo n.º 7
0
    def clone(self, *args, **kwargs):
        ret = self._clone()
        ret._caller_file, ret._caller_line, ret._caller_fn = traceback.extract_stack(
            limit=2)[0][0:3]
        _rec_update_objs(self)

        if hasattr(self, 'identifier'
                   ) and len(args) > 0 and self.identifier not in kwargs:
            kwargs[self.identifier] = args[0]

        for k in kwargs:
            if self.has_metadata and k in ('annotations', 'labels'):
                setattr(self, k, kwargs[k])
                continue

            if k not in ret._data:
                raise UserError(
                    TypeError(
                        "{} is not a valid argument for {} constructor".format(
                            k, ret.__class__.__name__)))

            if not isinstance(kwargs[k], (list, dict)):
                ret._data[k] = kwargs[k]
            elif isinstance(kwargs[k], list):
                ret._data[k] = []
                ret._data[k].extend(kwargs[k])
            else:
                if not isinstance(ret._data[k], dict):
                    ret._data[k] = {}
                ret._data[k].update(kwargs[k])

        return ret
Ejemplo n.º 8
0
    def validate(self, path=None):
        if path is None:
            path = 'self'

        types = self.__class__.resolve_types()
        mapping = self.__class__._find_defaults('_map')

        if hasattr(self, 'labels'):
            Map(String, String).check(self.labels, '{}.(labels)'.format(path))
        if hasattr(self, 'annotations'):
            Map(String, String).check(self.annotations, '{}.(annotations)'.format(path))

        if not self.check_namespace():
            raise UserError(KubeObjNoNamespace("No namespace attached to object at {}".format(path)))

        data = self.xform()

        for k in types:
            if k in data:
                types[k].check(data[k], path + '.' + k)
            else:
                types[k].check(None, path + '.' + k)

        for k in data:
            if k not in types and k not in mapping:
                raise KubeTypeUnresolvable(
                    "Unknown data key {} - no type information".format(k))

        sav_data = self._data
        try:
            self._data = data
            return self.do_validate()
        finally:
            self._data = sav_data
Ejemplo n.º 9
0
    def __init__(self, collection, path):
        if path.basename == '' or path.basename.lower().strip(
                '0123456789abcdefghijklmnopqrstuvwxyz_') != '':
            raise UserError(
                ValueError(
                    "Filenames should be python compliant (alphanumeric and '_'), found: {}"
                    .format(path.basename)))

        if hasattr(self, 'extensions') and len(self.extensions) != 0:
            assert path.extension in self.extensions

        self.path = path
        self.collection = weakref.ref(collection)

        self.output_was_called = False
        self.default_import_args = {}

        self.import_exception = None

        if self.compile_in_init:
            save_cluster = KubeBaseObj._default_cluster
            try:
                KubeBaseObj._default_cluster = None
                self.module = self.do_compile()
            finally:
                KubeBaseObj._default_cluster = save_cluster
Ejemplo n.º 10
0
        def run_command(*cmd, **kwargs):
            args = {
                'cwd': None,
                'env_clear': False,
                'env': None,
                'delay': True,
                'ignore_rc': True,
                'rstrip': True,
                'eol': False
            }
            for k in kwargs:
                if k not in args:
                    raise UserError(
                        TypeError("{} isn't a valid argument to run_command()".
                                  format(k)))
            args.update(kwargs)

            cwd = None
            if args['cwd'] is not None:
                cwd = self.path.rel_path(args['cwd'])

            good_rc = None
            if not args['ignore_rc']:
                good_rc = (0, )
            cmd_ent = kube_vartypes.Command(cmd,
                                            cwd=cwd,
                                            env_clear=args['env_clear'],
                                            env=args['env'],
                                            good_rc=good_rc,
                                            rstrip=args['rstrip'],
                                            eol=args['eol'])
            if args['delay']:
                return cmd_ent
            else:
                return str(cmd_ent)
Ejemplo n.º 11
0
    def get_file_context(self, path):
        if path.extension is None:
            raise UserError(
                loader.LoaderFileNameError(
                    "Filenames must have an extension in {}".format(
                        path.full_path)))

        python_loader = self.__class__.get_python_file_type(path.extension)

        if python_loader is None:
            raise UserError(
                loader.LoaderFileNameError(
                    "No valid handler for extension {} in {}".format(
                        path.extension, path.full_path)))

        return self.get_or_add_file(path, python_loader, (self, path))
Ejemplo n.º 12
0
def get_ns(self, name):
    ret = _REG.get_id(Namespace, name)
    if ret is None:
        return Namespace(name)
    if len(ret) > 1:
        raise UserError(
            ValueError(
                "More than one namespace with name {} has been declared".
                format(name)))
    return ret[0]
Ejemplo n.º 13
0
    def get_multi_python(self,
                         py_context,
                         pattern='*',
                         basepath=None,
                         **kwargs):
        extensions = self.__class__.get_python_file_type(None)
        ret = {}

        if pattern is None:
            raise UserError(
                ValueError("get_multi_python(): pattern must be specified"))

        basep = None
        if basepath is not None:
            try:
                basep = py_context.path.rel_path(basepath)
            except AssertionError as e:
                raise UserError(
                    LoaderImportError(
                        'basepath specifiers in get_multi_python must be relative: {}'
                        .format(basepath)))

        for p in self.find_all_source_files():
            if basep is not None and os.path.relpath(
                    p.repo_rel_path, basep.repo_rel_path).startswith('..'):
                continue
            if p.extension is None:
                continue
            if p.extension not in extensions:
                continue
            if not fnmatch.fnmatchcase(p.filename, pattern) and \
                    not fnmatch.fnmatchcase(p.basename, pattern):
                continue

            self.add_dep(self.current_context[-1], p)

            try:
                ret[p.repo_rel_path] = self.get_file_context(p).get_module(
                    **kwargs)
            except loader.LoaderBaseException as e:
                handle_user_error(e)
        return ret
Ejemplo n.º 14
0
    def validate(cls, surge, unavailable):
        def check_zero(v):
            if v is None:
                return True

            return (String().do_check(v, None) and int(v[:-1]) == 0) or (v == 0)

        if check_zero(surge) and check_zero(unavailable):
            raise UserError(SurgeError("maxSurge and maxUnavailable cannot both be zero"))

        return True
Ejemplo n.º 15
0
    def __init__(self, *args, **kwargs):
        # put the identifier in if it's specified
        if hasattr(self, 'identifier'
                   ) and len(args) > 0 and self.identifier not in kwargs:
            kwargs[self.identifier] = args[0]
        self._data = self.__class__._find_defaults('_defaults')

        self._caller_file, self._caller_line, self._caller_fn = traceback.extract_stack(
            limit=2)[0][0:3]

        for k in self.__class__._find_defaults('_map'):
            self._data[k] = None

        self.namespace = None
        self.set_namespace(KubeBaseObj._default_ns)

        self._in_cluster = KubeBaseObj._default_cluster
        if '_no_add' not in kwargs or not kwargs['_no_add']:
            if hasattr(self, 'add_obj'):
                self.add_obj()

        if '_no_add' in kwargs:
            del kwargs['_no_add']

        if self.has_metadata:
            self.annotations = {}
            self.labels = {}

        if hasattr(self, 'early_init'):
            self.early_init(*args, **kwargs)

        for k in kwargs:
            if self.has_metadata and k in ('annotations', 'labels'):
                setattr(self, k, kwargs[k])
                continue

            if k not in self._data:
                raise UserError(
                    TypeError(
                        "{} is not a valid argument for {} constructor".format(
                            k, self.__class__.__name__)))

            if not isinstance(kwargs[k], (list, dict)):
                self._data[k] = kwargs[k]
            elif isinstance(kwargs[k], list):
                self._data[k] = []
                self._data[k].extend(kwargs[k])
            else:
                if not isinstance(self._data[k], dict):
                    self._data[k] = {}
                self._data[k].update(kwargs[k])

        _rec_update_objs(self)
Ejemplo n.º 16
0
def exec_saved(savedLines):
    saved_locals = get_starting_locals()
    try:
        exec(savedLines, saved_locals)
    except Exception:
        _, exc_obj, exc_tb = exc_info()
        raise UserError(exc_obj, exc_tb, saved_locals)

    # deepcopy cant handle imported modules, so remove them
    saved_locals = {k: v for k, v in saved_locals.items() if str(type(v)) != "<class 'module'>"}

    return saved_locals
Ejemplo n.º 17
0
    def check(self, value, path=None):
        if not isinstance(value, dict):
            raise UserError(KubeTypeValidationError(value, self.name(), path, "not a dictionary"))

        if path is None:
            path = 'self'

        for k in value.keys():
            self.key.check(k, path='{}[{}] (key)'.format(path, k))
            self.value.check(value[k], path='{}[{}]'.format(path, k))

        return True
Ejemplo n.º 18
0
    def get_file_context(self, path):
        try:
            self.current_context.append(path)
            if path.extension is None:
                raise UserError(
                    loader.LoaderFileNameError(
                        "Filenames must have an extension in {}".format(
                            path.full_path)))

            python_loader = self.__class__.get_python_file_type(path.extension)

            if python_loader is None:
                raise UserError(
                    loader.LoaderFileNameError(
                        "No valid handler for extension {} in {}".format(
                            path.extension, path.full_path)))

            return self.get_or_add_file(path, python_loader, (self, path))
        finally:
            assert self.current_context[-1] is path
            self.current_context.pop()
Ejemplo n.º 19
0
    def import_python(self, py_context, name, exports, **kwargs):
        path = self.import_check(py_context, name)

        self.debug(
            1, 'importing python {} ({} -> {})'.format(
                path.repo_rel_path, py_context.path.repo_rel_path, name))

        basename = path.basename
        if 'import_as' in kwargs and kwargs['import_as'] is not None:
            basename = kwargs['import_as']

        new_context = None
        try:
            new_context = self.get_file_context(path)

            if 'no_import' not in kwargs or not kwargs['no_import']:
                if 'no_import' in kwargs:
                    del kwargs['no_import']
                if 'import_as' in kwargs:
                    del kwargs['import_as']

                self.import_symbols(name, new_context.path, py_context.path,
                                    basename, new_context,
                                    py_context._current_module, exports,
                                    **kwargs)

            elif len(exports) != 0 or ('import_as' in kwargs
                                       and kwargs['import_as'] is not None):
                raise UserError(
                    ValueError(
                        "import_python: Can't set symbols to import to when using no_import"
                    ))

        except loader.LoaderBaseException as e:
            raise UserError(e)

        self.add_dep(py_context.path, path)
        return new_context
Ejemplo n.º 20
0
    def import_check(self, py_context, name, valid_exts=None):
        try:
            npath = py_context.path.rel_path(name)
        except AssertionError as e:
            raise UserError(
                LoaderImportError(
                    'path imports must be relative {} -> {}'.format(
                        py_context.path.src_rel_path, name)))
        if valid_exts is not None:
            if npath.extension not in valid_exts:
                raise UserError(
                    LoaderImportError(
                        'expected file extension in ({}), got .{}'.format(
                            ', '.join(valid_exts), npath.extension)))

        if not npath.exists():
            raise UserError(
                LoaderImportError(
                    'file {} -> {} imported from {} does not exist'.format(
                        npath.src_rel_path, npath.full_path,
                        py_context.path.src_rel_path)))

        return npath
Ejemplo n.º 21
0
    def add_user(self, v):
        if isinstance(v, User) and v.name not in self._data['users']:
            self._data['users'].append(v.name)

        elif isinstance(v, ServiceAccount):
            sa_name = 'system:serviceaccount:' + v.namespace.name + ':' + v.name
            if sa_name not in self._data['users']:
                self._data['users'].append(sa_name)

        elif SystemIdentifier.do_check(v, None):
            self._data['users'].append(v)

        else:
            raise UserError(TypeError("can't add {} to users".format(repr(v))))
Ejemplo n.º 22
0
def get_ns(self, name):
    try:
        from kube_objs import Namespace
        ret = _REG.get_id(Namespace, name)
        if ret is None:
            return Namespace(name)
        if len(ret) > 1:
            raise UserError(
                ValueError(
                    "More than one namespace with name {} has been declared".
                    format(name)))
        return ret[0]
    except ImportError:
        return None
Ejemplo n.º 23
0
    def get_branches(self, path):
        try:
            path = "" + path
        except:
            raise UserError(
                TypeError("Wrong type for path: expected str, got {}".format(
                    path.__class__.__name__)))

        if len(path) == 0:
            raise UserError(
                ValueError(
                    "path should not be empty string - use '.' for root"))

        if not self.has_data:
            return ()

        if path == '.':
            return tuple(sorted(self.data.keys()))

        path_c = self._resolve_path(path).split('.')
        ctx = self.data

        i = 0
        while i < len(path_c):
            if not isinstance(ctx, dict) or not path_c[i] in ctx:
                raise UserError(
                    KeyNotExist("branch {} ({}) doesn't exist in {}".format(
                        '.'.join(path_c[0:i]), path,
                        self._get_repo_rel_path())))

            ctx = ctx[path_c[i]]
            i += 1

        if isinstance(ctx, dict):
            return tuple(sorted(ctx.keys()))

        return ()
Ejemplo n.º 24
0
    def get_key(self, *args):
        e_txt = None
        for p in range(0, len(args)):
            last = False
            if p == len(args) - 1:
                last = True
            path = self._resolve_path(args[p])

            try:
                if self.is_confidential:
                    return Confidential(str(self._get_key(path, e_txt)))

                try:
                    ret = self._get_key(path, e_txt)
                except InvalidKey as e:
                    handle_user_error(e)

                if self.assert_type is not None and not isinstance(
                        ret, self.assert_type):
                    raise UserError(
                        TypeError("return value of {} is not {}".format(
                            path, self.assert_type)))

                return ret
            except Exception as e:
                e_txt = str(e)

                if last:
                    if self.default is not None:
                        if self.assert_type is not None and not isinstance(
                                self.default, self.assert_type):
                            raise UserError(
                                TypeError(
                                    "return value of {} is not {}".format(
                                        path, self.assert_type)))
                        return self.default
                    handle_user_error(e)
Ejemplo n.º 25
0
 def valid_clusters(*clusters):
     if len(clusters) == 0:
         raise UserError(
             ValueError(
                 "Must specify at least one cluster"))
     all_clusters = tuple(
         self.collection().repository.get_clusters())
     for cc in clusters:
         if cc not in all_clusters:
             print(
                 "WARN: valid_clusters() called with unknown cluster name: "
                 + cc,
                 file=sys.stderr)
     if c not in clusters:
         raise PythonStopCompile("stop")
Ejemplo n.º 26
0
    def check(self, value, path=None):
        if path is None:
            path = 'self'

        for t in self.types:
            try:
                if t.check(value, path):
                    return True
            except UserError as e:
                if not isinstance(e.exc, KubeTypeValidationError):
                    raise
            except KubeTypeValidationError:
                pass
        raise UserError(KubeTypeValidationError(value, self.name(), path,
                                                "couldn't match any possible types"))
Ejemplo n.º 27
0
 def update(self, **kwargs):
     bad_args = set()
     for k in kwargs:
         if k in self._data:
             continue
         if self.has_metadata and k in ('labels', 'annotations'):
             continue
         bad_args.add(k)
     if len(bad_args) != 0:
         raise UserError(KeyError("{} isn't/aren't attributes of {}".format(
             ', '.join(map(lambda x: "'{}'".format(x), sorted(bad_args))),
             self.__class__.__name__)))
     for k in kwargs:
         if k in self._data:
             self._data[k] = kwargs[k]
         else:
             self.__setattr__(k, kwargs[k])
Ejemplo n.º 28
0
    def check_for_dupes(self, op):
        ret = self._check_for_dupes(op)
        if ret is None:
            return

        new_obj = op.namespace_name + '/' + op.identifier
        orig_obj = new_obj
        if op.cluster is None:
            new_obj = "<all clusters>:" + new_obj
        else:
            new_obj = op.cluster + ":" + new_obj

        if ret[0] is None:
            orig_obj = "<all clusters>:" + orig_obj
        else:
            orig_obj = ret[0] + ":" + orig_obj

        raise UserError(RubiksOutputError("Duplicate (different) objects found: (orig) {}, (added) {}".format(orig_obj, new_obj)))
Ejemplo n.º 29
0
def copy_saved_imports_to_exec(codeToExec, savedLines):
    """
    copies imports in savedLines to the top of codeToExec.
    If savedLines is empty this function does nothing.
    :raises: SyntaxError if err in savedLines
    """
    if savedLines.strip() != "":
        try:
            saved_code_AST = ast.parse(savedLines)
        except SyntaxError:
            _, exc_obj, exc_tb = exc_info()
            raise UserError(exc_obj, exc_tb)

        imports = get_imports(saved_code_AST, savedLines)
        codeToExec = imports + "\n" + codeToExec

        # to make sure line # in errors is right we need to pad codeToExec with newlines
        numLinesToAdd = len(savedLines.split("\n")) - len(imports.split("\n"))
        for i in range(numLinesToAdd):
            codeToExec = "\n" + codeToExec

    return codeToExec
Ejemplo n.º 30
0
    def _find_user(self, user_id):
        """
        A function to return the class of the person.
        :param user_name: the user_name of the person calling
                          the borrower.
        :return: a class of the person.
        """
        # loops through all the users in self.user_list
        # and returns the class of the desired person.
        #TODO if there are two users with identical identifiers
        # the the last one will be returned - write in an exception
        # to give a proper error.

        # set a clicker that will show if the user has been found
        found_the_user = False

        for possible_user in self.available_users:
            # each user has an attribute that is a user id
            # and if it is the right one - return it
            
            if type(user_id) == int:
                if possible_user.user_id == user_id:
                    ret_val = possible_user
                    found_the_user = True
            if type(user_id) == str:
                if possible_user.name == user_id:
                    ret_val = possible_user
                    found_the_user = True

        if found_the_user:

            return ret_val

        else:

            raise UserError()