예제 #1
0
    def normalise(self, meta, val):
        pairs = []
        has_self = False
        for account_id in self.accounts(meta):
            users = sb.listof(sb.string_spec()).normalise(meta.at("users"), self.resource.get('users', NotSpecified))
            for index, name in enumerate(sb.listof(sb.any_spec()).normalise(meta, val)):
                if name == "__self__":
                    if self.self_type != 'role':
                        raise BadPolicy("No __self__ iam role for this policy", meta=meta)
                    else:
                        has_self = True
                else:
                    if isinstance(name, six.string_types):
                        name = sb.formatted(sb.string_spec(), formatter=MergedOptionStringFormatter).normalise(meta.indexed_at(index), name)
                    pairs.append((name, account_id))

        if has_self:
            pairs.append(("role/{0}".format(self.self_name), self.default_account_id(meta)))

        for name, account_id in pairs:
            service = "sts" if name.startswith("assumed-role") else "iam"
            arn = "arn:aws:{0}::{1}:{2}".format(service, account_id, name)
            if not users:
                yield arn
            else:
                for user in users:
                    yield "{0}/{1}".format(arn, user)
예제 #2
0
    def normalise(self, meta, val):
        iam_spec = iam_specs(val, self.self_type, self.self_name)

        result = sb.set_options(
              Service = sb.listof(sb.string_spec())
            , Federated = sb.listof(sb.string_spec())
            , AWS = sb.listof(sb.string_spec())
            ).normalise(meta, val)

        special = sb.set_options(
              service = sb.listof(principal_service_spec())
            , federated = resource_spec(self.self_type, self.self_name)
            , iam = iam_spec
            ).normalise(meta, val)

        for arg, lst in special.items():
            capitalized = arg.capitalize()
            if arg == 'iam':
                capitalized = "AWS"
            result[capitalized].extend(lst)

        for key, val in list(result.items()):
            if not val:
                del result[key]
                continue

            # Amazon gets rid of the lists if only one item
            # And this mucks around with the diffing....
            if len(val) is 1:
                result[key] = val[0]
            else:
                result[key] = sorted(val)

        return result
예제 #3
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)

        gateway_name = meta.key_names()['_key_name_0']
        gateway_location = formatted_string().normalise(
            meta.at('location'), val.get('location', ''))

        return sb.create_spec(
            Gateway,
            name=sb.overridden(gateway_name),
            location=sb.required(formatted_string()),
            stages=sb.listof(formatted_string()),
            api_keys=sb.listof(api_key_spec()),
            domain_names=sb.dictof(sb.string_spec(),
                                   custom_domain_name_spec(gateway_location)),
            resources=sb.dictof(sb.string_spec(),
                                gateway_resource_spec())).normalise(meta, val)
예제 #4
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)
        key_name = meta.key_names()['_key_name_0']

        key = sb.create_spec(EncryptionKey
            , name = sb.overridden(key_name)
            , location = sb.required(formatted_string)
            , description = formatted_string
            , grant = sb.listof(grant_statement_spec('key', key_name))
            , admin_users = sb.listof(sb.any_spec())
            , permission = sb.listof(sb.dictionary_spec())
            , no_root_access = sb.defaulted(sb.boolean(), False)
            ).normalise(meta, val)

        statements = key.permission
        if not key.no_root_access:
            statements.append({"principal": {"iam": "root"}, "action": "kms:*", "resource": "*", "Sid": ""})

        if key.admin_users:
            for admin_user in key.admin_users:
                statements.append({"principal": admin_user, "action": "kms:*", "resource": { "kms": "__self__" }, "Sid": ""})

        key.policy = sb.container_spec(Document, sb.listof(resource_policy_statement_spec('key', key_name))).normalise(meta.at("admin_users"), statements)
        return key
예제 #5
0
파일: netscaler.py 프로젝트: carukc/bespin
    def normalise_filled(self, meta, val):
        typ = formatted(overridden("{_key_name_1}"), formatter=MergedOptionStringFormatter).normalise(meta, val)
        name = formatted(overridden("{_key_name_0}"), formatter=MergedOptionStringFormatter).normalise(meta, val)
        special = {}
        kls = special.get(typ, GenericNetscalerConfig)

        formatted_string = formatted(string_spec(), formatter=MergedOptionStringFormatter)
        formatted_options = dictof(string_spec(), match_spec((six.string_types, formatted_string), fallback=any_spec()))

        options = dict(
              typ=overridden(typ)
            , name=overridden(name)
            , bindings=dictof(string_spec()
            , netscaler_binding_spec())
            , tags=listof(string_spec())
            , options=formatted_options
            , overrides=formatted_options
            , binding_options=formatted_options
            , environments=optional_spec(listof(valid_environment_spec()))
            )

        if typ == "sslcertkey":
            options["link"] = listof(string_spec())
        as_dict = set_options(**options).normalise(meta, val)
        return kls(**dict((name, as_dict[name]) for name in options))
예제 #6
0
    def normalise(self, meta, val):
        iam_spec = iam_specs(val, self.self_type, self.self_name)

        result = sb.set_options(Service=sb.listof(sb.string_spec()),
                                Federated=sb.listof(sb.string_spec()),
                                AWS=sb.listof(sb.string_spec())).normalise(
                                    meta, val)

        special = sb.set_options(service=sb.listof(principal_service_spec()),
                                 federated=resource_spec(
                                     self.self_type, self.self_name),
                                 iam=iam_spec).normalise(meta, val)

        for arg, lst in special.items():
            capitalized = arg.capitalize()
            if arg == 'iam':
                capitalized = "AWS"
            result[capitalized].extend(lst)

        for key, val in list(result.items()):
            if not val:
                del result[key]
                continue

            # Amazon gets rid of the lists if only one item
            # And this mucks around with the diffing....
            if len(val) is 1:
                result[key] = val[0]
            else:
                result[key] = sorted(val)

        return result
예제 #7
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
        )
        key_name = meta.key_names()["_key_name_0"]

        key = sb.create_spec(
            EncryptionKey,
            name=sb.overridden(key_name),
            location=sb.required(formatted_string),
            description=formatted_string,
            grant=sb.listof(grant_statement_spec("key", key_name)),
            admin_users=sb.listof(sb.any_spec()),
        ).normalise(meta, val)

        statements = [{"principal": {"iam": "root"}, "action": "kms:*", "resource": "*", "Sid": ""}]
        if key.admin_users:
            for admin_user in key.admin_users:
                statements.append(
                    {"principal": admin_user, "action": "kms:*", "resource": {"kms": "__self__"}, "Sid": ""}
                )

        key.policy = sb.container_spec(Document, sb.listof(resource_policy_statement_spec("key", key_name))).normalise(
            meta.at("admin_users"), statements
        )
        return key
예제 #8
0
    def normalise(self, meta, val):
        pairs = []
        has_self = False
        for account_id in self.accounts(meta):
            users = sb.listof(sb.string_spec()).normalise(
                meta.at("users"), self.resource.get('users', NotSpecified))
            for name in sb.listof(sb.any_spec()).normalise(meta, val):
                if name == "__self__":
                    if self.self_type != 'role':
                        raise BadPolicy("No __self__ iam role for this policy",
                                        meta=meta)
                    else:
                        has_self = True
                else:
                    pairs.append((name, account_id))

        if has_self:
            pairs.append(("role/{0}".format(self.self_name),
                          self.default_account_id(meta)))

        for name, account_id in pairs:
            service = "sts" if name.startswith("assumed-role") else "iam"
            arn = "arn:aws:{0}::{1}:{2}".format(service, account_id, name)
            if not users:
                yield arn
            else:
                for user in users:
                    yield "{0}/{1}".format(arn, user)
예제 #9
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)
        bucket_name = meta.key_names()['_key_name_0']

        original_permission = sb.listof(resource_policy_dict()).normalise(meta.at("permission"), NotSpecified if "permission" not in val else val["permission"])
        deny_permission = sb.listof(resource_policy_dict(effect='Deny')).normalise(meta.at("deny_permission"), NotSpecified if "deny_permission" not in val else val["deny_permission"])
        allow_permission = sb.listof(resource_policy_dict(effect='Allow')).normalise(meta.at("allow_permission"), NotSpecified if "allow_permission" not in val else val["allow_permission"])

        # require_mfa_to_delete is an alias for this permission
        if val.get("require_mfa_to_delete") is True:
            delete_policy = {"action": "s3:DeleteBucket", "resource": { "s3": "__self__" }, "Condition": { "Bool": { "aws:MultiFactorAuthPresent": True } } }
            normalised_delete_policy = resource_policy_dict(effect='Allow').normalise(meta.at("require_mfa_to_delete"), delete_policy)
            allow_permission.append(normalised_delete_policy)

        val = val.wrapped()
        val['permission'] = original_permission + deny_permission + allow_permission

        return sb.create_spec(Bucket
            , acl = sb.defaulted(sb.match_spec((six.string_types, canned_acl_spec()), (dict, acl_statement_spec('acl', 'acl'))), None)
            , name = sb.overridden(bucket_name)
            , location = sb.defaulted(formatted_string, None)
            , permission = sb.container_spec(Document, sb.listof(resource_policy_statement_spec('bucket', bucket_name)))
            , tags = sb.dictof(sb.string_spec(), formatted_string)
            , website = sb.defaulted(website_statement_spec("website", "website"), None)
            , logging = sb.defaulted(logging_statement_spec("logging", "logging"), None)
            , lifecycle = sb.defaulted(sb.listof(lifecycle_statement_spec("lifecycle", "lifecycle")), None)
            ).normalise(meta, val)
 def __init__(self, extras=sb.NotSpecified, post_register=False):
     self.post_register = post_register
     if post_register and extras not in (None, {}, sb.NotSpecified):
         msg = "Sorry, can't specify ``extras`` and ``post_register`` at the same time"
         raise ProgrammerError(msg)
     spec = sb.listof(
         sb.tuple_spec(sb.string_spec(), sb.listof(sb.string_spec())))
     self.extras = spec.normalise(Meta({}, []), extras)
예제 #11
0
파일: tile.py 프로젝트: mic159/photons-core
async def set_chain_state(collector, target, reference, artifact, **kwargs):
    """
    Set the state of colors on your tile

    ``lan:set_chain_state d073d5f09124 -- '{"colors": [[[0, 0, 0, 3500], [0, 0, 0, 3500], ...], [[0, 0, 1, 3500], ...], ...], "tile_index": 1, "length": 1, "x": 0, "y": 0, "width": 8}'``

    Where the colors is a grid of 8 rows of 8 ``[h, s, b, k]`` values.
    """
    options = collector.configuration["photons_app"].extra_as_json

    if "colors" in options:
        spec = sb.listof(
            sb.listof(
                list_spec(sb.integer_spec(), sb.float_spec(), sb.float_spec(),
                          sb.integer_spec())))
        colors = spec.normalise(Meta.empty().at("colors"), options["colors"])

        row_lengths = [len(row) for row in colors]
        if len(set(row_lengths)) != 1:
            raise PhotonsAppError(
                "Please specify colors as a grid with the same length rows",
                got=row_lengths)

        num_cells = sum(len(row) for row in colors)
        if num_cells != 64:
            raise PhotonsAppError("Please specify 64 colors", got=num_cells)

        cells = []
        for row in colors:
            for col in row:
                cells.append({
                    "hue": col[0],
                    "saturation": col[1],
                    "brightness": col[2],
                    "kelvin": col[3]
                })

        options["colors"] = cells
    else:
        raise PhotonsAppError(
            "Please specify colors in options after -- as a grid of [h, s, b, k]"
        )

    missing = []
    for field in TileMessages.SetState64.Payload.Meta.all_names:
        if field not in options and field not in ("duration", "reserved6"):
            missing.append(field)

    if missing:
        raise PhotonsAppError("Missing options for the SetTileState message",
                              missing=missing)

    options["res_required"] = False
    msg = TileMessages.SetState64.empty_normalise(**options)
    await target.script(msg).run_with_all(reference)
예제 #12
0
파일: roles.py 프로젝트: delfick/aws_syncr
    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_spec(), MergedOptionStringFormatter, expected_type=six.string_types)
        role_name = meta.key_names()['_key_name_0']

        original_permission = sb.listof(permission_dict()).normalise(meta.at("permission"), NotSpecified if "permission" not in val else val["permission"])
        deny_permission = sb.listof(permission_dict(effect='Deny')).normalise(meta.at("deny_permission"), NotSpecified if "deny_permission" not in val else val["deny_permission"])
        allow_permission = sb.listof(permission_dict(effect='Allow')).normalise(meta.at("allow_permission"), NotSpecified if "allow_permission" not in val else val["allow_permission"])

        allow_to_assume_me = sb.listof(trust_dict("principal")).normalise(meta.at("allow_to_assume_me"), val.get("allow_to_assume_me", NotSpecified))
        disallow_to_assume_me = sb.listof(trust_dict("notprincipal")).normalise(meta.at("disallow_to_assume_me"), val.get("disallow_to_assume_me", NotSpecified))

        if not allow_to_assume_me and not disallow_to_assume_me:
            raise BadSpecValue("Roles must have either allow_to_assume_me or disallow_to_assume_me specified", meta=meta)

        val = val.wrapped()
        val['trust'] = allow_to_assume_me + disallow_to_assume_me
        val['permission'] = original_permission + deny_permission + allow_permission
        return sb.create_spec(Role
            , name = sb.overridden(role_name)
            , description = formatted_string
            , attached_policies = sb.listof(formatted_string)
            , trust = sb.container_spec(Document, sb.listof(trust_statement_spec('role', role_name)))
            , permission = sb.container_spec(Document, sb.listof(permission_statement_spec('role', role_name)))
            , make_instance_profile = sb.defaulted(sb.boolean(), False)
            ).normalise(meta, val)
예제 #13
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)
                )
            )
예제 #14
0
    def pack(self, meta, val):
        if type(val) not in (bytes, bitarray):
            try:
                if type(val) is not list:
                    raise BadSpecValue("Not a list")

                items = sb.listof(sb.dictionary_spec()).normalise(meta, val)
            except BadSpecValue as error:
                raise BadSpecValue(
                    "Sorry, many fields only supports a list of dictionary of values",
                    error=error)
            else:
                res = []
                for i, v in enumerate(items):
                    nxt = self.kls(**v)
                    spec = self.bytes_spec_for(nxt)
                    if hasattr(self.kls.Meta, "cache"):
                        items = tuple(sorted(nxt.items()))
                        if items not in self.kls.Meta.cache:
                            self.kls.Meta.cache[items] = nxt.pack()
                        packd = self.kls.Meta.cache[items]
                    else:
                        packd = nxt.pack()
                    res.append(spec.normalise(meta.indexed_at(i), packd))
                val = functools.reduce(operator.add, res)

        # The spec is likely a T.Bytes and will ensure we have enough bytes length in the result
        return self.spec.normalise(meta, val)
예제 #15
0
    def netscaler_spec(self):
        class to_boolean(Spec):
            def setup(self, spec):
                self.spec = spec

            def normalise_either(self, meta, val):
                val = self.spec.normalise(meta, val)

                if type(val) is bool:
                    return val

                if val == 'False':
                    return False
                elif val == 'True':
                    return True
                raise BadConfiguration("Expected a boolean", got=val, meta=meta)

        return create_spec(netscaler_specs.NetScaler
            , host = required(formatted(string_spec(), formatter=MergedOptionStringFormatter))
            , dry_run = to_boolean(formatted(overridden("{bespin.dry_run}"), formatter=MergedOptionStringFormatter))

            , username = required(formatted(string_spec(), formatter=MergedOptionStringFormatter))
            , configuration_username = optional_spec(formatted(string_spec(), formatter=MergedOptionStringFormatter))

            , password = delayed(required(formatted(string_spec(), formatter=MergedOptionStringFormatter)))
            , configuration_password = optional_spec(formatted(string_spec(), formatter=MergedOptionStringFormatter))

            , verify_ssl = defaulted(boolean(), True)
            , nitro_api_version = defaulted(formatted(string_spec(), formatter=MergedOptionStringFormatter), "v1")
            , configuration = optional_spec(netscaler_specs.configuration_spec())
            , syncable_environments = optional_spec(listof(valid_environment_spec()))
            )
예제 #16
0
    def normalise(self, meta, val):
        from harpoon.option_spec.harpoon_specs import HarpoonSpec
        if "content" in val or "context" in val:
            spec = sb.set_options(mtime=sb.optional_spec(sb.integer_spec()), dest=sb.required(sb.formatted(sb.string_spec(), formatter=MergedOptionStringFormatter)), content=sb.string_spec(), context=sb.optional_spec(HarpoonSpec().context_spec))
            result = spec.normalise(meta, val)
            if result["content"] != "" and result["context"] is not NotSpecified:
                raise BadOption("Please don't specify both context and content")

            mtime = result["mtime"]
            if mtime is NotSpecified:
                ctxt = type("Context", (object, ), {"use_git": True})()
                mtime = meta.everything["mtime"](ctxt)
            context_name = "{0}-{1}-mtime({2})".format(hashlib.md5(result['content'].encode('utf-8')).hexdigest(), result["dest"].replace("/", "-").replace(" ", "--"), mtime)
            extra_context = (result["content"], context_name)
            if result["context"] is not NotSpecified:
                context_name = "{0}.tar".format(context_name)
                extra_context = ({"context": result["context"]}, context_name)

            return Command(("ADD", "{0} {1}".format(context_name, result["dest"])), extra_context)
        else:
            spec = sb.set_options(
                  get=sb.required(sb.listof(sb.formatted(sb.string_spec(), formatter=MergedOptionStringFormatter)))
                , prefix = sb.defaulted(sb.string_spec(), "")
                )
            result = spec.normalise(meta, val)

            final = []
            for val in result["get"]:
                final.append(Command(("ADD", "{0} {1}/{2}".format(val, result["prefix"], val))))
            return final
예제 #17
0
def get_from_env(wanted):
    """Get environment variables from the env"""
    env = sb.listof(env_spec()).normalise(Meta({}, []), wanted)
    missing = [e.env_name for e in env if e.missing]
    if missing:
        raise BespinError("Missing environment variables", missing=missing)
    return dict(e.pair for e in env)
예제 #18
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)
예제 #19
0
    def bespin_spec(self):
        """Spec for bespin options"""
        formatted_string = formatted(string_spec(),
                                     MergedOptionStringFormatter,
                                     expected_type=six.string_types)
        formatted_boolean = formatted(boolean(),
                                      MergedOptionStringFormatter,
                                      expected_type=bool)

        return create_spec(Bespin,
                           validators.deprecated_key(
                               "region",
                               "Please use ``environments.<env>.region``"),
                           config=file_spec(),
                           configuration=any_spec(),
                           assume_role=optional_spec(string_spec()),
                           extra=defaulted(string_spec(), ""),
                           dry_run=defaulted(boolean(), False),
                           flat=defaulted(boolean(), False),
                           environment=optional_spec(string_spec()),
                           no_assume_role=defaulted(formatted_boolean, False),
                           chosen_task=defaulted(formatted_string,
                                                 "list_tasks"),
                           chosen_stack=defaulted(formatted_string, ""),
                           chosen_artifact=defaulted(formatted_string, ""),
                           extra_imports=listof(imports.import_spec()))
예제 #20
0
    def normalise(self, meta, val):
        result = []
        for index, item in enumerate(
                sb.listof(sb.any_spec()).normalise(meta, val)):
            s3_spec = s3_specs(item, self.self_type, self.self_name)
            iam_spec = iam_specs(item, self.self_type, self.self_name)
            kms_spec = kms_specs(item, self.self_type, self.self_name)
            arn_spec = arn_specs(item, self.self_type, self.self_name)

            if isinstance(item, six.string_types):
                result.append(item)
            else:
                types = (("iam", iam_spec), ("kms", kms_spec), ("s3", s3_spec),
                         ("arn", arn_spec))
                for typ, spec in types:
                    if typ in item:
                        if self.only and typ not in self.only:
                            raise BadPolicy(
                                "Sorry, don't support this resource type here",
                                wanted=typ,
                                available=self.only,
                                meta=meta)

                        for found in spec.normalise(
                                meta.indexed_at(index).at(typ), item[typ]):
                            result.append(found)
        return sorted(result)
예제 #21
0
    def setup_addon_register(self, photons_app, __main__):
        """Setup our addon register"""
        # Create the addon getter and register the crosshair namespace
        self.addon_getter = AddonGetter()
        self.addon_getter.add_namespace("lifx.photons", Result.FieldSpec(),
                                        Addon.FieldSpec())

        # Initiate the addons from our configuration
        register = Register(self.addon_getter, self)

        if "addons" in photons_app:
            addons = photons_app["addons"]
            if type(addons) in (MergedOptions, dict) or getattr(
                    addons, "is_dict", False):
                spec = sb.dictof(sb.string_spec(), sb.listof(sb.string_spec()))
                meta = Meta(photons_app, []).at("addons")
                for namespace, adns in spec.normalise(meta, addons).items():
                    register.add_pairs(*[(namespace, adn) for adn in adns])
        elif photons_app.get("default_activate_all_modules"):
            register.add_pairs(("lifx.photons", "__all__"))

        if __main__ is not None:
            register.add_pairs(("lifx.photons", "__main__"))

        # Import our addons
        register.recursive_import_known()

        # Resolve our addons
        register.recursive_resolve_imported()

        return register
예제 #22
0
    def wait_condition_spec(self):
        """Spec for a wait_condition block"""
        from harpoon.option_spec import image_objs
        formatted_string = formatted(string_spec(), formatter=MergedOptionStringFormatter)
        return create_spec(image_objs.WaitCondition
            , harpoon = formatted(overridden("{harpoon}"), formatter=MergedOptionStringFormatter)
            , timeout = defaulted(integer_spec(), 300)
            , wait_between_attempts = defaulted(float_spec(), 5)

            , greps = optional_spec(dictof(formatted_string, formatted_string))
            , command = optional_spec(listof(formatted_string))
            , port_open = optional_spec(listof(integer_spec()))
            , file_value = optional_spec(dictof(formatted_string, formatted_string))
            , curl_result = optional_spec(dictof(formatted_string, formatted_string))
            , file_exists = optional_spec(listof(formatted_string))
            )
class Result(dictobj.Spec):
    specs = dictobj.Field(sb.dictof(spec_key_spec(), sb.has("normalise")))
    extra = dictobj.Field(
        no_such_key_spec("Use extras instead (notice the s!)"))
    extras = dictobj.Field(
        sb.listof(sb.tuple_spec(sb.string_spec(),
                                sb.tupleof(sb.string_spec()))))
예제 #24
0
class array_command_spec(many_item_formatted_spec):
    value_name = "Command"
    specs = [
        # First item is just a string
        sb.string_spec()

        # Second item is a required list of either dicts or strings
        ,
        sb.required(
            sb.listof(
                sb.match_spec(
                    (dict, complex_ADD_spec()),
                    (six.string_types + (list, ),
                     sb.formatted(sb.string_spec(),
                                  formatter=MergedOptionStringFormatter)))))
    ]

    def create_result(self, action, command, meta, val, dividers):
        if callable(command) or isinstance(command, six.string_types):
            command = [command]

        result = []
        for cmd in command:
            if not isinstance(cmd, list):
                cmd = [cmd]

            for c in cmd:
                if isinstance(c, Command):
                    result.append(c)
                else:
                    result.append(Command((action, c)))
        return result
예제 #25
0
파일: actions.py 프로젝트: carukc/bespin
def get_from_env(wanted):
    """Get environment variables from the env"""
    env = sb.listof(env_spec()).normalise(Meta({}, []), wanted)
    missing = [e.env_name for e in env if e.missing]
    if missing:
        raise BespinError("Missing environment variables", missing=missing)
    return dict(e.pair for e in env)
예제 #26
0
    def normalise(self, meta, val):
        if "content" in val:
            spec = sb.set_options(dest=sb.required(
                sb.formatted(sb.string_spec(),
                             formatter=MergedOptionStringFormatter)),
                                  content=sb.string_spec())
            result = spec.normalise(meta, val)
            context_name = "{0}-{1}".format(
                hashlib.md5(result['content'].encode('utf-8')).hexdigest(),
                result["dest"].replace("/", "-").replace(" ", "--"))
            return Command(
                ("ADD", "{0} {1}".format(context_name, result["dest"])),
                (result["content"], context_name))
        else:
            spec = sb.set_options(get=sb.required(
                sb.listof(
                    sb.formatted(sb.string_spec(),
                                 formatter=MergedOptionStringFormatter))),
                                  prefix=sb.defaulted(sb.string_spec(), ""))
            result = spec.normalise(meta, val)

            final = []
            for val in result["get"]:
                final.append(
                    Command(
                        ("ADD", "{0} {1}/{2}".format(val, result["prefix"],
                                                     val))))
            return final
예제 #27
0
    def bespin_spec(self):
        """Spec for bespin options"""
        formatted_string = formatted(string_spec(), MergedOptionStringFormatter, expected_type=six.string_types)
        formatted_boolean = formatted(boolean(), MergedOptionStringFormatter, expected_type=bool)

        return create_spec(Bespin
            , validators.deprecated_key("region", "Please use ``environments.<env>.region``")

            , config = file_spec()
            , configuration = any_spec()

            , assume_role = optional_spec(string_spec())

            , dry_run = defaulted(boolean(), False)
            , flat = defaulted(boolean(), False)
            , environment = optional_spec(string_spec())

            , no_assume_role = defaulted(formatted_boolean, False)

            , chosen_task = defaulted(formatted_string, "list_tasks")
            , chosen_stack = defaulted(formatted_string, "")
            , chosen_artifact = defaulted(formatted_string, "")

            , extra_imports = listof(imports.import_spec())
            )
예제 #28
0
    def netscaler_spec(self):
        class to_boolean(Spec):
            def setup(self, spec):
                self.spec = spec

            def normalise_either(self, meta, val):
                val = self.spec.normalise(meta, val)

                if type(val) is bool:
                    return val

                if val == 'False':
                    return False
                elif val == 'True':
                    return True
                raise BadConfiguration("Expected a boolean", got=val, meta=meta)

        return create_spec(netscaler_specs.NetScaler
            , host = required(formatted(string_spec(), formatter=MergedOptionStringFormatter))
            , dry_run = to_boolean(formatted(overridden("{bespin.dry_run}"), formatter=MergedOptionStringFormatter))

            , username = required(formatted(string_spec(), formatter=MergedOptionStringFormatter))
            , configuration_username = optional_spec(formatted(string_spec(), formatter=MergedOptionStringFormatter))

            , password = delayed(required(formatted(string_spec(), formatter=MergedOptionStringFormatter)))
            , configuration_password = optional_spec(formatted(string_spec(), formatter=MergedOptionStringFormatter))

            , verify_ssl = defaulted(boolean(), True)
            , nitro_api_version = defaulted(formatted(string_spec(), formatter=MergedOptionStringFormatter), "v1")
            , configuration = optional_spec(netscaler_specs.configuration_spec())
            , syncable_environments = optional_spec(listof(valid_environment_spec()))
            )
예제 #29
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)))
예제 #30
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_spec(),
                                        MergedOptionStringFormatter,
                                        expected_type=six.string_types)
        role_name = meta.key_names()['_key_name_0']

        original_permission = sb.listof(permission_dict()).normalise(
            meta.at("permission"),
            NotSpecified if "permission" not in val else val["permission"])
        deny_permission = sb.listof(permission_dict(effect='Deny')).normalise(
            meta.at("deny_permission"), NotSpecified
            if "deny_permission" not in val else val["deny_permission"])
        allow_permission = sb.listof(
            permission_dict(effect='Allow')).normalise(
                meta.at("allow_permission"), NotSpecified
                if "allow_permission" not in val else val["allow_permission"])

        allow_to_assume_me = sb.listof(trust_dict("principal")).normalise(
            meta.at("allow_to_assume_me"),
            val.get("allow_to_assume_me", NotSpecified))
        disallow_to_assume_me = sb.listof(
            trust_dict("notprincipal")).normalise(
                meta.at("disallow_to_assume_me"),
                val.get("disallow_to_assume_me", NotSpecified))

        if not allow_to_assume_me and not disallow_to_assume_me:
            raise BadSpecValue(
                "Roles must have either allow_to_assume_me or disallow_to_assume_me specified",
                meta=meta)

        val = val.wrapped()
        val['trust'] = allow_to_assume_me + disallow_to_assume_me
        val['permission'] = original_permission + deny_permission + allow_permission
        return sb.create_spec(
            Role,
            name=sb.overridden(role_name),
            description=formatted_string,
            attached_policies=sb.listof(formatted_string),
            trust=sb.container_spec(
                Document, sb.listof(trust_statement_spec('role', role_name))),
            permission=sb.container_spec(
                Document,
                sb.listof(permission_statement_spec('role', role_name))),
            make_instance_profile=sb.defaulted(sb.boolean(),
                                               False)).normalise(meta, val)
예제 #31
0
    def add_configuration(self, configuration, collect_another_source, done,
                          result, src):
        """Used to add a file to the configuration, result here is the yaml.load of the src"""
        def make_mtime_func(source):
            """Lazily calculate the mtime to avoid wasted computation"""
            return lambda context: self.get_committime_or_mtime(
                context, source)

        if "harpoon" in result:
            if "extra_files" in result["harpoon"]:
                spec = sb.listof(
                    sb.formatted(sb.string_spec(),
                                 formatter=MergedOptionStringFormatter))
                meta = Meta(MergedOptions.using(result),
                            []).at("harpoon").at("extra_files")
                for extra in spec.normalise(meta,
                                            result["harpoon"]["extra_files"]):
                    if os.path.abspath(extra) not in done:
                        if not os.path.exists(extra):
                            raise BadConfiguration(
                                "Specified extra file doesn't exist",
                                extra=extra,
                                source=src)
                        collect_another_source(extra)

        if "images" in result and "__images_from__" in result["images"]:
            images_from_path = result["images"]["__images_from__"]

            if isinstance(images_from_path, six.string_types):
                images_from_path = [images_from_path]

            for ifp in images_from_path:

                if not ifp.startswith("/"):
                    ifp = os.path.join(os.path.dirname(src), ifp)

                if not os.path.exists(ifp) or not os.path.isdir(ifp):
                    raise self.BadConfigurationErrorKls(
                        "Specified folder for other configuration files points to a folder that doesn't exist",
                        path="images.__images_from__",
                        value=ifp)

                for root, dirs, files in os.walk(ifp):
                    for fle in files:
                        location = os.path.join(root, fle)
                        if fle.endswith(".yml") or fle.endswith(".yaml"):
                            collect_another_source(
                                location,
                                prefix=[
                                    "images",
                                    os.path.splitext(os.path.basename(fle))[0]
                                ],
                                extra={"mtime": make_mtime_func(location)})

            del result["images"]["__images_from__"]

        if "mtime" not in result:
            result["mtime"] = make_mtime_func(src)
        configuration.update(result, source=src)
예제 #32
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
                , validators.deprecated_key("use_git_timestamps", "Since docker 1.8, timestamps no longer invalidate the docker layer cache")

                , include = listof(string_spec())
                , exclude = listof(string_spec())
                , enabled = defaulted(boolean(), True)
                , find_options = string_spec()

                , parent_dir = directory_spec(formatted(defaulted(string_spec(), "{config_root}"), formatter=MergedOptionStringFormatter))
                , use_gitignore = defaulted(boolean(), False)
                , ignore_find_errors = defaulted(boolean(), False)
                )
            )
class Addon(dictobj.Spec):
    name = dictobj.Field(sb.string_spec)
    extras = dictobj.Field(
        sb.listof(sb.tuple_spec(sb.string_spec(), sb.string_spec())))
    resolver = dictobj.Field(sb.any_spec)
    namespace = dictobj.Field(sb.string_spec)

    class BadHook(DelfickError):
        desc = "Bad Hook"

    @property
    def resolved(self):
        errors = []
        if getattr(self, "_resolved", None) is None:
            try:
                self._resolved = list(self.resolver())
            except Exception as error:
                errors.append(
                    self.BadHook("Failed to resolve a hook",
                                 name=self.name,
                                 namespace=self.namespace,
                                 error=str(error)))

        if errors:
            raise self.BadHook(_errors=errors)

        return self._resolved

    def process(self, collector):
        for result in self.resolved:
            if collector is not None:
                collector.register_converters(result.get("specs", {}), Meta,
                                              collector.configuration,
                                              sb.NotSpecified)

    def post_register(self, **kwargs):
        list(self.resolver(post_register=True, **kwargs))

    def unresolved_dependencies(self):
        for namespace, name in self.extras:
            yield (namespace, name)

    def resolved_dependencies(self):
        for result in self.resolved:
            for namespace, names in result.get("extras", []):
                if not isinstance(names, (tuple, list)):
                    names = (names, )
                for name in names:
                    yield (namespace, name)

    def dependencies(self, all_deps):
        for dep in self.unresolved_dependencies():
            yield dep
        if hasattr(self, "_resolved"):
            for dep in self.resolved_dependencies():
                yield dep
예제 #34
0
 def wait_condition_spec(self):
     """Spec for a wait_condition block"""
     from harpoon.option_spec import image_objs
     formatted_string = formatted(string_spec(),
                                  formatter=MergedOptionStringFormatter)
     return create_spec(
         image_objs.WaitCondition,
         harpoon=formatted(overridden("{harpoon}"),
                           formatter=MergedOptionStringFormatter),
         timeout=defaulted(integer_spec(), 300),
         wait_between_attempts=defaulted(float_spec(), 5),
         greps=optional_spec(dictof(formatted_string, formatted_string)),
         command=optional_spec(listof(formatted_string)),
         port_open=optional_spec(listof(integer_spec())),
         file_value=optional_spec(dictof(formatted_string,
                                         formatted_string)),
         curl_result=optional_spec(
             dictof(formatted_string, formatted_string)),
         file_exists=optional_spec(listof(formatted_string)))
예제 #35
0
class acl_statement_spec(statement_spec):
    args = lambda s, self_type, self_name: {
        "grants": sb.listof(acl_grant_spec("grant", "grant"))
    }
    required = ["grants"]
    final_kls = lambda s, *args, **kwargs: lambda owner: {
        "AccessControlPolicy": {
            "Grants": [g(owner) for g in kwargs["grants"]]
        }
    }
예제 #36
0
class grant_statement_spec(statement_spec):
    args = lambda s, self_type, self_name: {
        'grantee': sb.required(resource_spec(self_type, self_name, only="iam")
                               ),
        'retiree': resource_spec(self_type, self_name, only="iam"),
        'operations': sb.required(sb.listof(sb.string_spec())),
        'constraints': sb.any_spec(),
        'grant_tokens': sb.any_spec()
    }
    final_kls = lambda s, *args, **kwargs: GrantStatement(*args, **kwargs)
예제 #37
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)
        bucket_name = meta.key_names()['_key_name_0']

        original_permission = sb.listof(resource_policy_dict()).normalise(
            meta.at("permission"),
            NotSpecified if "permission" not in val else val["permission"])
        deny_permission = sb.listof(
            resource_policy_dict(effect='Deny')).normalise(
                meta.at("deny_permission"), NotSpecified
                if "deny_permission" not in val else val["deny_permission"])
        allow_permission = sb.listof(
            resource_policy_dict(effect='Allow')).normalise(
                meta.at("allow_permission"), NotSpecified
                if "allow_permission" not in val else val["allow_permission"])

        val = val.wrapped()
        val['permission'] = original_permission + deny_permission + allow_permission
        return sb.create_spec(
            Bucket,
            name=sb.overridden(bucket_name),
            location=sb.required(formatted_string),
            permission=sb.container_spec(
                Document,
                sb.listof(resource_policy_statement_spec(
                    'bucket', bucket_name))),
            tags=sb.dictof(sb.string_spec(),
                           formatted_string)).normalise(meta, val)
예제 #38
0
    def add_configuration(self, configuration, collect_another_source, done, result, src):
        """Used to add a file to the configuration, result here is the yaml.load of the src"""
        configuration.update(result, dont_prefix=[dictobj], source=src)

        if "bespin" in configuration:
            if "extra_files" in configuration["bespin"]:
                for extra in sb.listof(sb.formatted(sb.string_spec(), formatter=MergedOptionStringFormatter)).normalise(Meta(configuration, [("bespin", ""), ("extra_files", "")]), configuration["bespin"]["extra_files"]):
                    if os.path.abspath(extra) not in done:
                        if not os.path.exists(extra):
                            raise BadConfiguration("Specified extra file doesn't exist", extra=extra, source=src)
                        collect_another_source(extra)
예제 #39
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)

        gateway_name = meta.key_names()['_key_name_0']
        gateway_location = formatted_string().normalise(meta.at('location'), val.get('location', ''))

        return sb.create_spec(Gateway
            , name = sb.overridden(gateway_name)
            , location = sb.required(formatted_string())
            , stages = sb.listof(formatted_string())
            , api_keys = sb.listof(api_key_spec())
            , domain_names = sb.dictof(sb.string_spec(), custom_domain_name_spec(gateway_location))
            , resources = sb.listof(gateway_resource_spec())
            ).normalise(meta, val)
예제 #40
0
class resource_policy_statement_spec(statement_spec):
    args = lambda s, self_type, self_name: {
        'sid': sb.string_spec(),
        'effect': sb.string_choice_spec(choices=["Deny", "Allow"]),
        'action': sb.listof(sb.string_spec()),
        ("not", "action"): sb.listof(sb.string_spec()),
        'resource': resource_spec(self_type, self_name),
        ('not', 'resource'): resource_spec(self_type, self_name),
        'principal': sb.listof(principal_spec(self_type, self_name)),
        ('not', 'principal'): sb.listof(principal_spec(self_type, self_name)),
        'condition': sb.dictionary_spec(),
        ('not', 'condition'): sb.dictionary_spec()
    }
    validators = [
        validators.deprecated_key('allow', "Use 'effect: Allow|Deny' instead"),
        validators.deprecated_key('disallow',
                                  "Use 'effect: Allow|Deny' instead")
    ]
    final_kls = lambda s, *args, **kwargs: ResourcePolicyStatement(
        *args, **kwargs)
예제 #41
0
    def normalise(self, meta, val):
        default_location = ""

        if "identity" not in self.resource:
            raise BadPolicy("Generic arn specified without specifying 'identity'", meta=meta)

        location = self.location(meta)
        identities = sb.listof(sb.formatted(sb.string_spec(), formatter=MergedOptionStringFormatter)).normalise(meta.at("identity"), self.resource.get("identity"))

        for account_id in self.accounts(meta):
            for identity in identities:
                yield "arn:aws:{0}:{1}:{2}:{3}".format(val, location, account_id, identity)
예제 #42
0
파일: tile.py 프로젝트: mic159/photons-core
async def set_tile_positions(collector, target, reference, **kwargs):
    """
    Set the positions of the tiles in your chain.

    ``lan:set_tile_positions d073d5f09124 -- '[[0, 0], [-1, 0], [-1, 1]]'``
    """
    extra = collector.configuration["photons_app"].extra_as_json
    positions = sb.listof(sb.listof(sb.float_spec())).normalise(
        Meta.empty(), extra)
    if any(len(position) != 2 for position in positions):
        raise PhotonsAppError(
            "Please enter positions as a list of two item lists of user_x, user_y"
        )

    async with target.session() as afr:
        for i, (user_x, user_y) in enumerate(positions):
            msg = TileMessages.SetUserPosition(tile_index=i,
                                               user_x=user_x,
                                               user_y=user_y,
                                               res_required=False)
            await target.script(msg).run_with_all(reference, afr)
예제 #43
0
    def normalise_filled(self, meta, val):
        val = sb.dictof(sb.string_choice_spec(["s3", "inline", "directory"]),
                        sb.any_spec()).normalise(meta, val)
        if not val:
            raise BadSpecValue(
                "Please specify s3, inline or directory for your code",
                meta=meta)

        if len(val) > 1:
            raise BadSpecValue(
                "Please only specify one of s3, inline or directory for your code",
                got=list(val.keys()),
                meta=meta)

        formatted_string = sb.formatted(sb.string_spec(),
                                        formatter=MergedOptionStringFormatter)
        if "s3" in val:
            return sb.create_spec(
                S3Code,
                key=formatted_string,
                bucket=formatted_string,
                version=sb.defaulted(sb.string_spec(),
                                     NotSpecified)).normalise(meta, val['s3'])
        elif "inline" in val:
            path = [p for p, _ in meta._path]
            path.pop()
            runtime = meta.everything['.'.join(path)].get("runtime", "python")
            runtime = sb.formatted(
                sb.string_spec(),
                formatter=MergedOptionStringFormatter).normalise(
                    meta.at("runtime"), runtime)

            return sb.create_spec(InlineCode,
                                  code=sb.string_spec(),
                                  runtime=sb.overridden(runtime)).normalise(
                                      meta, {"code": val['inline']})
        else:
            directory = val['directory']
            if isinstance(val['directory'], six.string_types):
                directory = {"directory": val['directory']}

            if 'directory' in directory:
                formatted_string = sb.formatted(
                    sb.string_spec(), formatter=MergedOptionStringFormatter)
                directory['directory'] = formatted_string.normalise(
                    meta.at("directory").at("directory"),
                    directory['directory'])

            return sb.create_spec(DirectoryCode,
                                  directory=sb.directory_spec(),
                                  exclude=sb.listof(
                                      sb.string_spec())).normalise(
                                          meta, directory)
예제 #44
0
    def password_spec(self):
        formatted_string = formatted(string_spec(), formatter=MergedOptionStringFormatter)
        return create_spec(stack_objs.Password
            , name = formatted(overridden("{_key_name_1}"), formatter=MergedOptionStringFormatter)
            , bespin = formatted(overridden("{bespin}"), formatter=MergedOptionStringFormatter)

            , KMSMasterKey = required(formatted_string)
            , encryption_context = optional_spec(dictionary_spec())
            , grant_tokens = optional_spec(listof(formatted_string))
            , crypto_text = required(formatted_string)

            , vars = dictionary_spec()
            )
예제 #45
0
    def password_spec(self):
        formatted_string = formatted(string_spec(), formatter=MergedOptionStringFormatter)
        return create_spec(stack_objs.Password
            , name = formatted(overridden("{_key_name_1}"), formatter=MergedOptionStringFormatter)
            , bespin = formatted(overridden("{bespin}"), formatter=MergedOptionStringFormatter)

            , KMSMasterKey = required(formatted_string)
            , encryption_context = optional_spec(dictionary_spec())
            , grant_tokens = optional_spec(listof(formatted_string))
            , crypto_text = required(formatted_string)

            , vars = dictionary_spec()
            )
예제 #46
0
class website_statement_spec(statement_spec):
    formatted_string = sb.formatted(sb.string_spec(),
                                    formatter=MergedOptionStringFormatter)
    args = lambda s, self_type, self_name: {
        (("sep", "_"), ("parts", ("index", "document"))):
        made_up_dict(s.formatted_string, ("Suffix", )),
        (("sep", "_"), ("parts", ("error", "document"))):
        made_up_dict(s.formatted_string, ("Key", )),
        (("sep", "_"), ("parts", ("redirect", "all", "requests", "to"))):
        redirect_all_requests_to_spec(s.formatted_string),
        (("sep", "_"), ("parts", ("routing", "rules"))):
        sb.listof(sb.dictionary_spec())
    }
    final_kls = lambda s, *args, **kwargs: WebsiteConfig(*args, **kwargs)
예제 #47
0
    def setup(self, **kwargs):
        account_spec = sb.set_options(
              account_id = sb.required(sb.string_spec())
            , role_to_assume = sb.required(sb.string_spec())
            )

        kwargs = sb.set_options(
              accounts = sb.required(sb.dictof(sb.string_spec(), account_spec))
            , ordered_accounts = sb.required(sb.listof(sb.string_spec()))
            , cloudability_auth_token = sb.required(sb.any_spec())
            ).normalise(Meta({}, []), kwargs)

        for key, val in kwargs.items():
            setattr(self, key, val)
예제 #48
0
    def normalise(self, meta, val):
        for bucket_key in sb.listof(sb.formatted(sb.string_spec(), formatter=MergedOptionStringFormatter)).normalise(meta, val):
            if bucket_key == "__self__" or bucket_key.startswith("__self__"):
                if self.self_type != "bucket":
                    raise BadPolicy("No __self__ bucket for this policy", meta=meta)
                else:
                    path = ""
                    if "/" in bucket_key:
                        path = bucket_key[bucket_key.find('/'):]
                    bucket_key = "{0}{1}".format(self.self_name, path)

            yield "arn:aws:s3:::{0}".format(bucket_key)
            if '/' not in bucket_key:
                yield "arn:aws:s3:::{0}/*".format(bucket_key)
예제 #49
0
    def normalise(self, meta, val):
        for bucket_key in sb.listof(sb.string_spec()).normalise(meta, val):
            if bucket_key == "__self__" or bucket_key.startswith("__self__"):
                if self.self_type != "bucket":
                    raise BadPolicy("No __self__ bucket for this policy",
                                    meta=meta)
                else:
                    path = ""
                    if "/" in bucket_key:
                        path = bucket_key[bucket_key.find('/'):]
                    bucket_key = "{0}{1}".format(self.self_name, path)

            yield "arn:aws:s3:::{0}".format(bucket_key)
            if '/' not in bucket_key:
                yield "arn:aws:s3:::{0}/*".format(bucket_key)
예제 #50
0
    def harpoon_spec(self):
        """Spec for harpoon options"""
        formatted_string = formatted(string_spec(), MergedOptionStringFormatter, expected_type=six.string_types)
        formatted_boolean = formatted(boolean(), MergedOptionStringFormatter, expected_type=bool)

        return create_spec(Harpoon
            , config = optional_spec(file_spec())

            , tag = optional_spec(string_spec())
            , extra = defaulted(formatted_string, "")
            , debug = defaulted(boolean(), False)
            , addons = dictof(string_spec(), listof(string_spec()))
            , artifact = optional_spec(formatted_string)
            , extra_files = listof(string_spec())
            , chosen_task = defaulted(formatted_string, "list_tasks")
            , chosen_image = defaulted(formatted_string, "")

            , flat = defaulted(formatted_boolean, False)
            , no_cleanup = defaulted(formatted_boolean, False)
            , interactive = defaulted(formatted_boolean, True)
            , silent_build = defaulted(formatted_boolean, False)
            , keep_replaced = defaulted(formatted_boolean, False)
            , ignore_missing = defaulted(formatted_boolean, False)
            , no_intervention = defaulted(formatted_boolean, False)
            , intervene_afterwards = defaulted(formatted_boolean, False)

            , do_push = defaulted(formatted_boolean, False)
            , only_pushable = defaulted(formatted_boolean, False)
            , docker_context = any_spec()
            , docker_context_maker = any_spec()

            , stdout = defaulted(any_spec(), sys.stdout)
            , tty_stdin = defaulted(any_spec(), None)
            , tty_stdout = defaulted(any_spec(), lambda: sys.stdout)
            , tty_stderr = defaulted(any_spec(), lambda: sys.stderr)
            )
예제 #51
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)
        bucket_name = meta.key_names()['_key_name_0']

        original_permission = sb.listof(resource_policy_dict()).normalise(meta.at("permission"), NotSpecified if "permission" not in val else val["permission"])
        deny_permission = sb.listof(resource_policy_dict(effect='Deny')).normalise(meta.at("deny_permission"), NotSpecified if "deny_permission" not in val else val["deny_permission"])
        allow_permission = sb.listof(resource_policy_dict(effect='Allow')).normalise(meta.at("allow_permission"), NotSpecified if "allow_permission" not in val else val["allow_permission"])

        val = val.wrapped()
        val['permission'] = original_permission + deny_permission + allow_permission
        return sb.create_spec(Bucket
            , name = sb.overridden(bucket_name)
            , location = sb.required(formatted_string)
            , permission = sb.container_spec(Document, sb.listof(resource_policy_statement_spec('bucket', bucket_name)))
            , tags = sb.dictof(sb.string_spec(), formatted_string)
            ).normalise(meta, val)
예제 #52
0
    def harpoon_spec(self):
        """Spec for harpoon options"""
        formatted_string = formatted(string_spec(),
                                     MergedOptionStringFormatter,
                                     expected_type=six.string_types)
        formatted_boolean = formatted(boolean(),
                                      MergedOptionStringFormatter,
                                      expected_type=bool)

        return create_spec(
            Harpoon,
            config=optional_spec(file_spec()),
            tag=optional_spec(string_spec()),
            extra=defaulted(formatted_string, ""),
            debug=defaulted(boolean(), False),
            addons=dictof(string_spec(), listof(string_spec())),
            artifact=optional_spec(formatted_string),
            extra_files=listof(string_spec()),
            chosen_task=defaulted(formatted_string, "list_tasks"),
            chosen_image=defaulted(formatted_string, ""),
            flat=defaulted(formatted_boolean, False),
            no_cleanup=defaulted(formatted_boolean, False),
            interactive=defaulted(formatted_boolean, True),
            silent_build=defaulted(formatted_boolean, False),
            keep_replaced=defaulted(formatted_boolean, False),
            ignore_missing=defaulted(formatted_boolean, False),
            no_intervention=defaulted(formatted_boolean, False),
            intervene_afterwards=defaulted(formatted_boolean, False),
            do_push=defaulted(formatted_boolean, False),
            only_pushable=defaulted(formatted_boolean, False),
            docker_context=any_spec(),
            docker_context_maker=any_spec(),
            stdout=defaulted(any_spec(), sys.stdout),
            tty_stdin=defaulted(any_spec(), None),
            tty_stdout=defaulted(any_spec(), lambda: sys.stdout),
            tty_stderr=defaulted(any_spec(), lambda: sys.stderr))
예제 #53
0
    def confirm_deployment_spec(self):
        return create_spec(deployment_check.ConfirmDeployment
            , deploys_s3_path = optional_spec(listof(stack_specs.s3_address()))
            , zero_instances_is_ok = defaulted(boolean(), False)
            , auto_scaling_group_name = optional_spec(formatted(string_spec(), formatter=MergedOptionStringFormatter))

            , url_checker = optional_spec(self.url_checker_spec)

            , sns_confirmation = optional_spec(create_spec(deployment_check.SNSConfirmation
                , validators.deprecated_key("auto_scaling_group_id", "Use ``confirm_deployment.auto_scaling_group_name``")
                , validators.deprecated_key("env", "Use ``stack.<stack>.env`` instead``")

                , timeout = defaulted(integer_spec(), 300)
                , version_message = required(formatted(string_spec(), formatter=MergedOptionStringFormatter))
                , deployment_queue = required(formatted(string_spec(), formatter=MergedOptionStringFormatter))
                ))
            )
예제 #54
0
    def accounts(self, meta):
        accounts = meta.everything["accounts"]
        default_account_id = self.default_account_id(meta)

        provided_accounts = sb.listof(sb.string_spec()).normalise(meta.at("account"), self.resource.get("account", []))
        if not provided_accounts:
            yield default_account_id

        for provided_account in provided_accounts:
            if not provided_account:
                yield ""
            else:
                if provided_account not in accounts:
                    raise BadPolicy("Unknown account specified", account=provided_account, meta=meta)
                else:
                    account_id = accounts[provided_account]

                yield account_id
예제 #55
0
    def normalise(self, meta, val):
        result = []
        for index, item in enumerate(sb.listof(sb.any_spec()).normalise(meta, val)):
            s3_spec = s3_specs(item, self.self_type, self.self_name)
            iam_spec = iam_specs(item, self.self_type, self.self_name)
            kms_spec = kms_specs(item, self.self_type, self.self_name)
            arn_spec = arn_specs(item, self.self_type, self.self_name)

            if isinstance(item, six.string_types):
                result.append(item)
            else:
                types = (("iam", iam_spec), ("kms", kms_spec), ("s3", s3_spec), ("arn", arn_spec))
                for typ, spec in types:
                    if typ in item:
                        if self.only and typ not in self.only:
                            raise BadPolicy("Sorry, don't support this resource type here", wanted=typ, available=self.only, meta=meta)

                        for found in spec.normalise(meta.indexed_at(index).at(typ), item[typ]):
                            result.append(found)
        return sorted(result)
예제 #56
0
파일: actions.py 프로젝트: henrikhch/bespin
def downtime(collector, stack, method="downtime", **kwargs):
    """Downtime this stack in alerting systems"""
    if stack.downtimer_options is NotSpecified:
        raise BespinError("Nothing to downtime!")

    env = sb.listof(env_spec()).normalise(Meta({}, []), ["USER", "DURATION", "COMMENT"])
    missing = [e.env_name for e in env if e.missing]
    if missing:
        raise BespinError("Missing environment variables", missing=missing)
    provided_env = dict(e.pair for e in env)

    author = provided_env["USER"]
    comment = provided_env["COMMENT"]
    duration = provided_env["DURATION"]

    downtimer = Downtimer(stack.downtimer_options, dry_run=collector.configuration["bespin"].dry_run)
    for system, options in stack.alerting_systems.items():
        downtimer.register_system(system, options)

    getattr(downtimer, method)(duration, author, comment)
예제 #57
0
    def normalise(self, meta, val):
        from harpoon.option_spec.harpoon_specs import HarpoonSpec
        formatted_string = sb.formatted(sb.string_spec(), formatter=MergedOptionStringFormatter)
        val = sb.apply_validators(meta, val, [validators.either_keys(["context"], ["content"], ["get"], ["formatted"])])

        if "get" in val:
            val = sb.create_spec(CommandAddExtra
                , get = sb.required(sb.listof(formatted_string))
                , prefix = sb.optional_spec(sb.string_spec())
                ).normalise(meta, val)

        if "context" in val:
            val = sb.create_spec(CommandContextAdd
                , validators.deprecated_key("mtime", "Since docker 1.8, timestamps no longer invalidate the docker layer cache")

                , dest = sb.required(formatted_string)
                , context = sb.required(HarpoonSpec().context_spec)
                ).normalise(meta, val)

        if "formatted" in val:
            val = sb.create_spec(CommandContentAdd
                , validators.deprecated_key("mtime", "Since docker 1.8, timestamps no longer invalidate the docker layer cache")

                , dest = sb.required(formatted_string)
                , content = sb.overridden(sb.NotSpecified)
                , formatted = sb.container_spec(CommandContentAddString, formatted_string)
                ).normalise(meta, val)

        if "content" in val:
            val = sb.create_spec(CommandContentAdd
                , validators.deprecated_key("mtime", "Since docker 1.8, timestamps no longer invalidate the docker layer cache")

                , dest = sb.required(formatted_string)
                , content = sb.match_spec(
                      (six.string_types, sb.container_spec(CommandContentAddString, sb.string_spec()))
                    , fallback = complex_ADD_from_image_spec()
                    )
                ).normalise(meta, val)

        return list(val.commands(meta))
예제 #58
0
    def normalise_filled(self, meta, val):
        val = sb.dictof(sb.string_choice_spec(["s3", "inline", "directory"]), sb.any_spec()).normalise(meta, val)
        if not val:
            raise BadSpecValue("Please specify s3, inline or directory for your code", meta=meta)

        if len(val) > 1:
            raise BadSpecValue("Please only specify one of s3, inline or directory for your code", got=list(val.keys()), meta=meta)

        formatted_string = sb.formatted(sb.string_spec(), formatter=MergedOptionStringFormatter)
        if "s3" in val:
            return sb.create_spec(S3Code
                , key = formatted_string
                , bucket = formatted_string
                , version = sb.defaulted(sb.string_spec(), NotSpecified)
                ).normalise(meta, val['s3'])
        elif "inline" in val:
            path = [p for p, _ in meta._path]
            path.pop()
            runtime = meta.everything['.'.join(path)].get("runtime", "python")
            runtime = sb.formatted(sb.string_spec(), formatter=MergedOptionStringFormatter).normalise(meta.at("runtime"), runtime)

            return sb.create_spec(InlineCode
                , code = sb.string_spec()
                , runtime = sb.overridden(runtime)
                ).normalise(meta, {"code": val['inline']})
        else:
            directory = val['directory']
            if isinstance(val['directory'], six.string_types):
                directory = {"directory": val['directory']}

            if 'directory' in directory:
                formatted_string = sb.formatted(sb.string_spec(), formatter=MergedOptionStringFormatter)
                directory['directory'] = formatted_string.normalise(meta.at("directory").at("directory"), directory['directory'])

            return sb.create_spec(DirectoryCode
                , directory = sb.directory_spec()
                , exclude = sb.listof(sb.string_spec())
                ).normalise(meta, directory)
예제 #59
0
    def setup_addon_register(self, harpoon):
        """Setup our addon register"""
        # Create the addon getter and register the crosshairs namespace
        self.addon_getter = AddonGetter()
        self.addon_getter.add_namespace("harpoon.crosshairs", Result.FieldSpec(), Addon.FieldSpec())

        # Initiate the addons from our configuration
        register = Register(self.addon_getter, self)

        if "addons" in harpoon:
            addons = harpoon["addons"]
            if type(addons) in (MergedOptions, dict) or getattr(addons, "is_dict", False):
                spec = sb.dictof(sb.string_spec(), sb.listof(sb.string_spec()))
                meta = Meta(harpoon, []).at("addons")
                for namespace, adns in spec.normalise(meta, addons).items():
                    register.add_pairs(*[(namespace, adn) for adn in adns])

        # Import our addons
        register.recursive_import_known()

        # Resolve our addons
        register.recursive_resolve_imported()

        return register
예제 #60
0
파일: netscaler.py 프로젝트: carukc/bespin
from bespin.formatter import MergedOptionStringFormatter
from bespin.errors import BadNetScaler

from input_algorithms.spec_base import Spec, dictof, listof, string_spec, container_spec, match_spec, overridden, formatted, set_options, any_spec, optional_spec
from input_algorithms.spec_base import NotSpecified
from input_algorithms.dictobj import dictobj
import requests
import logging
import json
import six
import re

log = logging.getLogger("bespin.option_spec.netscaler")

netscaler_binding_spec = lambda: container_spec(NetscalerBinding, match_spec(((list, ) + six.string_types, listof(string_spec())), (dict, set_options(tagged=listof(string_spec())))))

class valid_environment_spec(Spec):
    def normalise_filled(self, meta, val):
        if "environments" not in meta.everything:
            raise BespinError("Please specify {environments}")

        val = string_spec().normalise(meta, val)
        available = list(meta.everything["environments"].keys())
        if val not in available:
            raise BespinError("Please choose a valid environment", meta=meta, wanted=val, available=available)

        return val

class netscaler_config_spec(Spec):
    def normalise_filled(self, meta, val):
        typ = formatted(overridden("{_key_name_1}"), formatter=MergedOptionStringFormatter).normalise(meta, val)