user6136315 user6136315 - 7 months ago 31
Python Question

pattern match with in if statement

I would like to list all active stacks in AWS cloud formation that match a regular expression. Stacks name like this 'FeatureEnv-commit123asdfqw212da-3241'. What is the best way to achieve this? whenever I run the script it's throwing an error. Complete script http://www.technobabelfish.com/2013/08/boto-and-cloudformation.html. I've updated that script to work for my requirement.

#!/usr/bin/env python

import sys
import boto
import boto.cloudformation
import argparse
import re

class MyBaseException(Exception):
msg ="MyBaseException"
def __init__(self, value):
self.value = value
def __str__(self):
return "%s: %s" % (self.msg, self.value)

class MissingParamException(MyBaseException):
msg ="Missing param"

class InvalidCommandException(MyBaseException):
msg ="Invalid command"

class InvalidStackException(MyBaseException):
msg ="Invalid stack"


def _create_cf_connection(args):
# Connect to a cloudformation
# Returns a cloudformation connection.
# Throws exception if connect fails
if not args.access_key:
raise MissingParamException("access_key")

if not args.secret_key:
raise MissingParamException("secret_key")

if not args.region:
raise MissingParamException("region")

conn = boto.cloudformation.connect_to_region(args.region,
aws_access_key_id = args.access_key,
aws_secret_access_key = args.secret_key)

return conn

def get_stacks(args):
conn = _create_cf_connection(args)
return conn.list_stacks()

def get_stack(args, stack):
conn = _create_cf_connection(args)

stacks = conn.describe_stacks(stack)
if not stacks:
raise InvalidStackException(stack)

return stacks[0]

def print_stack(stack):
print "---"
print "Name: %s" % stack.stack_name
print"ID: %s"% stack.stack_id
print "Status: %s" % stack.stack_status
print "Creation Time: %s" % stack.creation_time
print"Outputs: %s"% stack.outputs
print "Parameters: %s" % stack.parameters
print"Tags: %s"% stack.tags
print "Capabilities: %s" % stack.capabilities


def list_stacks(args):
stacks = get_stacks(args)
for stackSumm in stacks:
pattern = re.compile("^FeatureEnv-commit([a-z][0-9]+)*-([0-9]*)")
match = pattern.match(stackSumm.stack_name)
print match.string
if stackSumm.stack_status in "CREATE_COMPLETE" and match and stackSumm.stack_name in match.string:
print_stack(get_stack(args, stackSumm.stack_id))


def list_regions(args):
regions = boto.cloudformation.regions()

for r in regions:
print r.name


command_list = { 'list-regions' : list_regions,
'list-stacks' : list_stacks,
}


def parseArgs():
parser = argparse.ArgumentParser()
parser.add_argument("--region" )
parser.add_argument("--command" )
parser.add_argument("--access-key" )
parser.add_argument("--secret-key" )
args = parser.parse_args()

if not args.command:
raise MissingParamException("command")

if args.command not in command_list:
raise InvalidCommandException(args.command)

command_list[args.command](args)
if __name__=='__main__':
try:
parseArgs()
except Exception, e:
print e


Error:

'NoneType' object has no attribute 'string'

Answer

The error is in this statement stackSumm.stack_name in pattern. pattern in this case is a _sre.SRE_Pattern object, not a string. The string that contains the result of the match is:

match = pattern.match(stackSumm.stack_name)
print match.string

And string is iterable. So you can safely check if a stack name is contained in the match of your re expression:

if stackSumm.stack_status in "CREATE_COMPLETE" and match and stackSumm.stack_name in match.string:
    print_stack(get_stack(args, stackSumm.stack_id))
Comments