def schema_completer(prefix): """ For tab-completion via argcomplete, return completion options. For the given prefix so far, return the possible options. Note that filtering via startswith happens after this list is returned. """ load_resources() components = prefix.split('.') # Completions for resource if len(components) == 1: choices = [r for r in resources.keys() if r.startswith(prefix)] if len(choices) == 1: choices += ['{}{}'.format(choices[0], '.')] return choices if components[0] not in resources.keys(): return [] # Completions for category if len(components) == 2: choices = ['{}.{}'.format(components[0], x) for x in ('actions', 'filters') if x.startswith(components[1])] if len(choices) == 1: choices += ['{}{}'.format(choices[0], '.')] return choices # Completions for item elif len(components) == 3: resource_mapping = schema.resource_vocabulary() return ['{}.{}.{}'.format(components[0], components[1], x) for x in resource_mapping[components[0]][components[1]]] return []
class SchemaDirectiveTest(unittest.TestCase): CustodianDirective.vocabulary = resource_vocabulary() def test_schema_resolver(self): self.assertTrue(CustodianSchema.resolve('mode.periodic')) self.assertTrue(CustodianSchema.resolve('aws.ec2.actions.stop')) self.assertEqual(CustodianSchema.resolve('aws.ec2').type, 'ec2')
def test_element_resolve(self): vocab = resource_vocabulary() self.assertEqual( ElementSchema.resolve(vocab, 'mode.periodic').type, 'periodic') self.assertEqual(ElementSchema.resolve(vocab, 'aws.ec2').type, 'ec2') self.assertEqual( ElementSchema.resolve(vocab, 'aws.ec2.actions.stop').type, 'stop') self.assertRaises(ValueError, ElementSchema.resolve, vocab, 'aws.ec2.actions.foo')
def init(): global INITIALIZED if INITIALIZED: return load_resources() CustodianDirective.vocabulary = resource_vocabulary() CustodianDirective.env = env = get_environment() INITIALIZED = True return env
def init(): global INITIALIZED if INITIALIZED: return load_resources() CustodianDirective.vocabulary = resource_vocabulary() CustodianDirective.definitions = generate_schema()['definitions'] CustodianDirective.env = env = get_environment() INITIALIZED = True return env
def schema_completer(prefix): """ For tab-completion via argcomplete, return completion options. For the given prefix so far, return the possible options. Note that filtering via startswith happens after this list is returned. """ from c7n import schema load_available() components = prefix.split('.') if components[0] in provider.clouds.keys(): cloud_provider = components.pop(0) provider_resources = provider.resources(cloud_provider) else: cloud_provider = 'aws' provider_resources = provider.resources('aws') components[0] = "aws.%s" % components[0] # Completions for resource if len(components) == 1: choices = [ r for r in provider.resources().keys() if r.startswith(components[0]) ] if len(choices) == 1: choices += ['{}{}'.format(choices[0], '.')] return choices if components[0] not in provider_resources.keys(): return [] # Completions for category if len(components) == 2: choices = [ '{}.{}'.format(components[0], x) for x in ('actions', 'filters') if x.startswith(components[1]) ] if len(choices) == 1: choices += ['{}{}'.format(choices[0], '.')] return choices # Completions for item elif len(components) == 3: resource_mapping = schema.resource_vocabulary(cloud_provider) return [ '{}.{}.{}'.format(components[0], components[1], x) for x in resource_mapping[components[0]][components[1]] ] return []
def schema_completer(prefix): """ For tab-completion via argcomplete, return completion options. For the given prefix so far, return the possible options. Note that filtering via startswith happens after this list is returned. """ from c7n import schema load_resources() components = prefix.split('.') if components[0] in provider.clouds.keys(): cloud_provider = components.pop(0) provider_resources = provider.resources(cloud_provider) else: cloud_provider = 'aws' provider_resources = provider.resources('aws') components[0] = "aws.%s" % components[0] # Completions for resource if len(components) == 1: choices = [r for r in provider.resources().keys() if r.startswith(components[0])] if len(choices) == 1: choices += ['{}{}'.format(choices[0], '.')] return choices if components[0] not in provider_resources.keys(): return [] # Completions for category if len(components) == 2: choices = ['{}.{}'.format(components[0], x) for x in ('actions', 'filters') if x.startswith(components[1])] if len(choices) == 1: choices += ['{}{}'.format(choices[0], '.')] return choices # Completions for item elif len(components) == 3: resource_mapping = schema.resource_vocabulary(cloud_provider) return ['{}.{}.{}'.format(components[0], components[1], x) for x in resource_mapping[components[0]][components[1]]] return []
def schema_cmd(options): """ Print info about the resources, actions and filters available. """ from c7n import schema if options.json: schema.json_dump(options.resource) return if options.summary: load_available() resource_mapping = schema.resource_vocabulary() schema.pprint_schema_summary(resource_mapping) return # Here are the formats for what we accept: # - No argument # - List all available RESOURCES # - PROVIDER # - List all available RESOURCES for supplied PROVIDER # - RESOURCE # - List all available actions and filters for supplied RESOURCE # - MODE # - List all available MODES # - RESOURCE.actions # - List all available actions for supplied RESOURCE # - RESOURCE.actions.ACTION # - Show class doc string and schema for supplied action # - RESOURCE.filters # - List all available filters for supplied RESOURCE # - RESOURCE.filters.FILTER # - Show class doc string and schema for supplied filter if not options.resource: load_available(resources=False) resource_list = {'resources': sorted(itertools.chain( *[clouds[p].resource_map.keys() for p in PROVIDER_NAMES]))} print(yaml_dump(resource_list)) return # Format is [PROVIDER].RESOURCE.CATEGORY.ITEM # optional provider defaults to aws for compatibility components = options.resource.lower().split('.') if len(components) == 1 and components[0] in PROVIDER_NAMES: load_providers((components[0])) resource_list = {'resources': sorted( clouds[components[0]].resource_map.keys())} print(yaml_dump(resource_list)) return if components[0] in PROVIDER_NAMES: cloud_provider = components.pop(0) components[0] = '%s.%s' % (cloud_provider, components[0]) load_resources((components[0],)) resource_mapping = schema.resource_vocabulary( cloud_provider) elif components[0] == 'mode': load_available(resources=False) resource_mapping = schema.resource_vocabulary() else: # compatibility, aws is default for provider components[0] = 'aws.%s' % components[0] load_resources((components[0],)) resource_mapping = schema.resource_vocabulary('aws') # # Handle mode # if components[0] == "mode": if len(components) == 1: output = {components[0]: list(resource_mapping[components[0]].keys())} print(yaml_dump(output)) return if len(components) == 2: if components[1] not in resource_mapping[components[0]]: log.error('{} is not a valid mode'.format(components[1])) sys.exit(1) _print_cls_schema(resource_mapping[components[0]][components[1]]) return # We received too much (e.g. mode.actions.foo) log.error("Invalid selector '{}'. Valid options are 'mode' " "or 'mode.TYPE'".format(options.resource)) sys.exit(1) # # Handle resource # resource = components[0] if resource not in resource_mapping: log.error('{} is not a valid resource'.format(resource)) sys.exit(1) if len(components) == 1: docstring = ElementSchema.doc( resource_mapping[resource]['classes']['resource']) del(resource_mapping[resource]['classes']) if docstring: print("\nHelp\n----\n") print(docstring + '\n') output = {resource: resource_mapping[resource]} print(yaml_dump(output)) return # # Handle category # category = components[1] if category not in ('actions', 'filters'): log.error("Valid choices are 'actions' and 'filters'. You supplied '{}'".format(category)) sys.exit(1) if len(components) == 2: output = "No {} available for resource {}.".format(category, resource) if category in resource_mapping[resource]: output = {resource: { category: resource_mapping[resource][category]}} print(yaml_dump(output)) return # # Handle item # item = components[2] if item not in resource_mapping[resource][category]: log.error('{} is not in the {} list for resource {}'.format(item, category, resource)) sys.exit(1) if len(components) == 3: cls = resource_mapping[resource]['classes'][category][item] _print_cls_schema(cls) return # We received too much (e.g. s3.actions.foo.bar) log.error("Invalid selector '{}'. Max of 3 components in the " "format RESOURCE.CATEGORY.ITEM".format(options.resource)) sys.exit(1)
def schema_cmd(options): """ Print info about the resources, actions and filters available. """ if options.json: schema.json_dump(options.resource) return load_resources() resource_mapping = schema.resource_vocabulary() if options.summary: schema.summary(resource_mapping) return # Here are the formats for what we accept: # - No argument # - List all available RESOURCES # - RESOURCE # - List all available actions and filters for supplied RESOURCE # - RESOURCE.actions # - List all available actions for supplied RESOURCE # - RESOURCE.actions.ACTION # - Show class doc string and schema for supplied action # - RESOURCE.filters # - List all available filters for supplied RESOURCE # - RESOURCE.filters.FILTER # - Show class doc string and schema for supplied filter if not options.resource: resource_list = {'resources': sorted(resources.keys())} print(yaml.safe_dump(resource_list, default_flow_style=False)) return # Format is RESOURCE.CATEGORY.ITEM components = options.resource.split('.') # # Handle resource # resource = components[0].lower() if resource not in resource_mapping: log.error('{} is not a valid resource'.format(resource)) sys.exit(1) if len(components) == 1: del (resource_mapping[resource]['classes']) output = {resource: resource_mapping[resource]} print(yaml.safe_dump(output)) return # # Handle category # category = components[1].lower() if category not in ('actions', 'filters'): log.error( "Valid choices are 'actions' and 'filters'. You supplied '{}'". format(category)) sys.exit(1) if len(components) == 2: output = "No {} available for resource {}.".format(category, resource) if category in resource_mapping[resource]: output = { resource: { category: resource_mapping[resource][category] } } print(yaml.safe_dump(output)) return # # Handle item # item = components[2].lower() if item not in resource_mapping[resource][category]: log.error('{} is not in the {} list for resource {}'.format( item, category, resource)) sys.exit(1) if len(components) == 3: cls = resource_mapping[resource]['classes'][category][item] # Print docstring docstring = _schema_get_docstring(cls) print("\nHelp\n----\n") if docstring: print(docstring) else: # Shouldn't ever hit this, so exclude from cover print("No help is available for this item.") # pragma: no cover # Print schema print("\nSchema\n------\n") if hasattr(cls, 'schema'): print(json.dumps(cls.schema, indent=4)) else: # Shouldn't ever hit this, so exclude from cover print("No schema is available for this item.", file=sys.sterr) # pragma: no cover print('') return # We received too much (e.g. s3.actions.foo.bar) log.error("Invalid selector '{}'. Max of 3 components in the " "format RESOURCE.CATEGORY.ITEM".format(options.resource)) sys.exit(1)
def schema_cmd(options): """ Print info about the resources, actions and filters available. """ if options.json: schema.json_dump(options.resource) return load_resources() resource_mapping = schema.resource_vocabulary() if options.summary: schema.summary(resource_mapping) return # Here are the formats for what we accept: # - No argument # - List all available RESOURCES # - PROVIDER # - List all available RESOURCES for supplied PROVIDER # - RESOURCE # - List all available actions and filters for supplied RESOURCE # - RESOURCE.actions # - List all available actions for supplied RESOURCE # - RESOURCE.actions.ACTION # - Show class doc string and schema for supplied action # - RESOURCE.filters # - List all available filters for supplied RESOURCE # - RESOURCE.filters.FILTER # - Show class doc string and schema for supplied filter if not options.resource: resource_list = {'resources': sorted(provider.resources().keys())} print(yaml.safe_dump(resource_list, default_flow_style=False)) return # Format is [PROVIDER].RESOURCE.CATEGORY.ITEM # optional provider defaults to aws for compatibility components = options.resource.lower().split('.') if len(components) == 1 and components[0] in provider.clouds.keys(): resource_list = {'resources': sorted( provider.resources(cloud_provider=components[0]).keys())} print(yaml.safe_dump(resource_list, default_flow_style=False)) return if components[0] in provider.clouds.keys(): cloud_provider = components.pop(0) resource_mapping = schema.resource_vocabulary( cloud_provider) components[0] = '%s.%s' % (cloud_provider, components[0]) else: resource_mapping = schema.resource_vocabulary('aws') components[0] = 'aws.%s' % components[0] # # Handle resource # resource = components[0] if resource not in resource_mapping: log.error('{} is not a valid resource'.format(resource)) sys.exit(1) if len(components) == 1: del(resource_mapping[resource]['classes']) output = {resource: resource_mapping[resource]} print(yaml.safe_dump(output)) return # # Handle category # category = components[1] if category not in ('actions', 'filters'): log.error("Valid choices are 'actions' and 'filters'. You supplied '{}'".format(category)) sys.exit(1) if len(components) == 2: output = "No {} available for resource {}.".format(category, resource) if category in resource_mapping[resource]: output = {resource: { category: resource_mapping[resource][category]}} print(yaml.safe_dump(output)) return # # Handle item # item = components[2] if item not in resource_mapping[resource][category]: log.error('{} is not in the {} list for resource {}'.format(item, category, resource)) sys.exit(1) if len(components) == 3: cls = resource_mapping[resource]['classes'][category][item] # Print docstring docstring = _schema_get_docstring(cls) print("\nHelp\n----\n") if docstring: print(docstring) else: # Shouldn't ever hit this, so exclude from cover print("No help is available for this item.") # pragma: no cover # Print schema print("\nSchema\n------\n") if hasattr(cls, 'schema'): print(json.dumps(cls.schema, indent=4)) else: # Shouldn't ever hit this, so exclude from cover print("No schema is available for this item.", file=sys.sterr) # pragma: no cover print('') return # We received too much (e.g. s3.actions.foo.bar) log.error("Invalid selector '{}'. Max of 3 components in the " "format RESOURCE.CATEGORY.ITEM".format(options.resource)) sys.exit(1)
def schema_cmd(options): """ Print info about the resources, actions and filters available. """ if options.json: schema.json_dump(options.resource) return load_resources() resource_mapping = schema.resource_vocabulary() if options.summary: schema.summary(resource_mapping) return # Here are the formats for what we accept: # - No argument # - List all available RESOURCES # - RESOURCE # - List all available actions and filters for supplied RESOURCE # - RESOURCE.actions # - List all available actions for supplied RESOURCE # - RESOURCE.actions.ACTION # - Show class doc string and schema for supplied action # - RESOURCE.filters # - List all available filters for supplied RESOURCE # - RESOURCE.filters.FILTER # - Show class doc string and schema for supplied filter if not options.resource: resource_list = {'resources': sorted(resources.keys())} print(yaml.safe_dump(resource_list, default_flow_style=False)) return # Format is RESOURCE.CATEGORY.ITEM components = options.resource.split('.') # # Handle resource # resource = components[0].lower() if resource not in resource_mapping: eprint('Error: {} is not a valid resource'.format(resource)) sys.exit(1) if len(components) == 1: del(resource_mapping[resource]['classes']) output = {resource: resource_mapping[resource]} print(yaml.safe_dump(output)) return # # Handle category # category = components[1].lower() if category not in ('actions', 'filters'): eprint(("Error: Valid choices are 'actions' and 'filters'." " You supplied '{}'").format(category)) sys.exit(1) if len(components) == 2: output = "No {} available for resource {}.".format(category, resource) if category in resource_mapping[resource]: output = {resource: { category: resource_mapping[resource][category]}} print(yaml.safe_dump(output)) return # # Handle item # item = components[2].lower() if item not in resource_mapping[resource][category]: eprint('Error: {} is not in the {} list for resource {}'.format( item, category, resource)) sys.exit(1) if len(components) == 3: cls = resource_mapping[resource]['classes'][category][item] # Print docstring docstring = _schema_get_docstring(cls) print("\nHelp\n----\n") if docstring: print(docstring) else: # Shouldn't ever hit this, so exclude from cover print("No help is available for this item.") # pragma: no cover # Print schema print("\nSchema\n------\n") pp = pprint.PrettyPrinter(indent=4) if hasattr(cls, 'schema'): pp.pprint(cls.schema) else: # Shouldn't ever hit this, so exclude from cover print("No schema is available for this item.", file=sys.sterr) # pragma: no cover print('') return # We received too much (e.g. s3.actions.foo.bar) eprint("Invalid selector '{}'. Max of 3 components in the " "format RESOURCE.CATEGORY.ITEM".format(options.resource)) sys.exit(1)
def schema_cmd(options): """ Print info about the resources, actions and filters available. """ from c7n import schema if options.json: schema.json_dump(options.resource) return load_resources() resource_mapping = schema.resource_vocabulary() if options.summary: schema.summary(resource_mapping) return # Here are the formats for what we accept: # - No argument # - List all available RESOURCES # - PROVIDER # - List all available RESOURCES for supplied PROVIDER # - RESOURCE # - List all available actions and filters for supplied RESOURCE # - MODE # - List all available MODES # - RESOURCE.actions # - List all available actions for supplied RESOURCE # - RESOURCE.actions.ACTION # - Show class doc string and schema for supplied action # - RESOURCE.filters # - List all available filters for supplied RESOURCE # - RESOURCE.filters.FILTER # - Show class doc string and schema for supplied filter if not options.resource: resource_list = {'resources': sorted(provider.resources().keys())} print(yaml.safe_dump(resource_list, default_flow_style=False)) return # Format is [PROVIDER].RESOURCE.CATEGORY.ITEM # optional provider defaults to aws for compatibility components = options.resource.lower().split('.') if len(components) == 1 and components[0] in provider.clouds.keys(): resource_list = {'resources': sorted( provider.resources(cloud_provider=components[0]).keys())} print(yaml.safe_dump(resource_list, default_flow_style=False)) return if components[0] in provider.clouds.keys(): cloud_provider = components.pop(0) resource_mapping = schema.resource_vocabulary( cloud_provider) components[0] = '%s.%s' % (cloud_provider, components[0]) elif components[0] in schema.resource_vocabulary().keys(): resource_mapping = schema.resource_vocabulary() else: resource_mapping = schema.resource_vocabulary('aws') components[0] = 'aws.%s' % components[0] # # Handle mode # if components[0] == "mode": if len(components) == 1: output = {components[0]: list(resource_mapping[components[0]].keys())} print(yaml.safe_dump(output, default_flow_style=False)) return if len(components) == 2: if components[1] not in resource_mapping[components[0]]: log.error('{} is not a valid mode'.format(components[1])) sys.exit(1) _print_cls_schema(resource_mapping[components[0]][components[1]]) return # We received too much (e.g. mode.actions.foo) log.error("Invalid selector '{}'. Valid options are 'mode' " "or 'mode.TYPE'".format(options.resource)) sys.exit(1) # # Handle resource # resource = components[0] if resource not in resource_mapping: log.error('{} is not a valid resource'.format(resource)) sys.exit(1) if len(components) == 1: docstring = _schema_get_docstring( resource_mapping[resource]['classes']['resource']) del(resource_mapping[resource]['classes']) if docstring: print("\nHelp\n----\n") print(docstring + '\n') output = {resource: resource_mapping[resource]} print(yaml.safe_dump(output)) return # # Handle category # category = components[1] if category not in ('actions', 'filters'): log.error("Valid choices are 'actions' and 'filters'. You supplied '{}'".format(category)) sys.exit(1) if len(components) == 2: output = "No {} available for resource {}.".format(category, resource) if category in resource_mapping[resource]: output = {resource: { category: resource_mapping[resource][category]}} print(yaml.safe_dump(output)) return # # Handle item # item = components[2] if item not in resource_mapping[resource][category]: log.error('{} is not in the {} list for resource {}'.format(item, category, resource)) sys.exit(1) if len(components) == 3: cls = resource_mapping[resource]['classes'][category][item] _print_cls_schema(cls) return # We received too much (e.g. s3.actions.foo.bar) log.error("Invalid selector '{}'. Max of 3 components in the " "format RESOURCE.CATEGORY.ITEM".format(options.resource)) sys.exit(1)