def parse_spec(self): '''Parse repository build/lint spec''' logger.info('Parsing specification for repository %s', self.context.repository) conf_file = os.path.join(self.context.clone_path, current_app.config['BADWOLF_PROJECT_CONF']) try: spec = Specification.parse_file(conf_file) except OSError: logger.warning( 'No project configuration file found for repo: %s', self.context.repository ) raise SpecificationNotFound() secretfile = os.path.join(self.context.clone_path, 'Secretfile') if os.path.exists(secretfile): spec.parse_secretfile(secretfile) branch = self.context.source['branch']['name'] if self.context.type == 'branch' and not spec.is_branch_enabled(branch): logger.info( 'Ignore tests since branch %s test is not enabled. Allowed branches: %s', branch, spec.branch ) raise BuildDisabled() if not spec.scripts and not spec.linters: logger.warning('No script(s) or linter(s) to run') raise InvalidSpecification('No script or linter to run') self.spec = spec # setup Vault vault_url = spec.vault.url or current_app.config['VAULT_URL'] vault_token = spec.vault.token or current_app.config['VAULT_TOKEN'] if vault_url and vault_token: self.vault = hvac.Client(url=vault_url, token=vault_token) self._populate_envvars_from_vault()
def parse_spec(self): '''Parse repository build/lint spec''' logger.info('Parsing specification for repository %s', self.context.repository) conf_file = os.path.join(self.context.clone_path, current_app.config['BADWOLF_PROJECT_CONF']) try: spec = Specification.parse_file(conf_file) except OSError: logger.warning('No project configuration file found for repo: %s', self.context.repository) raise SpecificationNotFound() secretfile = os.path.join(self.context.clone_path, 'Secretfile') if os.path.exists(secretfile): spec.parse_secretfile(secretfile) branch = self.context.source['branch']['name'] if self.context.type == 'branch' and not spec.is_branch_enabled( branch): logger.info( 'Ignore tests since branch %s test is not enabled. Allowed branches: %s', branch, spec.branch) raise BuildDisabled() if not spec.scripts and not spec.linters: logger.warning('No script(s) or linter(s) to run') raise InvalidSpecification('No script or linter to run') self.spec = spec
def _populate_envvars_from_vault(self): if self.vault is None or not self.spec.vault.env: return paths = [v[0] for v in self.spec.vault.env.values()] secrets = {} for path in paths: try: res = self.vault.read(path) except VaultError as exc: raise InvalidSpecification('Error reading {} from Vault: {}'.format(path, str(exc))) if not res: raise InvalidSpecification('Error reading {} from Vault: not found'.format(path)) secrets[path] = res['data'] for name, (path, key) in self.spec.vault.env.items(): val = secrets.get(path, {}).get(key) if val is not None: self.context.environment.setdefault(name, val)
def parse(cls, conf): schema = SpecificationSchema() try: data = schema.load(conf) except ValidationError as e: logger.exception('badwolf specification validation error') raise InvalidSpecification(str(e)) spec = cls() for key, value in data.items(): setattr(spec, key, value) return spec
def parse_file(cls, path): try: if hasattr(path, 'read') and callable(path.read): # File-like obj conf = yaml.load(path.read(), Loader=_Loader) else: with io.open(path) as f: conf = yaml.load(f.read(), Loader=_Loader) except yaml.error.MarkedYAMLError as e: raise InvalidSpecification(str(e)) return cls.parse(conf)