# Path: badwolf/utils.py
# class ObjectDict(dict):
#     """Makes a dictionary behave like an object, with attribute-style access.
#     """
#     def __getattr__(self, key):
#         if key in self:
#             return self[key]
#         return None
# 
#     def __setattr__(self, key, value):
#         self[key] = value
# 
# def to_text(value, encoding='utf-8', errors='ignore'):
#     """Convert value to unicode, default encoding is utf-8
# 
#     :param value: Value to be converted
#     :param encoding: Desired encoding
#     """
#     if not value:
#         return ''
#     if isinstance(value, str):
#         return value
#     if isinstance(value, bytes):
#         return value.decode(encoding, errors)
#     return str(value)
# 
# def to_binary(value, encoding='utf-8'):
#     """Convert value to binary string, default encoding is utf-8
# 
#     :param value: Value to be converted
#     :param encoding: Desired encoding
#     """
#     if not value:
#         return b''
#     if isinstance(value, bytes):
#         return value
#     if isinstance(value, str):
#         return value.encode(encoding)
#     return bytes(value)
# 
# Path: badwolf/security.py
# class SecureToken(object):
# 
#     @staticmethod
#     def encrypt(text):
#         fernet = Fernet(to_binary(current_app.config['SECURE_TOKEN_KEY']))
#         return fernet.encrypt(to_binary(text))
# 
#     @staticmethod
#     def decrypt(encrypted):
#         fernet = Fernet(to_binary(current_app.config['SECURE_TOKEN_KEY']))
#         text = fernet.decrypt(to_binary(encrypted))
#         return to_text(text)
# 
# def parse_secretfile(fd):
#     env = []
#     for line in fd:
#         line = line.strip()
#         if not line:
#             continue
#         if line.startswith('#'):
#             continue
#         elif line.startswith('>'):
#             # Write to file not supported for now
#             continue
#         else:
#             env.append(line)
#     return env
# 
# Path: badwolf/exceptions.py
# class InvalidSpecification(BadwolfException):
#     pass


import io
import base64
import logging
import shlex
import yaml
    from yaml import CLoader as _Loader
    from yaml import Loader as _Loader
from flask import render_template
from marshmallow import Schema, fields, pre_load, post_load, ValidationError, validate
from marshmallow.utils import is_collection
from marshmallow_oneofschema import OneOfSchema
from badwolf.utils import ObjectDict, to_text, to_binary
from badwolf.security import SecureToken, parse_secretfile
from badwolf.exceptions import InvalidSpecification
        from cryptography.fernet import InvalidToken
class Specification(object):
    def __init__(self):
        self.shell = 'bash'
        self.image = None
        self.services = []
        self.scripts = []
        self.dockerfile = 'Dockerfile'
        self.docker = False  # Bind Docker sock to container or not
        self.after_success = []
        self.after_failure = []
        self.notification = ObjectDict(
            email=None,
            slack_webhook=None,
        )
        self.branch = set()
        self.environments = []
        self.linters = []
        self.privileged = False
        self.deploy = []
        self.after_deploy = []
        self.artifacts = ObjectDict(
            paths=[],
            excludes=[]
        )
        self.vault = ObjectDict(
            url=None,
            token=None,
            env=ObjectDict()
        )


# Path: badwolf/utils.py
# class ObjectDict(dict):
#     """Makes a dictionary behave like an object, with attribute-style access.
#     """
#     def __getattr__(self, key):
#         if key in self:
#             return self[key]
#         return None
# 
#     def __setattr__(self, key, value):
#         self[key] = value
# 
# def to_text(value, encoding='utf-8', errors='ignore'):
#     """Convert value to unicode, default encoding is utf-8
# 
#     :param value: Value to be converted
#     :param encoding: Desired encoding
#     """
#     if not value:
#         return ''
#     if isinstance(value, str):
#         return value
#     if isinstance(value, bytes):
#         return value.decode(encoding, errors)
#     return str(value)
# 
# def to_binary(value, encoding='utf-8'):
#     """Convert value to binary string, default encoding is utf-8
# 
#     :param value: Value to be converted
#     :param encoding: Desired encoding
#     """
#     if not value:
#         return b''
#     if isinstance(value, bytes):
#         return value
#     if isinstance(value, str):
#         return value.encode(encoding)
#     return bytes(value)
# 
# Path: badwolf/security.py
# class SecureToken(object):
# 
#     @staticmethod
#     def encrypt(text):
#         fernet = Fernet(to_binary(current_app.config['SECURE_TOKEN_KEY']))
#         return fernet.encrypt(to_binary(text))
# 
#     @staticmethod
#     def decrypt(encrypted):
#         fernet = Fernet(to_binary(current_app.config['SECURE_TOKEN_KEY']))
#         text = fernet.decrypt(to_binary(encrypted))
#         return to_text(text)
# 
# def parse_secretfile(fd):
#     env = []
#     for line in fd:
#         line = line.strip()
#         if not line:
#             continue
#         if line.startswith('#'):
#             continue
#         elif line.startswith('>'):
#             # Write to file not supported for now
#             continue
#         else:
#             env.append(line)
#     return env
# 
# Path: badwolf/exceptions.py
# class InvalidSpecification(BadwolfException):
#     pass


# Path: badwolf/spec.py
import io
import base64
import logging
import shlex
import yaml
    from yaml import CLoader as _Loader
    from yaml import Loader as _Loader
from flask import render_template
from marshmallow import Schema, fields, pre_load, post_load, ValidationError, validate
from marshmallow.utils import is_collection
from marshmallow_oneofschema import OneOfSchema
from badwolf.utils import ObjectDict, to_text, to_binary
from badwolf.security import SecureToken, parse_secretfile
from badwolf.exceptions import InvalidSpecification
        from cryptography.fernet import InvalidToken

class Specification(object):
    def __init__(self):
        self.shell = 'bash'
        self.image = None
        self.services = []
        self.scripts = []
        self.dockerfile = 'Dockerfile'
        self.docker = False  # Bind Docker sock to container or not
        self.after_success = []
        self.after_failure = []
        self.notification = ObjectDict(
            email=None,
            slack_webhook=None,
        )
        self.branch = set()
        self.environments = []
        self.linters = []
        self.privileged = False
        self.deploy = []
        self.after_deploy = []
        self.artifacts = ObjectDict(
            paths=[],
            excludes=[]
        )
        self.vault = ObjectDict(
            url=None,
            token=None,
            env=ObjectDict()
        )


    @classmethod