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
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))
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 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))
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 , dest = sb.required(formatted_string) , mtime = sb.optional_spec(sb.integer_spec()) , context = sb.required(HarpoonSpec().context_spec) ).normalise(meta, val) if "formatted" in val: val = sb.create_spec(CommandContentAdd , dest = sb.required(formatted_string) , mtime = sb.optional_spec(sb.integer_spec()) , content = sb.overridden(sb.NotSpecified) , formatted = sb.container_spec(CommandContentAddString, formatted_string) ).normalise(meta, val) if "content" in val: val = sb.create_spec(CommandContentAdd , dest = sb.required(formatted_string) , mtime = sb.optional_spec(sb.integer_spec()) , 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))
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)
DomainName, name=sb.overridden(name), gateway_location=sb.overridden(self.gateway_location), zone=formatted_string(), stage=formatted_string(), base_path=sb.defaulted(formatted_string(), "(none)"), certificate=sb.required(certificate_spec())).normalise(meta, val) while result.zone and result.zone.endswith("."): result.zone = result.zone[:-1] return result formatted_dictionary_or_string = lambda: sb.match_spec( (six.string_types, formatted_string()), fallback=sb.dictof(sb.string_spec(), formatted_string())) mapping_spec = lambda: sb.create_spec( Mapping, content_type=sb.defaulted(formatted_string(), "application/json"), template=sb.defaulted(formatted_dictionary_or_string(), "$input.json('$')" )) class aws_resource_spec(Spec): def setup(self, method, resource_name): self.method = method self.resource_name = resource_name def normalise(self, meta, val):
if isinstance(val, Command): result.append(val) else: result.extend(val) return result class has_a_space(validators.Validator): def validate(self, meta, val): if ' ' not in val: raise BadOption( "Expected string to have a space (<ACTION> <COMMAND>)", meta=meta, got=val) return val string_command_spec = lambda: sb.container_spec( Command, sb.valid_string_spec(has_a_space())) # Only support ADD commands for the dictionary representation atm dict_key = sb.valid_string_spec(validators.choice("ADD")) dictionary_command_spec = lambda: convert_dict_command_spec( sb.dictof(dict_key, complex_ADD_spec())) # The main spec # We match against, strings, lists, dictionaries and Command objects with different specs command_spec = lambda: sb.match_spec( (six.string_types, string_command_spec()), (list, array_command_spec()), (dict, dictionary_command_spec()), (Command, sb.any_spec()))
def environments_spec(self): """Spec for each environment options""" return dictof( string_spec(), match_spec((str, copy_environment_spec()), (dict, self.environment_spec)))
required, integer_spec, directory_spec, delayed, Spec, ) from input_algorithms.dictobj import dictobj from textwrap import dedent import six valid_import_name = regexed("[a-zA-Z_][a-zA-Z_0-9]*(\.[a-zA-Z_][a-zA-Z_0-9]*)*:[a-zA-Z_][a-zA-Z_0-9]") formatted_dict_or_string_or_list = lambda: match_spec( (six.string_types, formatted(string_spec(), MergedOptionStringFormatter)), ((list,), lambda: listof(formatted_dict_or_string_or_list())), fallback=lambda: dictof(string_spec(), formatted_dict_or_string_or_list()), ) class dashboards_spec(Spec): def normalise(self, meta, val): val = dictionary_spec().normalise(meta, val).as_dict() if "/" not in val: val["/"] = {"is_index": True} return dictof(string_spec(), dashboard_spec()).normalise(meta, val) class dashboard_spec(Spec): def normalise(self, meta, val): val = dictionary_spec().normalise(meta, val)
spec = complex_ADD_spec() else: spec = complex_COPY_spec() result = [] for val in spec.normalise(meta.at(items[0]), items[1]): if isinstance(val, Command): result.append(val) else: result.extend(val) return result class has_a_space(validators.Validator): def validate(self, meta, val): if ' ' not in val: raise BadOption("Expected string to have a space (<ACTION> <COMMAND>)", meta=meta, got=val) return val string_command_spec = lambda: sb.container_spec(Command, sb.valid_string_spec(has_a_space())) # The main spec # We match against, strings, lists, dictionaries and Command objects with different specs command_spec = lambda: sb.match_spec( (six.string_types, string_command_spec()) , (list, array_command_spec()) , (dict, convert_dict_command_spec()) , (Command, sb.any_spec()) )
def environments_spec(self): """Spec for each environment options""" return dictof( string_spec() , match_spec((str, copy_environment_spec()), (dict, self.environment_spec)) )
result = sb.create_spec(DomainName , name = sb.overridden(name) , gateway_location = sb.overridden(self.gateway_location) , zone = formatted_string() , stage = formatted_string() , base_path = sb.defaulted(formatted_string(), "(none)") , certificate = sb.required(certificate_spec()) ).normalise(meta, val) while result.zone and result.zone.endswith("."): result.zone = result.zone[:-1] return result formatted_dictionary_or_string = lambda : sb.match_spec( (six.string_types, formatted_string()) , fallback = sb.dictof(sb.string_spec(), formatted_string()) ) mapping_spec = lambda: sb.create_spec(Mapping , content_type = sb.defaulted(formatted_string(), "application/json") , template = sb.defaulted(formatted_dictionary_or_string(), "$input.json('$')") ) class aws_resource_spec(Spec): def setup(self, method, resource_name): self.method = method self.resource_name = resource_name def normalise(self, meta, val): result = sb.create_spec(LambdaMethod , http_method = sb.overridden(self.method)
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)
num_results = len(results) if num_results >= self.value: return num_results return -1 Type.install(("Bool", 1, bool, bool), ("Int8", 8, "<b", int), ("Uint8", 8, "<B", int), ("BoolInt", 8, "<?", (bool, int)), ("Int16", 16, "<h", int), ("Uint16", 16, "<H", int), ("Int32", 32, "<i", int), ("Uint32", 32, "<I", int), ("Int64", 64, "<q", int), ("Uint64", 64, "<Q", int), ("Float", 32, "<f", float), ("Double", 64, "<d", float), ("Bytes", None, None, bytes), ("String", None, None, str), ("Reserved", None, None, bytes), ("CSV", None, None, (list, str, ",")), ("JSON", None, None, json)) json_spec = sb.match_spec( (bool, sb.any_spec()), (int, sb.any_spec()), (float, sb.any_spec()), (str, sb.any_spec()), (list, lambda: sb.listof(json_spec)), (type(None), sb.any_spec()), fallback=lambda: sb.dictof(sb.string_spec(), json_spec)) # Here so we don't have to instantiate these every time we get a value from a packet static_conversion_from_spec = { any: sb.any_spec(), bool: boolean(), float: float_spec(), (bool, int): boolean_as_int_spec(), json: json_spec }