예제 #1
0
    def test_own_document_examples(self):
        examples_path = os.path.join(os.getcwd(), 'examples')
        example_files = [
            os.path.join(examples_path, f) for f in os.listdir(examples_path)
            if os.path.isfile(os.path.join(examples_path, f))
        ]
        validated_manifests = []

        for example_file in example_files:
            with open(example_file) as f:
                documents = yaml.safe_load_all(f.read())

            # If the example file doesn't have a document with
            # armada/Manifest/v1 then skip validating it as the example could
            # merely be an override.
            has_manifest = any(x['schema'] == 'armada/Manifest/v1'
                               for x in documents)
            if not has_manifest:
                continue

            validated_manifests.append(example_file)
            valid, _ = validate.validate_armada_documents(list(documents))
            self.assertTrue(valid)

        self.assertTrue(validated_manifests)
예제 #2
0
 def test_build_armada_manifest_with_missing_chart_grps_fails(self):
     """Validate that attempting to build a manifest with missing
     chart groups fails.
     """
     self.documents[6]['data']['chart_groups'] = ['missing-chart-groups']
     valid, details = validate.validate_armada_documents(self.documents)
     self.assertFalse(valid)
예제 #3
0
 def test_build_chart_deps_with_missing_dependency_fails(self):
     """Validate that attempting to build a chart that points to
     a missing dependency fails.
     """
     self.documents[1]['data']['dependencies'] = ['missing-dependency']
     valid, details = validate.validate_armada_documents(self.documents)
     self.assertFalse(valid)
예제 #4
0
    def test_validate_armada_yaml_passes(self):
        template = '{}/resources/valid_armada_document.yaml'.format(
            self.basepath)

        with open(template) as f:
            documents = yaml.safe_load_all(f.read())
        valid, details = validate.validate_armada_documents(list(documents))

        self.assertTrue(valid)
예제 #5
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, details = validate_armada_documents(documents)

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

            error_details = [m for m in details if m.get('error', False)]

            resp_body['details']['errorCount'] = len(error_details)
            resp_body['details']['messageList'] = details

            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 = 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)
예제 #6
0
    def pre_flight_ops(self):
        """Perform a series of checks and operations to ensure proper
        deployment.
        """
        LOG.info("Performing pre-flight operations.")

        # Ensure Tiller is available and manifest is valid
        if not self.tiller.tiller_status():
            raise tiller_exceptions.TillerServicesUnavailableException()

        valid, details = validate.validate_armada_documents(self.documents)

        if details:
            for msg in details:
                if msg.get('error', False):
                    LOG.error(msg.get('message', 'Unknown validation error.'))
                else:
                    LOG.debug(msg.get('message', 'Validation succeeded.'))
            if not valid:
                raise validate_exceptions.InvalidManifestException(
                    error_messages=details)

        result, msg_list = validate.validate_armada_manifests(self.documents)
        if not result:
            raise validate_exceptions.InvalidArmadaObjectException(
                details=','.join([m.get('message') for m in msg_list]))

        # Purge known releases that have failed and are in the current yaml
        manifest_data = self.manifest.get(KEYWORD_ARMADA, {})
        prefix = manifest_data.get(KEYWORD_PREFIX, '')
        failed_releases = self.get_releases_by_status(STATUS_FAILED)

        for release in failed_releases:
            for group in manifest_data.get(KEYWORD_GROUPS, []):
                for ch in group.get(KEYWORD_CHARTS, []):
                    ch_release_name = release_prefix(
                        prefix,
                        ch.get('chart', {}).get('chart_name'))
                    if release[0] == ch_release_name:
                        LOG.info(
                            'Purging failed release %s '
                            'before deployment', release[0])
                        self.tiller.uninstall_release(release[0])

        # Clone the chart sources
        #
        # We only support a git source type right now, which can also
        # handle git:// local paths as well
        repos = {}
        for group in manifest_data.get(KEYWORD_GROUPS, []):
            for ch in group.get(KEYWORD_CHARTS, []):
                self.tag_cloned_repo(ch, repos)

                for dep in ch.get('chart', {}).get('dependencies', []):
                    self.tag_cloned_repo(dep, repos)
예제 #7
0
 def _document_checker(self, doc, ovr=None):
     # Validate document or raise the appropriate exception
     try:
         valid, details = validate.validate_armada_documents(doc)
     except (RuntimeError, TypeError):
         raise override_exceptions.InvalidOverrideValueException(ovr)
     if not valid:
         if ovr:
             raise override_exceptions.InvalidOverrideValueException(ovr)
         else:
             raise validate_exceptions.InvalidManifestException(
                 error_messages=details)
예제 #8
0
파일: override.py 프로젝트: raja324/armada
    def update_manifests(self):

        if self.values:
            for value in self.values:
                merging_values = self._load_yaml_file(value)
                self.update_document(merging_values)
        if self.overrides:
            for override in self.overrides:
                new_value = override.split('=')[1]
                doc_path = override.split('=')[0].split(":")
                data_path = doc_path.pop().split('.')

                self.override_manifest_value(doc_path, data_path, new_value)

        try:
            validate.validate_armada_documents(self.documents)
        except Exception:
            raise override_exceptions.InvalidOverrideValueException(
                self.overrides)

        return self.documents
예제 #9
0
    def test_validate_invalid_chart_armada_manifest(self):
        template = '{}/resources/valid_armada_document.yaml'.format(
            self.basepath)

        with open(template) as f:
            documents = list(yaml.safe_load_all(f.read()))

        mariadb_document = [
            d for d in documents if d['metadata']['name'] == 'mariadb'
        ][0]
        del mariadb_document['data']['release']

        _, error_messages = validate.validate_armada_documents(documents)
        expected_error = self._build_error_message(
            'armada/Chart/v1', 'mariadb', "'release' is a required property")

        self.assertEqual(1, len(error_messages))
        self.assertEqual(expected_error, error_messages[0]['message'])
예제 #10
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))
예제 #11
0
    def test_validate_chart_group_with_values(self):
        test_chart_group = """
---
schema: armada/ChartGroup/v1
metadata:
    name: kubernetes-proxy
    schema: metadata/Document/v1
data:
    description: Kubernetes proxy
    name: kubernetes-proxy
    sequenced: true
    chart_group:
      - proxy
---
schema: armada/Chart/v1
metadata:
    name: proxy
    schema: metadata/Document/v1
data:
    chart_name: proxy
    timeout: 600
    release: kubernetes-proxy
    source:
      subpath: proxy
      type: local
      location: "/etc/genesis/armada/assets/charts"
    namespace: kube-system
    upgrade:
      no_hooks: true
    values:
      images:
        tags:
          proxy: gcr.io/google_containers/hyperkube-amd64:v1.8.6
      network:
        kubernetes_netloc: 127.0.0.1:6553
    dependencies:
      - helm-toolkit
---
schema: armada/Chart/v1
metadata:
    name: helm-toolkit
    schema: metadata/Document/v1
data:
    chart_name: helm-toolkit
    wait:
      timeout: 600
    release: helm-toolkit
    source:
      reference: master
      subpath: helm-toolkit
      location: https://git.openstack.org/openstack/openstack-helm-infra
      type: git
    namespace: helm-toolkit
    upgrade:
      no_hooks: true
    values: {}
    dependencies: []
"""

        chart_group = yaml.safe_load_all(test_chart_group)
        is_valid, error = validate.validate_armada_documents(list(chart_group))

        self.assertTrue(is_valid)
예제 #12
0
파일: test.py 프로젝트: sana-aawan/armada
 def _validate_documents(self, req, resp, documents):
     result, details = validate.validate_armada_documents(documents)
     return self._format_validation_response(req, resp, result, details)