Exemplo n.º 1
0
    def __init__(self,
                 serialized_service_description,
                 alias):

        validate(serialized_service_description,
                "yac/schema/description.json")

        self.name = search('"name"',
                            serialized_service_description,"")

        self.summary = search('summary',
                              serialized_service_description,"")

        self.version = search('version',
                              serialized_service_description,"")

        self.repo = search('repo',
                            serialized_service_description,"")

        self.default_alias = search('"default-alias"',
                                serialized_service_description,"")
        if alias:
            self.alias = alias
        else:
            self.alias = self.default_alias
Exemplo n.º 2
0
    def __init__(self, serialized_inputs_cacher):

        validate(serialized_inputs_cacher, "yac/schema/inputs_cacher.json")

        self.enabled = search("enabled", serialized_inputs_cacher, False)
        self.path = search("path", serialized_inputs_cacher, "")
        self.exclusions = search('"exclusions"', serialized_inputs_cacher, [])
Exemplo n.º 3
0
    def __init__(self,
                 credentials_descriptor):

        validate(credentials_descriptor, "yac/schema/stacks/k8s/credentialer.json")

        self.namespace = search("namespace",
                               credentials_descriptor,"")

        self.clusters = search("clusters",
                               credentials_descriptor,
                               ["nonprod","prod"])

        # if tokens are input there should be one per cluster
        self.tokens = search("tokens",
                               credentials_descriptor,
                               [])

        self.secrets = Secrets(search('"Secrets"',
                               credentials_descriptor,{}))

        # initialize the inputs (for driving user prompts)
        self.inputs = Inputs(search("Inputs",
                                    credentials_descriptor,{}))

        # for integration testing it is useful to write files to a
        # root director other than user's home
        self.rootdir = search("rootdir",
                              credentials_descriptor,"")
Exemplo n.º 4
0
    def __init__(self,
                 serialized_input):

        """ Inputs are typically used when a service
            provider wants to create an easy installation experience for their
            service.

        Args:
            serialized_input: A dictionary containing serialized input,
                               satisfying the yac/schema/input.json schema

        Raises:
            ValidationError: if a inputs fails schema validation

        """

        validate(serialized_input, "yac/schema/input.json")

        self.key = search("key",serialized_input,"")
        self.type = search("type",serialized_input,"")
        self.title = search("description",serialized_input,"")
        self.help = search("help",serialized_input,"")
        self.required = search("required",serialized_input,True)
        self.options = search("options",serialized_input,[])
        self.conditions = search("conditions",serialized_input,{})
Exemplo n.º 5
0
    def __init__(self, credentials_descriptor):
        """ Generates aws credentials for nordstrom users.

        Args:
            credentials_descriptor: A dictionary containing serialized credentialer,
                               satisfying the yac/schema/aws/credentialer.json schema

        Raises:
            ValidationError: if a inputs fails schema validation

        """

        validate(credentials_descriptor,
                 "yac/schema/stacks/aws/credentialer.json")

        self.accounts = search("accounts", credentials_descriptor, [])

        self.region = search("region", credentials_descriptor, [])

        # if urls not provided, use defaults
        self.token_endpoint_url = search('"token-endpoint-url"',
                                         credentials_descriptor,
                                         TOKEN_ENDPOINT_URL)

        self.role_endpoint_url = search('"role-endpoint-url"',
                                        credentials_descriptor,
                                        ROLE_ENDPOINT_URL)

        # initialize the inputs (for driving user prompts)
        self.inputs = Inputs(search("Inputs", credentials_descriptor, {}))
Exemplo n.º 6
0
    def __init__(self,
                 serialized_artifact):

        validate(serialized_artifact, "yac/schema/makers/container_image.json")

        self.name = search("name",serialized_artifact,"")
        self.description = search("description",serialized_artifact,"")

        self.image = search("image",serialized_artifact)

        # the registry where the images should be pushed
        # defaults to artifactory
        self.registry = search('registry',
                                serialized_artifact,
                                ARTIFACTORY_URL)

        # initialize the inputs (for driving user prompts)
        self.inputs = Inputs(search("Inputs",
                                    serialized_artifact,{}))

        self.secrets = Secrets(search('"Secrets"',
                                    serialized_artifact,{}))

        # client for most operations
        self.client = docker.DockerClient('tcp://%s:%s'%(BUILDER_HOST,
                                                         BUILDER_PORT))

        # client for "low-level" build operations (e.g. builds that send
        # the details on each layer built to stdout )
        # TODO: figure out why auth isn't working from inside a container
        # with this one
        self.api_client = docker.APIClient('tcp://%s:%s'%(BUILDER_HOST,
                                                         BUILDER_PORT))
Exemplo n.º 7
0
    def __init__(self, serialized_secrets):

        # validate. this will raise a validation error if
        # required fields aren't present
        validate(serialized_secrets, "yac/schema/secrets.json")

        self.values = serialized_secrets
        self.errors = []
Exemplo n.º 8
0
    def __init__(self, vault_configs):

        validate(vault_configs, "yac/schema/vaults/file.json")

        self.vault_path = search('"vault-path"', vault_configs)

        # default to json format
        self.format = search("format", vault_configs, "json")

        self.initialized = False
        self.ready = False
Exemplo n.º 9
0
    def __init__(self, serialized_tasks):

        # first validate. this should raise an error if
        # required fields aren't present
        validate(serialized_tasks, "yac/schema/tasks.json")

        self.values = {}
        for serialized_task in serialized_tasks:

            this_task = Task(serialized_task)
            self.values[this_task.name] = this_task
Exemplo n.º 10
0
def get_engine_configs(configs_path=""):
    # raises:
    #   validation error if anything is missing

    if not configs_path:
        configs_path = os.path.join(get_root_path(), "config/engines.json")

    engine_configs = {}
    with open(configs_path, 'r') as config_file:
        engine_configs = json.load(config_file)

    validate(engine_configs, "yac/schema/engines.json")
    return engine_configs
Exemplo n.º 11
0
    def __init__(self,
                 serialized_stack):
        # args:
        #    serialized_stack: dict containing the stack object from the Stack stanza
        #                      in the Servicefile

        # use the yac.lib.schema module to validate the serialized_stack, e.g.:
        validate(serialized_stack, "yac/schema/stacks/gcp/stack.json")

        # use the yac.lib.search module to grab fields from the serialized_stack, e.g.:
        self.name = search('name', serialized_stack)
        self.resources = search("Resources",serialized_stack, {})
        self.conditions = search("Conditions",serialized_stack, {})
Exemplo n.º 12
0
    def load_from_file(self, params_file_arg):

        params_str = ""

        # user may have specified a params file as a command line arg
        if params_file_arg and os.path.exists(params_file_arg):

            params_str = get_file_contents(params_file)

            serialized_params = json.loads(params_str)

            # validate
            validate(serialized_params, "yac/schema/params.json")

            self.values.update(Params(serialized_params))
Exemplo n.º 13
0
    def __init__(self, vault_configs):

        validate(vault_configs, "yac/schema/vaults/keepass.json")

        self.vault_path = search('"vault-path"', vault_configs)
        vault_pwd_path = search('"vault-pwd-path"', vault_configs)
        self.vault_pwd = search('"vault-pwd"', vault_configs)

        if not self.vault_pwd and vault_pwd_path and os.path.exists(
                vault_pwd_path):
            self.vault_pwd = read_pwd_file(vault_pwd_path)

        self.ready = False
        self.initialized = False
        self.kp = None
Exemplo n.º 14
0
    def __init__(self, int_test_descriptor):

        # validate the test descriptor
        # note: this will raise an exception if validation fails
        validate(int_test_descriptor, "yac/schema/integration_tests.json")

        # raw because it my contain instrinsics
        self.raw_target_map = search('"target-map"', int_test_descriptor, {})

        self.results_store = search('"results-store"', int_test_descriptor, {})

        self.tests = search('tests', int_test_descriptor, [])

        self.test_groups = search('"test-groups"', int_test_descriptor, [])

        self.test_results = TestResults()
Exemplo n.º 15
0
    def __init__(self, serialized_stack):

        self.type = "aws-cloudformation"

        # validate. this should raise an error if required
        # fields aren't present
        validate(serialized_stack, "yac/schema/stacks/aws/stack.json")

        self.parameters = search("Parameters", serialized_stack, {})
        self.resources = search("Resources", serialized_stack, {})
        self.conditions = search("Conditions", serialized_stack, {})

        # for mapping cloud formation parameters to yac params
        self.cf_param_map = ParameterMapping(
            search("ParameterMapping", serialized_stack, {}))

        self.boot_files = BootFiles(search('"BootFiles"', serialized_stack,
                                           {}))
Exemplo n.º 16
0
    def __init__(self, notifier_descriptor, logger=None):

        # first validate. this should throw an exception if
        # required fields aren't present
        validate(notifier_descriptor, "yac/schema/notifier/slack.json")

        self.info_channel = search('"info-channel"', notifier_descriptor, "")
        self.warning_channel = search('"warning-channel"', notifier_descriptor,
                                      "")

        self.api_key = search('"api-key"', notifier_descriptor, "")

        self.client = SlackClient(self.api_key)

        if logger:
            self.logger = logger
        else:
            self.logger = get_yac_logger()
Exemplo n.º 17
0
    def __init__(self,
                 serialized_secret_vaults):

        validate(serialized_secret_vaults, "yac/schema/vaults.json")

        self.vaults = {}

        for vault_descriptor in serialized_secret_vaults:

            vault_key = vault_descriptor['name']
            vault_type = vault_descriptor['type']

            self.vaults[vault_key], err = get_vault_provider(vault_type,
                                                 vault_descriptor['configs'])

            if err:
                print("vault provider for type '%s' not available. err: %s ... exiting"%(vault_type,err))
                exit(1)
Exemplo n.º 18
0
    def __init__(self, vault_configs={}):

        validate(vault_configs, "yac/schema/vaults/s3.json")

        self.vault_bucket = search('"bucket"', vault_configs)
        self.vault_s3_path = search('"vault-path"', vault_configs)
        self.format = search("format", vault_configs, "json")

        vault_file_local_path = get_vault_local_path(self.vault_bucket,
                                                     self.vault_s3_path)

        file_vault_config = {
            "vault-path": vault_file_local_path,
            "format": self.format
        }

        FileVault.__init__(self, file_vault_config)

        self.session = None
Exemplo n.º 19
0
    def __init__(self, serialized_artifact):

        validate(serialized_artifact, "yac/schema/makers/ami.json")

        self.name = search('name', serialized_artifact)

        self.description = search('description', serialized_artifact)

        # the aws profile aliasing the account to build in
        self.profile = search('profile', serialized_artifact)

        # path to the packer file
        self.packer_file = search('"packer-file"', serialized_artifact)

        # directory containing files that should be included in the build
        self.packable_dir = search('"packer-dir"', serialized_artifact, "")

        self.secrets = Secrets(search('"Secrets"', serialized_artifact, {}))

        # initialize the inputs (for driving user prompts)
        self.inputs = Inputs(search("Inputs", serialized_artifact, {}))
Exemplo n.º 20
0
    def __init__(self,
                 serialized_pipeline):

        # first validate. this should throw an exception if
        # required fields aren't present
        validate(serialized_pipeline,
                 "yac/schema/pipeline.json")

        self.deploy_branch = jmespath.search('"deploy-branch"',
                                              serialized_pipeline)

        self.rollback_branch = jmespath.search('"rollback-branch"',
                                              serialized_pipeline)

        self.setup  = jmespath.search('setup',
                                      serialized_pipeline)

        self.notifications = search('notifications',serialized_pipeline)

        self.stages = search('stages',serialized_pipeline,[])

        self.stage_names = search('stages[*].name',serialized_pipeline,[])
Exemplo n.º 21
0
    def __init__(self, serialized_stack):
        """
        Args:
            serialized_stack: A dictionary containing serialized k8s stack,
                              satisfying the yac/schema/stacks/k8s/stack.json schema
        Returns:
            A K8sStack instance

        Raises:
            ValidationError: if a serialized_stack fails schema validation

        """

        # first validate. this should raise an error if
        # required fields aren't present
        validate(serialized_stack, "yac/schema/stacks/k8s/stack.json")

        self.type = "kubernetes"

        self.namespace = search("namespace", serialized_stack, "")

        self.configmaps = ConfigMaps(serialized_stack)

        self.secrets = Secrets(serialized_stack)

        self.deployments = Deployments(serialized_stack)

        self.ingresses = Ingresses(serialized_stack)

        self.statefulsets = StatefulSets(serialized_stack)

        self.services = Services(serialized_stack)

        self.pvcs = PVCs(serialized_stack)

        # generic resources (orchestrated via kubectl)
        self.resources = Resources(serialized_stack)
Exemplo n.º 22
0
    def __init__(self,
                 serialized_service,
                 service_path,
                 alias="",
                 params_path="",
                 kvps=""):

        # first validate. this should throw an exception if
        # required fields aren't present
        validate(serialized_service, "yac/schema/service.json")

        self.path = service_path
        self.kvps_str = kvps
        self.params_file_path = params_path

        self.description = Description(search('Description',
                                       serialized_service,{}),
                                       alias)

        self.vaults = SecretVaults(search('"Vaults"',
                                      serialized_service,[]))

        # a service can references other services that it includes
        self.includes = search("includes",
                             serialized_service,{})

        # initialize stack params (key/value pairs and maps), including static params specified
        # in the serialized service, params from an external file,
        # params specified in a key-value pair string (kvps),
        self.params = Params(search('"Params"',
                                    serialized_service, {}))

        # initialize the dictionary that will hold all params (statics+secrets+inputs)
        self.all_params = {}

        inputs_cacher = InputsCacher(search('InputsCache',
                                    serialized_service,{}))

        self.inputs = Inputs(search('Inputs',
                                    serialized_service,{}),
                             inputs_cacher)

        self.secrets = Secrets(search('"Secrets"',
                                      serialized_service,{}))

        # inialize the stack associated with this service
        self.stack = Stack(search('Stack',
                                  serialized_service, {}))

        self.tasks = Tasks(search('Tasks',
                                    serialized_service,{}))

        # initialize the tests associated with this service
        self.tests = IntegrationTests(search('"IntegrationTests"',
                                      serialized_service,{}))

        # initialize the artifacts associate with this service
        self.artifacts = Artifacts(search('Artifacts',
                                           serialized_service,[]))

        # initialize the credentialer associated with this service
        self.credentialers = Credentialers(search("Credentialers",serialized_service,[]))

        # initialize the pipeline associated with this service
        self.pipeline = Pipeline(search('Pipeline',
                                     serialized_service,{}))

        # load the objects from each included service
        self.load_includes()

        # save a copy of the full serialized version of the
        # service to support the serialize() method
        self.serialized_service = serialized_service
Exemplo n.º 23
0
def apply_intrinsics(source_dict, params):
    """ Replaces yac intrinsics in a dictionary

    Args:
        source_dict: A dictionary with intrinsics
        params: A Params instance

    Returns:
        A dictionary with yac intrinsics replaced with values

    Raises:
        IntrinsicsError: message includes what instrinsics failed to render


    Currently supported instrisics include:

    {"yac-ref": "<param key>"}
        where,
           <param-key> is the key of a parameter to be dereferenced

    {"yac-join": ["<delimitter>", [elem1, elem2, ...,elemN]]}
        where,
           <delimitter> is the delimitter to be placed between each element
           <elem1-N> are any object (including another intrinsic)

    {"yac-name": "<resource>"}

        where,
            <resource> is an arbitrary string that helps define the
            resource (i.e. "elb", "asg", "stack", etc.)

        the 'name' instrinsic is a short-hand form of the 'join'
        intrinsic, since resource naming is such a common occurrence in
        stack templates. by default, it appends the service alias with the
        resource label, separated by a '-' delimmter.

        this default convention can be overridden via service-supplied
        'naming-convention' parameter, formatted as:

        ...
        "naming-convention": {
            "comment": "name resources using the alias followed by the environment",
            "value": {
                "param-keys": ['service-alias','env'],
                "delimitter": "-"
            }
        }
        ...
    }

    {"yac-include": <arg>}
        where <arg> is either:
            * a relative path to a json or yaml file containing a stack resource, or
            * a relative path to a python module with a 'generate_resource()' fxn

    {"yac-calc": <argv>}
        where,
            <argv> is an argv-style array containing the calculator to
            run and any arguments to pass to the calculator. Each element
            in argv is comma separated.

        the following 'stock'calculators are available:

        - {"yac-calc": ["vpc-id"]},

            which calculates the id of the vpc associated with the
            current aws credential

        - {"yac-calc": ["vpc-cidr"]},

            which calculates the cidr of the vpc associated with the
            current aws credential

        - {"yac-calc": ["subnet-ids","<label-str>",[<availability-zones>]],

            which calculates the subnets ids for all subnets in the vpc
            associated with the current aws credential. subnet ids
            returned are per the order of zones in the [<availability-zones>]
            array.

        In addition to the stock calculators, the yac-calc intrinsic will
        accept a path to any service-supplied module that contains a 'do_calc()'
        method, as:

        - {"yac-calc": ["<path to module>","arg1","arg2", etc.]},

            an example might look like:
               {"yac-calc": ["/lib/foo.py","bar1","bar2"]}

            the foo module is loaded, and its do_calc() function is called as:
                do_calc(["bar1", "bar2"])

            note: the module path is relative to the servicefile.

    """

    # make sure input is in the expected object format
    validate(source_dict, 'yac/schema/intrinsics_input.json')

    # Take a copy of template before applying intrinsics.
    source_dict_copy = copy.deepcopy(source_dict)

    # source_dict can contain intrinsics at any level.
    # _apply_intrinsics() uses recursion in processing intrinsics, and thus does not
    # support intrinsics at the first-child level. to address, do the following:
    # 1) create a placeholder first child that keys the source_dict
    # 2) process using _apply_intrinsics()
    # 3) return the rendered dictionary under placeholder

    placeholder_key = "placeholder"
    placeholder_dict = {placeholder_key: source_dict_copy}

    rendered_dictionary = _apply_intrinsics(placeholder_dict, params)

    # raise an IntrinsicsError if any failures were encountered
    if get_failures(params):
        raise IntrinsicsError(_pp_failures(params))
    else:
        return rendered_dictionary[placeholder_key]