예제 #1
0
    def normalise(self, meta, val):
        if 'use' in val:
            template = val['use']
            if template not in meta.everything['templates']:
                available = list(meta.everything['templates'].keys())
                raise BadTemplate("Template doesn't exist!", wanted=template, available=available, meta=meta)

            val = MergedOptions.using(meta.everything['templates'][template], val)

        formatted_string = sb.formatted(sb.string_or_int_as_string_spec(), MergedOptionStringFormatter, expected_type=six.string_types)
        function_name = meta.key_names()['_key_name_0']

        val = sb.create_spec(Lambda
            , name = sb.overridden(function_name)
            , role = sb.required(only_one_spec(resource_spec("lambda", function_name, only=["iam"])))
            , code = sb.required(function_code_spec())
            , handler = function_handler_spec()
            , timeout = sb.integer_spec()
            , runtime = sb.required(formatted_string)
            , location = sb.required(formatted_string)
            , description = formatted_string
            , sample_event = sb.defaulted(sb.or_spec(formatted_dictionary(), sb.string_spec()), "")
            , desired_output_for_test = sb.defaulted(sb.or_spec(formatted_dictionary(), sb.string_spec()), "")
            , memory_size = sb.defaulted(divisible_by_spec(64), 128)
            ).normalise(meta, val)

        # Hack to make sample_event and desired_output_for_test not appear as a MergedOptions
        for key in ('sample_event', 'desired_output_for_test'):
            if isinstance(val[key], MergedOptions):
                v = val[key].as_dict()
                class Arbritrary(dictobj):
                    fields = list(v.keys())
                val[key] = Arbritrary(**v)
        return val
예제 #2
0
    def normalise(self, meta, val):
        if 'use' in val:
            template = val['use']
            if template not in meta.everything['templates']:
                available = list(meta.everything['templates'].keys())
                raise BadTemplate("Template doesn't exist!",
                                  wanted=template,
                                  available=available,
                                  meta=meta)

            val = MergedOptions.using(meta.everything['templates'][template],
                                      val)

        formatted_string = sb.formatted(sb.string_or_int_as_string_spec(),
                                        MergedOptionStringFormatter,
                                        expected_type=six.string_types)
        function_name = meta.key_names()['_key_name_0']

        val = sb.create_spec(Lambda,
                             name=sb.overridden(function_name),
                             role=sb.required(
                                 only_one_spec(
                                     resource_spec("lambda",
                                                   function_name,
                                                   only=["iam"]))),
                             code=sb.required(function_code_spec()),
                             handler=function_handler_spec(),
                             timeout=sb.integer_spec(),
                             runtime=sb.required(formatted_string),
                             location=sb.required(formatted_string),
                             description=formatted_string,
                             sample_event=sb.defaulted(
                                 sb.or_spec(formatted_dictionary(),
                                            sb.string_spec()), ""),
                             desired_output_for_test=sb.defaulted(
                                 sb.or_spec(formatted_dictionary(),
                                            sb.string_spec()), ""),
                             memory_size=sb.defaulted(divisible_by_spec(64),
                                                      128)).normalise(
                                                          meta, val)

        # Hack to make sample_event and desired_output_for_test not appear as a MergedOptions
        for key in ('sample_event', 'desired_output_for_test'):
            if isinstance(val[key], MergedOptions):
                v = val[key].as_dict()

                class Arbritrary(dictobj):
                    fields = list(v.keys())

                val[key] = Arbritrary(**v)
        return val
예제 #3
0
 def environment_spec(self):
     """Spec for each environment"""
     return create_spec(Environment
         , account_id = required(or_spec(string_spec(), valid_string_spec(validators.regexed("\d+"))))
         , region = defaulted(string_spec(), "ap-southeast-2")
         , vars = dictionary_spec()
         )
예제 #4
0
class acl_grant_spec(statement_spec):
    args = lambda s, self_type, self_name: {
        "grantee":
        sb.or_spec(sb.string_choice_spec(["__owner__"]),
                   acl_grantee_spec("grantee", "grantee")),
        "permission":
        sb.string_choice_spec(
            ["READ", "WRITE", "READ_ACP", "WRITE_ACP", "FULL_CONTROL"])
    }

    required = ["grantee", "permission"]

    def final_kls(self, *args, **kwargs):
        def ret(owner):
            result = {
                "Grantee": kwargs["grantee"],
                "Permission": kwargs["permission"]
            }
            if isinstance(kwargs['grantee'], six.string_types):
                if result["Grantee"] == "__owner__":
                    result["Grantee"] = owner
                else:
                    raise BadOption("Don't know how to deal with this grantee",
                                    grantee=kwargs['grantee'])
            return result

        return ret
예제 #5
0
    def normalise(self, meta, val):
        accounts = list(self.accounts(meta))
        if not accounts:
            accounts = [self.default_account_id(meta)]

        for account_id in accounts:
            string_or_dict = sb.or_spec(sb.string_spec(), sb.dictof(sb.string_choice_spec(["key_id", "alias"]), sb.string_spec()))
            for key_id in sb.listof(string_or_dict).normalise(meta, val):
                alias = None
                if key_id == "__self__" or (isinstance(key_id, dict) and (key_id.get("alias") == "__self__" or key_id.get("key_id") == "__self__")):
                    if self.self_type != "key":
                        raise BadPolicy("No __self__ key for this policy", meta=meta)
                    else:
                        alias = self.self_name
                        location = self.default_location(meta)
                else:
                    location = self.location(meta)

                if not alias:
                    if isinstance(key_id, six.string_types):
                        alias = key_id
                    else:
                        alias = key_id.get("alias")
                        key_id = key_id.get("key_id")

                if alias:
                    yield "arn:aws:kms:{0}:{1}:alias/{2}".format(location, account_id, alias)
                else:
                    yield "arn:aws:kms:{0}:{1}:key/{2}".format(location, account_id, key_id)
예제 #6
0
    def normalise(self, meta, val):
        result = sb.create_spec(
            LambdaMethod,
            http_method=sb.overridden(self.method),
            resource_name=sb.overridden(self.resource_name),
            function=formatted_string(),
            location=formatted_string(),
            account=sb.optional_spec(formatted_string()),
            require_api_key=sb.defaulted(sb.boolean(), False),
            request_mapping=sb.defaulted(mapping_spec(),
                                         Mapping("application/json", "")),
            mapping=sb.defaulted(
                mapping_spec(), Mapping("application/json",
                                        "$input.json('$')")),
            sample_event=sb.or_spec(formatted_dictionary(), sb.string_spec()),
            desired_output_for_test=sb.or_spec(formatted_dictionary(),
                                               sb.string_spec())).normalise(
                                                   meta, val)

        for key in ('sample_event', 'desired_output_for_test'):
            if isinstance(result[key], six.string_types):
                v = result[key]
                if v.startswith("{") and v.endswith("}"):
                    v = sb.formatted(
                        sb.string_spec(),
                        formatter=MergedOptionStringFormatter).normalise(
                            meta.at(key), v)
                    result[key] = v

        function = result.function
        location = None

        if result.location is not NotSpecified and location is not None:
            raise BadSpecValue(
                "Please don't specify a defined lambda function and location at the same time",
                meta=meta)

        if not isinstance(function, six.string_types):
            location = function.location
            function = function.name

        if location is None and result.location is NotSpecified:
            raise BadSpecValue("Location is a required key!", meta=meta)

        result.function = function
        result.location = location
        return result
예제 #7
0
 def environment_spec(self):
     """Spec for each environment"""
     return create_spec(stack_objs.Environment
         , account_id = required(or_spec(valid_string_spec(validators.regexed("\d+")), integer_spec()))
         , region = defaulted(string_spec(), "ap-southeast-2")
         , vars = dictionary_spec()
         , tags = self.tags_spec
         )
예제 #8
0
    def make_spec(self, meta, formatter):
        """
        Create the spec for this Field:

          * If callable, then call it

          * If is nullable
            * or the spec with none_spec
            * if we have an after format, do the same with that

          * if it has a default, wrap in defaulted

          * If it can be formatted, wrap in formatted

          * If it has a wrapper, wrap it with that

          * Return the result!
        """
        spec = self.spec
        if callable(spec):
            spec = spec()

        af = self.after_format
        if af is not NotSpecified and callable(af):
            af = af()

        if self.nullable:
            spec = defaulted(or_spec(none_spec(), spec), None)

            if af is not NotSpecified:
                af = or_spec(none_spec(), af)

        if self.default is not NotSpecified:
            spec = defaulted(spec, self.default)

        if self.formatted:
            if formatter is None:
                raise BadSpec("Need a formatter to be defined", meta=meta)
            else:
                spec = formatted(spec, formatter=formatter, after_format=af)

        if self.wrapper is not NotSpecified:
            spec = self.wrapper(spec)

        return spec
예제 #9
0
    def normalise(self, meta, val):
        return sb.create_spec(MockMethod
            , http_method = sb.overridden(self.method)
            , resource_name = sb.overridden(self.resource_name)

            , request_mapping = sb.defaulted(mapping_spec(), Mapping("application/json", '{"statusCode": 200}'))
            , mapping = mapping_spec()
            , require_api_key = sb.defaulted(sb.boolean(), False)
            , sample_event = sb.or_spec(sb.dictionary_spec(), sb.string_spec())
            , desired_output_for_test = sb.or_spec(sb.dictionary_spec(), sb.string_spec())
            ).normalise(meta, val)

        for key in ('sample_event', 'desired_output_for_test'):
            if isinstance(result[key], six.string_types):
                v = result[key]
                if v.startswith("{") and v.endswith("}"):
                    v = sb.formatted(sb.string_spec(), formatter=MergedOptionStringFormatter).normalise(meta.at(key), v)
                    result[key] = v
예제 #10
0
    def normalise(self, meta, val):
        result = sb.create_spec(LambdaMethod
            , http_method = sb.overridden(self.method)
            , resource_name = sb.overridden(self.resource_name)

            , function = formatted_string()
            , location = formatted_string()
            , account = sb.optional_spec(formatted_string())
            , require_api_key = sb.defaulted(sb.boolean(), False)
            , request_mapping = sb.defaulted(mapping_spec(), Mapping("application/json", ""))
            , mapping = sb.defaulted(mapping_spec(), Mapping("application/json", "$input.json('$')"))
            , sample_event = sb.or_spec(formatted_dictionary(), sb.string_spec())
            , desired_output_for_test = sb.or_spec(formatted_dictionary(), sb.string_spec())
            ).normalise(meta, val)

        for key in ('sample_event', 'desired_output_for_test'):
            if isinstance(result[key], six.string_types):
                v = result[key]
                if v.startswith("{") and v.endswith("}"):
                    v = sb.formatted(sb.string_spec(), formatter=MergedOptionStringFormatter).normalise(meta.at(key), v)
                    result[key] = v

        function = result.function
        location = None

        if result.location is not NotSpecified and location is not None:
            raise BadSpecValue("Please don't specify a defined lambda function and location at the same time", meta=meta)

        if not isinstance(function, six.string_types):
            location = function.location
            function = function.name

        if location is None and result.location is NotSpecified:
            raise BadSpecValue("Location is a required key!", meta=meta)

        result.function = function
        result.location = location
        return result
예제 #11
0
    def context_spec(self):
        """Spec for specifying context options"""
        from harpoon.option_spec import image_objs
        return dict_from_bool_spec(lambda meta, val: {"enabled": val}
            , create_spec(image_objs.Context
                , include = listof(string_spec())
                , exclude = listof(string_spec())
                , enabled = defaulted(boolean(), True)

                , parent_dir = directory_spec(formatted(defaulted(string_spec(), "{config_root}"), formatter=MergedOptionStringFormatter))
                , use_gitignore = defaulted(boolean(), False)
                , use_git_timestamps = defaulted(or_spec(boolean(), listof(string_spec())), False)
                )
            )
예제 #12
0
    def normalise(self, meta, val):
        from harpoon.option_spec.harpoon_specs import HarpoonSpec
        from harpoon.option_spec.image_objs import Image
        formatted_string = sb.formatted(sb.or_spec(sb.string_spec(), sb.typed(Image)), formatter=MergedOptionStringFormatter)

        img = conf = formatted_string.normalise(meta, val)
        if isinstance(img, six.string_types):
            conf = HarpoonSpec().image_spec.normalise(meta.at("image")
                , { "harpoon": meta.everything["harpoon"]
                  , "commands": ["FROM {0}".format(img)]
                  }
                )
            conf.image_name = img

        return img, conf
예제 #13
0
    def normalise(self, meta, val):
        return sb.create_spec(
            MockMethod,
            http_method=sb.overridden(self.method),
            resource_name=sb.overridden(self.resource_name),
            request_mapping=sb.defaulted(
                mapping_spec(),
                Mapping("application/json", '{"statusCode": 200}')),
            mapping=mapping_spec(),
            require_api_key=sb.defaulted(sb.boolean(), False),
            sample_event=sb.or_spec(sb.dictionary_spec(), sb.string_spec()),
            desired_output_for_test=sb.or_spec(sb.dictionary_spec(),
                                               sb.string_spec())).normalise(
                                                   meta, val)

        for key in ('sample_event', 'desired_output_for_test'):
            if isinstance(result[key], six.string_types):
                v = result[key]
                if v.startswith("{") and v.endswith("}"):
                    v = sb.formatted(
                        sb.string_spec(),
                        formatter=MergedOptionStringFormatter).normalise(
                            meta.at(key), v)
                    result[key] = v
예제 #14
0
 def context_spec(self):
     """Spec for specifying context options"""
     from harpoon.option_spec import image_objs
     return dict_from_bool_spec(
         lambda meta, val: {"enabled": val},
         create_spec(image_objs.Context,
                     include=listof(string_spec()),
                     exclude=listof(string_spec()),
                     enabled=defaulted(boolean(), True),
                     parent_dir=directory_spec(
                         formatted(defaulted(string_spec(),
                                             "{config_root}"),
                                   formatter=MergedOptionStringFormatter)),
                     use_gitignore=defaulted(boolean(), False),
                     use_git_timestamps=defaulted(
                         or_spec(boolean(), listof(string_spec())), False)))
예제 #15
0
    def normalise(self, meta, val):
        from harpoon.option_spec.harpoon_specs import HarpoonSpec
        from harpoon.option_spec.image_objs import Image
        formatted_string = sb.formatted(sb.or_spec(sb.string_spec(), sb.typed(Image)), formatter=MergedOptionStringFormatter)

        img = val["conf"] = sb.set_options(image = formatted_string).normalise(meta, val)["image"]
        if isinstance(img, six.string_types):
            val["conf"] = HarpoonSpec().image_spec.normalise(meta.at("image"), {"commands": ["FROM {0}".format(img)]})
            val["conf"].image_name = img

        return sb.create_spec(CommandContentAddDict
            , image = sb.overridden(img)
            , conf = sb.any_spec()
            , path = formatted_string
            , images = sb.overridden(meta.everything.get("images", []))
            , docker_context = sb.overridden(meta.everything["harpoon"].docker_context)
            ).normalise(meta, val)
예제 #16
0
class var_spec(many_item_formatted_spec):
    value_name = "Variable"
    specs = [
        sb.or_spec(sb.string_or_int_as_string_spec(),
                   sb.listof(sb.string_or_int_as_string_spec()))
    ]
    optional_specs = [sb.string_or_int_as_string_spec()]
    formatter = MergedOptionStringFormatter
    seperators = "|"

    def create_result(self, variable, variable_value, meta, val, dividers):
        if variable_value is NotSpecified:
            return StaticVariable(variable)
        else:
            stack = variable
            return DynamicVariable(stack, variable_value,
                                   meta.everything["bespin"])
예제 #17
0
    def normalise(self, meta, val):
        accounts = list(self.accounts(meta))
        if not accounts:
            accounts = [self.default_account_id(meta)]

        for account_id in accounts:
            string_or_dict = sb.or_spec(
                sb.string_spec(),
                sb.dictof(sb.string_choice_spec(["key_id", "alias"]),
                          sb.string_spec()))
            for key_id in sb.listof(string_or_dict).normalise(meta, val):
                alias = None
                if key_id == "__self__" or (
                        isinstance(key_id, dict) and
                    (key_id.get("alias") == "__self__"
                     or key_id.get("key_id") == "__self__")):
                    if self.self_type != "key":
                        raise BadPolicy("No __self__ key for this policy",
                                        meta=meta)
                    else:
                        alias = self.self_name
                        location = self.default_location(meta)
                else:
                    location = self.location(meta)

                if not alias:
                    if isinstance(key_id, six.string_types):
                        alias = key_id
                    else:
                        alias = key_id.get("alias")
                        key_id = key_id.get("key_id")

                if alias:
                    yield "arn:aws:kms:{0}:{1}:alias/{2}".format(
                        location, account_id, alias)
                else:
                    yield "arn:aws:kms:{0}:{1}:key/{2}".format(
                        location, account_id, key_id)
예제 #18
0
class lifecycle_statement_spec(statement_spec):
    formatted_string = sb.formatted(sb.string_spec(),
                                    formatter=MergedOptionStringFormatter)
    args = lambda s, self_type, self_name: {
        "id":
        s.formatted_string,
        "enabled":
        sb.boolean(),
        "prefix":
        s.formatted_string,
        "transition":
        transition_spec("transition", "transition"),
        "expiration":
        sb.or_spec(sb.integer_spec(),
                   expiration_spec("expiration", "expiration")),
        (("sep", "_"), ("parts", ("abort", "incomplete", "multipart", "upload"))):
        made_up_dict(sb.integer_spec(), ("DaysAfterInitiation", )),
        (("sep", "_"), ("parts", ("noncurrent", "version", "transition"))):
        capitalized_only_spec(),
        (("sep", "_"), ("parts", ("noncurrent", "version", "expiration"))):
        capitalized_only_spec()
    }
    final_kls = lambda s, *args, **kwargs: LifeCycleConfig(*args, **kwargs)
예제 #19
0
    def normalise(self, meta, val):
        if 'use' in val:
            template = val['use']
            if template not in meta.everything['templates']:
                available = list(meta.everything['templates'].keys())
                raise BadTemplate("Template doesn't exist!", wanted=template, available=available, meta=meta)

            val = MergedOptions.using(meta.everything['templates'][template], val)

        formatted_string = sb.formatted(sb.string_or_int_as_string_spec(), MergedOptionStringFormatter, expected_type=six.string_types)
        function_name = meta.key_names()['_key_name_0']

        return sb.create_spec(Lambda
            , name = sb.overridden(function_name)
            , role = sb.required(only_one_spec(resource_spec("lambda", function_name, only=["iam"])))
            , code = sb.required(function_code_spec())
            , handler = function_handler_spec()
            , timeout = sb.integer_spec()
            , runtime = sb.required(formatted_string)
            , location = sb.required(formatted_string)
            , description = formatted_string
            , sample_event = sb.defaulted(sb.or_spec(sb.dictionary_spec(), sb.string_spec()), "")
            , memory_size = sb.defaulted(divisible_by_spec(64), 128)
            ).normalise(meta, val)
예제 #20
0
    def image_spec(self):
        """Spec for each image"""
        from harpoon.option_spec import image_specs as specs
        from harpoon.option_spec import image_objs
        class persistence_shell_spec(Spec):
            """Make the persistence shell default to the shell on the image"""
            def normalise(self, meta, val):
                shell = defaulted(string_spec(), "/bin/bash").normalise(meta, meta.everything[["images", meta.key_names()["_key_name_2"]]].get("shell", NotSpecified))
                shell = defaulted(formatted(string_spec(), formatter=MergedOptionStringFormatter), shell).normalise(meta, val)
                return shell

        return create_spec(image_objs.Image
            , validators.deprecated_key("persistence", "The persistence feature has been removed")
            , validators.deprecated_key("squash_after", "The squash feature has been removed")
            , validators.deprecated_key("squash_before_push", "The squash feature has been removed")

            # Changed how volumes_from works
            , validators.deprecated_key("volumes_from", "Use ``volumes.share_with``")

            # Deprecated link
            , validators.deprecated_key("link", "Use ``links``")

            # Harpoon options
            , harpoon = any_spec()

            # default the name to the key of the image
            , tag = optional_spec(formatted(string_spec(), formatter=MergedOptionStringFormatter))
            , name = formatted(defaulted(string_spec(), "{_key_name_1}"), formatter=MergedOptionStringFormatter)
            , key_name = formatted(overridden("{_key_name_1}"), formatter=MergedOptionStringFormatter)
            , image_name = optional_spec(string_spec())
            , image_index = formatted(defaulted(string_spec(), ""), formatter=MergedOptionStringFormatter)
            , container_name = optional_spec(string_spec())
            , image_name_prefix = defaulted(string_spec(), "")

            , no_tty_option = defaulted(formatted(boolean(), formatter=MergedOptionStringFormatter), False)

            , user = defaulted(string_spec(), None)
            , configuration = any_spec()

            , vars = dictionary_spec()
            , assume_role = optional_spec(formatted(string_spec(), formatter=MergedOptionStringFormatter))
            , deleteable_image = defaulted(boolean(), False)

            , authentication = self.authentications_spec

            # The spec itself
            , shell = defaulted(formatted(string_spec(), formatter=MergedOptionStringFormatter), "/bin/bash")
            , bash = delayed(optional_spec(formatted(string_spec(), formatter=MergedOptionStringFormatter)))
            , command = delayed(optional_spec(formatted(string_spec(), formatter=MergedOptionStringFormatter)))
            , commands = required(container_spec(Commands, listof(command_spec())))
            , cache_from = delayed(or_spec(boolean(), listof(formatted(string_spec(), formatter=MergedOptionStringFormatter))))
            , cleanup_intermediate_images = defaulted(boolean(), True)

            , links = listof(specs.link_spec(), expect=image_objs.Link)

            , context = self.context_spec
            , wait_condition = optional_spec(self.wait_condition_spec)

            , lxc_conf = defaulted(filename_spec(), None)

            , volumes = create_spec(image_objs.Volumes
                , mount = listof(specs.mount_spec(), expect=image_objs.Mount)
                , share_with = listof(formatted(string_spec(), MergedOptionStringFormatter, expected_type=image_objs.Image))
                )

            , dependency_options = dictof(specs.image_name_spec()
                , create_spec(image_objs.DependencyOptions
                  , attached = defaulted(boolean(), False)
                  , wait_condition = optional_spec(self.wait_condition_spec)
                  )
                )

            , env = listof(specs.env_spec(), expect=image_objs.Environment)
            , ports = listof(specs.port_spec(), expect=image_objs.Port)
            , ulimits = defaulted(listof(dictionary_spec()), None)
            , log_config = defaulted(listof(dictionary_spec()), None)
            , security_opt = defaulted(listof(string_spec()), None)
            , read_only_rootfs = defaulted(boolean(), False)

            , other_options = create_spec(other_options
                , start = dictionary_spec()
                , build = dictionary_spec()
                , create = dictionary_spec()
                , host_config = dictionary_spec()
                )

            , network = create_spec(image_objs.Network
                , dns = defaulted(listof(string_spec()), None)
                , mode = defaulted(string_spec(), None)
                , hostname = defaulted(string_spec(), None)
                , domainname = defaulted(string_spec(), None)
                , disabled = defaulted(boolean(), False)
                , dns_search = defaulted(listof(string_spec()), None)
                , extra_hosts = listof(string_spec())
                , network_mode = defaulted(string_spec(), None)
                , publish_all_ports = defaulted(boolean(), False)
                )

            , cpu = create_spec(image_objs.Cpu
                , cap_add = defaulted(listof(string_spec()), None)
                , cpuset_cpus = defaulted(string_spec(), None)
                , cpuset_mems = defaulted(string_spec(), None)
                , cap_drop = defaulted(listof(string_spec()), None)
                , mem_limit = defaulted(integer_spec(), 0)
                , cpu_shares = defaulted(integer_spec(), None)
                , memswap_limit = defaulted(integer_spec(), 0)
                )

            , devices = defaulted(listof(dictionary_spec()), None)
            , privileged = defaulted(boolean(), False)
            , restart_policy = defaulted(string_spec(), None)
            )
예제 #21
0
    def image_spec(self):
        """Spec for each image"""
        from harpoon.option_spec import image_specs as specs
        from harpoon.option_spec import image_objs

        return create_spec(
            image_objs.Image
            # Change the context options
            ,
            validators.deprecated_key("exclude_context", "Use ``context.exclude``"),
            validators.deprecated_key("use_git_timestamps", "Use ``context.use_git_timestamps``"),
            validators.deprecated_key("respect_gitignore", "Use ``context.use_gitignore``"),
            validators.deprecated_key("parent_dir", "Use ``context.parent_dir``"),
            validators.deprecated_key("recursive", "Use ``persistence``")
            # Changed how volumes_from works
            ,
            validators.deprecated_key("volumes_from", "Use ``volumes.share_with``")
            # Deprecated link
            ,
            validators.deprecated_key("link", "Use ``links``")
            # Harpoon options
            ,
            harpoon=any_spec()
            # default the name to the key of the image
            ,
            name=formatted(defaulted(string_spec(), "{_key_name_1}"), formatter=MergedOptionStringFormatter),
            key_name=formatted(overridden("{_key_name_1}"), formatter=MergedOptionStringFormatter),
            image_name=optional_spec(string_spec()),
            image_index=defaulted(string_spec(), ""),
            container_name=optional_spec(string_spec()),
            image_name_prefix=defaulted(string_spec(), ""),
            user=defaulted(string_spec(), None),
            mtime=defaulted(any_spec(), time.time()),
            configuration=any_spec(),
            vars=dictionary_spec(),
            deleteable_image=defaulted(boolean(), False)
            # The spec itself
            ,
            bash=delayed(optional_spec(formatted(string_spec(), formatter=MergedOptionStringFormatter))),
            command=delayed(optional_spec(formatted(string_spec(), formatter=MergedOptionStringFormatter))),
            commands=required(container_spec(Commands, listof(command_spec()))),
            squash_after=optional_spec(or_spec(boolean(), container_spec(Commands, listof(command_spec())))),
            squash_before_push=optional_spec(or_spec(boolean(), container_spec(Commands, listof(command_spec())))),
            persistence=optional_spec(
                create_spec(
                    image_objs.Persistence,
                    validators.deprecated_key("persist", "Use ``folders``"),
                    action=required(formatted(string_spec(), formatter=MergedOptionStringFormatter)),
                    folders=required(listof(formatted(string_spec(), formatter=MergedOptionStringFormatter))),
                    cmd=optional_spec(formatted(string_spec(), formatter=MergedOptionStringFormatter)),
                    shell=defaulted(formatted(string_spec(), formatter=MergedOptionStringFormatter), "/bin/bash"),
                    image_name=delayed(
                        many_format(
                            overridden("images.{_key_name_2}.image_name"), formatter=MergedOptionStringFormatter
                        )
                    ),
                )
            ),
            links=listof(specs.link_spec(), expect=image_objs.Link),
            context=self.context_spec,
            wait_condition=optional_spec(self.wait_condition_spec),
            lxc_conf=defaulted(filename_spec(), None),
            volumes=create_spec(
                image_objs.Volumes,
                mount=listof(specs.mount_spec(), expect=image_objs.Mount),
                share_with=listof(
                    formatted(string_spec(), MergedOptionStringFormatter, expected_type=image_objs.Image)
                ),
            ),
            dependency_options=dictof(
                specs.image_name_spec(),
                create_spec(
                    image_objs.DependencyOptions,
                    attached=defaulted(boolean(), False),
                    wait_condition=optional_spec(self.wait_condition_spec),
                ),
            ),
            env=listof(specs.env_spec(), expect=image_objs.Environment),
            ports=listof(specs.port_spec(), expect=image_objs.Port),
            ulimits=defaulted(listof(dictionary_spec()), None),
            log_config=defaulted(listof(dictionary_spec()), None),
            security_opt=defaulted(listof(string_spec()), None),
            read_only_rootfs=defaulted(boolean(), False),
            other_options=create_spec(
                other_options,
                start=dictionary_spec(),
                build=dictionary_spec(),
                create=dictionary_spec(),
                host_config=dictionary_spec(),
            ),
            network=create_spec(
                image_objs.Network,
                dns=defaulted(listof(string_spec()), None),
                mode=defaulted(string_spec(), None),
                hostname=defaulted(string_spec(), None),
                domainname=defaulted(string_spec(), None),
                disabled=defaulted(boolean(), False),
                dns_search=defaulted(listof(string_spec()), None),
                extra_hosts=listof(string_spec()),
                network_mode=defaulted(string_spec(), None),
                publish_all_ports=defaulted(boolean(), False),
            ),
            cpu=create_spec(
                image_objs.Cpu,
                cap_add=defaulted(boolean(), None),
                cpuset=defaulted(listof(string_spec()), None),
                cap_drop=defaulted(boolean(), None),
                mem_limit=defaulted(integer_spec(), 0),
                cpu_shares=defaulted(integer_spec(), None),
                memswap_limit=defaulted(integer_spec(), 0),
            ),
            devices=defaulted(listof(dictionary_spec()), None),
            privileged=defaulted(boolean(), False),
            restart_policy=defaulted(string_spec(), None),
        )
예제 #22
0
    def image_spec(self):
        """Spec for each image"""
        from harpoon.option_spec import image_specs as specs
        from harpoon.option_spec import image_objs
        return create_spec(
            image_objs.Image
            # Change the context options
            ,
            validators.deprecated_key("exclude_context",
                                      "Use ``context.exclude``"),
            validators.deprecated_key("use_git_timestamps",
                                      "Use ``context.use_git_timestamps``"),
            validators.deprecated_key("respect_gitignore",
                                      "Use ``context.use_gitignore``"),
            validators.deprecated_key("parent_dir",
                                      "Use ``context.parent_dir``")

            # Changed how volumes_from works
            ,
            validators.deprecated_key("volumes_from",
                                      "Use ``volumes.share_with``")

            # Deprecated link
            ,
            validators.deprecated_key("link", "Use ``links``")

            # Harpoon options
            ,
            harpoon=any_spec()

            # default the name to the key of the image
            ,
            name=formatted(defaulted(string_spec(), "{_key_name_1}"),
                           formatter=MergedOptionStringFormatter),
            key_name=formatted(overridden("{_key_name_1}"),
                               formatter=MergedOptionStringFormatter),
            image_name=optional_spec(string_spec()),
            image_index=defaulted(string_spec(), ""),
            container_name=optional_spec(string_spec()),
            image_name_prefix=defaulted(string_spec(), ""),
            user=defaulted(string_spec(), None),
            mtime=defaulted(any_spec(), time.time()),
            configuration=any_spec(),
            vars=dictionary_spec(),
            deleteable_image=defaulted(boolean(), False)

            # The spec itself
            ,
            bash=delayed(
                optional_spec(
                    formatted(string_spec(),
                              formatter=MergedOptionStringFormatter))),
            command=delayed(
                optional_spec(
                    formatted(string_spec(),
                              formatter=MergedOptionStringFormatter))),
            commands=required(container_spec(Commands,
                                             listof(command_spec()))),
            squash_after=optional_spec(
                or_spec(boolean(),
                        container_spec(Commands, listof(command_spec())))),
            squash_before_push=optional_spec(
                or_spec(boolean(),
                        container_spec(Commands, listof(command_spec())))),
            recursive=optional_spec(
                create_spec(
                    image_objs.Recursive,
                    action=required(
                        formatted(string_spec(),
                                  formatter=MergedOptionStringFormatter)),
                    persist=required(
                        listof(
                            formatted(string_spec(),
                                      formatter=MergedOptionStringFormatter))),
                    image_name=delayed(
                        many_format(
                            overridden("images.{_key_name_2}.image_name"),
                            formatter=MergedOptionStringFormatter)))),
            links=listof(specs.link_spec(), expect=image_objs.Link),
            context=self.context_spec,
            wait_condition=optional_spec(self.wait_condition_spec),
            lxc_conf=defaulted(filename_spec(), None),
            volumes=create_spec(image_objs.Volumes,
                                mount=listof(specs.mount_spec(),
                                             expect=image_objs.Mount),
                                share_with=listof(
                                    formatted(
                                        string_spec(),
                                        MergedOptionStringFormatter,
                                        expected_type=image_objs.Image))),
            dependency_options=dictof(
                specs.image_name_spec(),
                create_spec(image_objs.DependencyOptions,
                            attached=defaulted(boolean(), False),
                            wait_condition=optional_spec(
                                self.wait_condition_spec))),
            env=listof(specs.env_spec(), expect=image_objs.Environment),
            ports=listof(specs.port_spec(), expect=image_objs.Port),
            ulimits=defaulted(listof(dictionary_spec()), None),
            log_config=defaulted(listof(dictionary_spec()), None),
            security_opt=defaulted(listof(string_spec()), None),
            read_only_rootfs=defaulted(boolean(), False),
            other_options=create_spec(other_options,
                                      start=dictionary_spec(),
                                      build=dictionary_spec(),
                                      create=dictionary_spec(),
                                      host_config=dictionary_spec()),
            network=create_spec(image_objs.Network,
                                dns=defaulted(listof(string_spec()), None),
                                mode=defaulted(string_spec(), None),
                                hostname=defaulted(string_spec(), None),
                                domainname=defaulted(string_spec(), None),
                                disabled=defaulted(boolean(), False),
                                dns_search=defaulted(listof(string_spec()),
                                                     None),
                                extra_hosts=listof(string_spec()),
                                network_mode=defaulted(string_spec(), None),
                                publish_all_ports=defaulted(boolean(), False)),
            cpu=create_spec(image_objs.Cpu,
                            cap_add=defaulted(boolean(), None),
                            cpuset=defaulted(listof(string_spec()), None),
                            cap_drop=defaulted(boolean(), None),
                            mem_limit=defaulted(integer_spec(), 0),
                            cpu_shares=defaulted(integer_spec(), None),
                            memswap_limit=defaulted(integer_spec(), 0)),
            devices=defaulted(listof(dictionary_spec()), None),
            privileged=defaulted(boolean(), False),
            restart_policy=defaulted(string_spec(), None))