Exemplo n.º 1
0
    def invoke(self):
        try:
            doc_data = ReferenceResolver.resolve_reference(self.locations)
            documents = list()
            for d in doc_data:
                documents.extend(list(yaml.safe_load_all(d.decode())))
        except InvalidPathException as ex:
            self.logger.error(str(ex))
            return
        except yaml.YAMLError as yex:
            self.logger.error("Invalid YAML found: %s" % str(yex))
            return

        if not self.ctx.obj.get('api', False):
            with Tiller(tiller_host=self.tiller_host,
                        tiller_port=self.tiller_port,
                        tiller_namespace=self.tiller_namespace,
                        dry_run=self.dry_run) as tiller:
                armada = Armada(documents,
                                disable_update_pre=self.disable_update_pre,
                                disable_update_post=self.disable_update_post,
                                enable_chart_cleanup=self.enable_chart_cleanup,
                                dry_run=self.dry_run,
                                set_ovr=self.set,
                                force_wait=self.wait,
                                timeout=self.timeout,
                                tiller=tiller,
                                values=self.values,
                                target_manifest=self.target_manifest)

                resp = armada.sync()
                self.output(resp)
        else:
            if len(self.values) > 0:
                self.logger.error(
                    "Cannot specify local values files when using the API.")
                return

            query = {
                'disable_update_post': self.disable_update_post,
                'disable_update_pre': self.disable_update_pre,
                'dry_run': self.dry_run,
                'enable_chart_cleanup': self.enable_chart_cleanup,
                'tiller_host': self.tiller_host,
                'tiller_port': self.tiller_port,
                'tiller_namespace': self.tiller_namespace,
                'timeout': self.timeout,
                'wait': self.wait
            }

            client = self.ctx.obj.get('CLIENT')
            if self.use_doc_ref:
                resp = client.post_apply(manifest_ref=self.locations,
                                         set=self.set,
                                         query=query)
            else:
                resp = client.post_apply(manifest=documents,
                                         set=self.set,
                                         query=query)
            self.output(resp.get('message'))
Exemplo n.º 2
0
    def invoke(self):
        if not self.ctx.obj.get('api', False):
            doc_data = ReferenceResolver.resolve_reference(self.locations)
            documents = list()
            for d in doc_data:
                documents.extend(list(yaml.safe_load_all(d.decode())))

            manifest_obj = Manifest(documents).get_manifest()
            obj_check = validate_armada_object(manifest_obj)
            doc_check = validate_armada_documents(documents)

            try:
                if doc_check and obj_check:
                    self.logger.info('Successfully validated: %s',
                                     self.locations)
            except Exception:
                raise Exception('Failed to validate: %s', self.locations)
        else:
            if len(self.locations) > 1:
                self.logger.error("Cannot specify multiple locations "
                                  "when using validate API.")
                return

            client = self.ctx.obj.get('CLIENT')
            resp = client.post_validate(self.locations[0])

            if resp.get('code') == 200:
                self.logger.info('Successfully validated: %s', self.locations)
            else:
                self.logger.error("Failed to validate: %s", self.locations)
Exemplo n.º 3
0
    def on_post(self, req, resp):
        try:
            if req.content_type == 'application/json':
                self.logger.debug("Validating manifest based on reference.")
                json_body = self.req_json(req)
                if json_body.get('href', None):
                    self.logger.debug(
                        "Validating manifest from reference %s." %
                        json_body.get('href'))
                    data = ReferenceResolver.resolve_reference(
                        json_body.get('href'))
                    documents = list()
                    for d in data:
                        documents.extend(list(yaml.safe_load_all(d.decode())))
                else:
                    resp.status = falcon.HTTP_400
                    return
            else:
                manifest = self.req_yaml(req)
                documents = list(manifest)

            self.logger.debug("Validating set of %d documents." %
                              len(documents))

            result = validate_armada_documents(documents)

            resp.content_type = 'application/json'
            resp_body = {
                'kind': 'Status',
                'apiVersion': 'v1.0',
                'metadata': {},
                'reason': 'Validation',
                'details': {
                    'errorCount': 0,
                    'messageList': []
                },
            }

            if result:
                resp.status = falcon.HTTP_200
                resp_body['status'] = 'Success'
                resp_body['message'] = 'Armada validations succeeded'
                resp_body['code'] = 200
            else:
                resp.status = falcon.HTTP_400
                resp_body['status'] = 'Failure'
                resp_body['message'] = 'Armada validations failed'
                resp_body['code'] = 400
                resp_body['details']['errorCount'] = 1
                resp_body['details']['messageList'].\
                    append(dict(message='Validation failed.', error=True))

            resp.body = json.dumps(resp_body)
        except Exception as ex:
            err_message = 'Failed to validate Armada Manifest'
            self.logger.error(err_message, exc_info=ex)
            self.return_error(resp, falcon.HTTP_400, message=err_message)
Exemplo n.º 4
0
    def on_post(self, req, resp):
        # Load data from request and get options
        if req.content_type == 'application/x-yaml':
            data = list(self.req_yaml(req))
            if type(data[0]) is list:
                documents = list(data[0])
            else:
                documents = data
        elif req.content_type == 'application/json':
            self.logger.debug("Applying manifest based on reference.")
            req_body = self.req_json(req)
            doc_ref = req_body.get('hrefs', None)

            if not doc_ref:
                self.logger.info("Request did not contain 'hrefs'.")
                resp.status = falcon.HTTP_400
                return

            data = ReferenceResolver.resolve_reference(doc_ref)
            documents = list()
            for d in data:
                documents.extend(list(yaml.safe_load_all(d.decode())))

            if req_body.get('overrides', None):
                overrides = Override(documents,
                                     overrides=req_body.get('overrides'))
                documents = overrides.update_manifests()
        else:
            self.error(req.context,
                       "Unknown content-type %s" % req.content_type)
            # TODO(fmontei): Use falcon.<Relevant API Exception Class> instead.
            return self.return_error(
                resp,
                falcon.HTTP_415,
                message="Request must be in application/x-yaml"
                "or application/json")
        try:
            with self.get_tiller(req, resp) as tiller:
                msg = self.handle(req, documents, tiller)
                resp.body = json.dumps({
                    'message': msg,
                })
                resp.content_type = 'application/json'
                resp.status = falcon.HTTP_200

        except exceptions.ManifestException as e:
            self.return_error(resp, falcon.HTTP_400, message=str(e))
        except LockException as e:
            self.return_error(resp, falcon.HTTP_409, message=str(e))
        except Exception as e:
            self.logger.exception('Caught unexpected exception')
            err_message = 'Failed to apply manifest: {}'.format(e)
            self.error(req.context, err_message)
            self.return_error(resp, falcon.HTTP_500, message=err_message)
Exemplo n.º 5
0
    def invoke(self):
        try:
            doc_data = ReferenceResolver.resolve_reference(self.locations)
            documents = list()
            for d in doc_data:
                documents.extend(list(yaml.safe_load_all(d.decode())))
        except InvalidPathException as ex:
            self.logger.error(str(ex))
            return
        except yaml.YAMLError as yex:
            self.logger.error("Invalid YAML found: %s" % str(yex))
            return

        if not self.ctx.obj.get('api', False):
            with Tiller(tiller_host=self.tiller_host,
                        tiller_port=self.tiller_port,
                        tiller_namespace=self.tiller_namespace,
                        bearer_token=self.bearer_token) as tiller:

                try:
                    resp = self.handle(documents, tiller)
                    self.output(resp)
                finally:
                    if self.metrics_output:
                        path = self.metrics_output
                        self.logger.info(
                            'Storing metrics output in path: {}'.format(path))
                        prometheus_client.write_to_textfile(
                            path, metrics.REGISTRY)
        else:
            if len(self.values) > 0:
                self.logger.error(
                    "Cannot specify local values files when using the API.")
                return

            query = {
                'disable_update_post': self.disable_update_post,
                'disable_update_pre': self.disable_update_pre,
                'enable_chart_cleanup': self.enable_chart_cleanup,
                'tiller_host': self.tiller_host,
                'tiller_port': self.tiller_port,
                'tiller_namespace': self.tiller_namespace,
                'timeout': self.timeout,
                'wait': self.wait
            }

            client = self.ctx.obj.get('CLIENT')
            if self.use_doc_ref:
                resp = client.post_apply(
                    manifest_ref=self.locations, set=self.set, query=query)
            else:
                resp = client.post_apply(
                    manifest=documents, set=self.set, query=query)
            self.output(resp.get('message'))
Exemplo n.º 6
0
    def invoke(self):
        if not self.ctx.obj.get('api', False):
            doc_data = ReferenceResolver.resolve_reference(self.locations)
            documents = list()
            for d in doc_data:
                documents.extend(list(yaml.safe_load_all(d.decode())))

            try:
                valid, details = validate_armada_documents(documents)

                if not documents:
                    self.logger.warn('No documents to validate.')
                elif valid:
                    self.logger.info('Successfully validated: %s',
                                     self.locations)
                else:
                    self.logger.info('Validation failed: %s', self.locations)

                for m in details:
                    self.logger.info('Validation details: %s', str(m))
            except Exception:
                raise Exception('Exception raised during '
                                'validation: %s', self.locations)
        else:
            if len(self.locations) > 1:
                self.logger.error(
                    "Cannot specify multiple locations "
                    "when using validate API."
                )
                return

            client = self.ctx.obj.get('CLIENT')
            resp = client.post_validate(self.locations[0])

            if resp.get('code') == 200:
                self.logger.info('Successfully validated: %s', self.locations)
            else:
                self.logger.error("Validation failed: %s", self.locations)

            for m in resp.get('details', {}).get('messageList', []):
                self.logger.info("Validation details: %s", str(m))
Exemplo n.º 7
0
    def on_post(self, req, resp):
        # Load data from request and get options
        if req.content_type == 'application/x-yaml':
            data = list(self.req_yaml(req))
            if type(data[0]) is list:
                documents = list(data[0])
            else:
                documents = data
        elif req.content_type == 'application/json':
            self.logger.debug("Applying manifest based on reference.")
            req_body = self.req_json(req)
            doc_ref = req_body.get('hrefs', None)

            if not doc_ref:
                self.logger.info("Request did not contain 'hrefs'.")
                resp.status = falcon.HTTP_400
                return

            data = ReferenceResolver.resolve_reference(doc_ref)
            documents = list()
            for d in data:
                documents.extend(list(yaml.safe_load_all(d.decode())))

            if req_body.get('overrides', None):
                overrides = Override(
                    documents, overrides=req_body.get('overrides'))
                documents = overrides.update_manifests()
        else:
            self.error(req.context,
                       "Unknown content-type %s" % req.content_type)
            # TODO(fmontei): Use falcon.<Relevant API Exception Class> instead.
            return self.return_error(
                resp,
                falcon.HTTP_415,
                message="Request must be in application/x-yaml"
                "or application/json")
        try:
            armada = Armada(
                documents,
                disable_update_pre=req.get_param_as_bool('disable_update_pre'),
                disable_update_post=req.get_param_as_bool(
                    'disable_update_post'),
                enable_chart_cleanup=req.get_param_as_bool(
                    'enable_chart_cleanup'),
                dry_run=req.get_param_as_bool('dry_run'),
                force_wait=req.get_param_as_bool('wait'),
                timeout=req.get_param_as_int('timeout') or 0,
                tiller_host=req.get_param('tiller_host'),
                tiller_port=req.get_param_as_int('tiller_port') or
                CONF.tiller_port,
                tiller_namespace=req.get_param(
                    'tiller_namespace', default=CONF.tiller_namespace),
                target_manifest=req.get_param('target_manifest'))

            msg = armada.sync()

            resp.body = json.dumps({
                'message': msg,
            })

            resp.content_type = 'application/json'
            resp.status = falcon.HTTP_200
        except exceptions.ManifestException as e:
            self.return_error(resp, falcon.HTTP_400, message=str(e))
        except Exception as e:
            self.logger.exception('Caught unexpected exception')
            err_message = 'Failed to apply manifest: {}'.format(e)
            self.error(req.context, err_message)
            self.return_error(resp, falcon.HTTP_500, message=err_message)
Exemplo n.º 8
0
    def on_post(self, req, resp):
        try:

            # Load data from request and get options
            if req.content_type == 'application/x-yaml':
                data = list(self.req_yaml(req))
                if type(data[0]) is list:
                    documents = list(data[0])
                else:
                    documents = data
            elif req.content_type == 'application/json':
                self.logger.debug("Applying manifest based on reference.")
                req_body = self.req_json(req)
                doc_ref = req_body.get('hrefs', None)

                if not doc_ref:
                    self.logger.info("Request did not contain 'hrefs'.")
                    resp.status = falcon.HTTP_400
                    return

                data = ReferenceResolver.resolve_reference(doc_ref)
                documents = list()
                for d in data:
                    documents.extend(list(yaml.safe_load_all(d.decode())))

                if req_body.get('overrides', None):
                    overrides = Override(documents,
                                         overrides=req_body.get('overrides'))
                    documents = overrides.update_manifests()
            else:
                self.error(req.context,
                           "Unknown content-type %s" % req.content_type)
                self.return_error(
                    resp,
                    falcon.HTTP_415,
                    message="Request must be in application/x-yaml"
                    "or application/json")

            opts = req.params

            # Encode filename
            armada = Armada(
                documents,
                disable_update_pre=req.get_param_as_bool('disable_update_pre'),
                disable_update_post=req.get_param_as_bool(
                    'disable_update_post'),
                enable_chart_cleanup=req.get_param_as_bool(
                    'enable_chart_cleanup'),
                dry_run=req.get_param_as_bool('dry_run'),
                wait=req.get_param_as_bool('wait'),
                timeout=int(opts.get('timeout', 3600)),
                tiller_host=opts.get('tiller_host', None),
                tiller_port=int(opts.get('tiller_port', 44134)),
            )

            msg = armada.sync()

            resp.body = json.dumps({
                'message': msg,
            })

            resp.content_type = 'application/json'
            resp.status = falcon.HTTP_200
        except Exception as e:
            err_message = 'Failed to apply manifest: {}'.format(e)
            self.error(req.context, err_message)
            self.return_error(resp, falcon.HTTP_500, message=err_message)