rainit2006 / Python-room

my python room
0 stars 0 forks source link

Python for AWS #13

Open rainit2006 opened 6 years ago

rainit2006 commented 6 years ago

rainit2006 commented 6 years ago

CloudFormation

利用boto库

conn = boto.cloudformation.connect_to_region("eu-west-1")

def get_stack_status(): try: stack = conn.describe_stacks(stackname)[0] return stack.stack_status //得到stack的状态 except boto.exception.BotoServerError as e: if -1 != str(e).find('does not exist'): # not here return 'NONE_COMPLETE' else: # something worse raise

def check_stack_status(status): temp = get_stack_status() print temp return -1 == temp.find(status)

def wait_for_status(success_stats, fail_stats=None, timeout=20): while True: status = get_stack_status() print status if status in success_stats: return True if fail_stats and status in fail_stats: return False if timeout == 0: return False time.sleep(60) timeout -= 1

stack = conn.describe_stacks(stackname)[0] ///Returns the description for the specified stack; if no stack name was specified, then it returns the description for all the stacks created. //http://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-stacks.html

conn.validate_template(template_body=template_body) //Validates a specified template.

elif sys.argv[1] == 'create': assert(len(sys.argv) == 3) owner_name = sys.argv[2] print 'Checking state' if (not wait_for_status(['NONE_COMPLETE', 'UPDATE_COMPLETE', 'DELETE_COMPLETE', 'CREATE_COMPLETE', 'ROLLBACK_COMPLETE'])): sys.exit(-1)

    # we have to start stack from scratch
    if (get_stack_status() in ['NONE_COMPLETE', 'DELETE_COMPLETE']):
        print 'Creating stack'
        conn.create_stack(
            stackname,
            template_body=template_body,
            parameters=get_params(),
            capabilities=['CAPABILITY_IAM'],
            timeout_in_minutes=30)
        if wait_for_status(['CREATE_COMPLETE'], ['ROLLBACK_COMPLETE', 'ROLLBACK_IN_PROGRESS'], 40):
            get_lock(owner_name)
    elif (get_stack_status() in ['CREATE_COMPLETE', 'UPDATE_COMPLETE']):
        print 'Reusing stack'
        # check if it is occupied
        get_lock(owner_name)
        # clean it up
        subprocess.call("./undeploy.sh", shell=True)
        clean_buckets()
        # update and reuse
        try:
            conn.update_stack(
                stackname,
                template_body=template_body,
                parameters=get_params(),
                capabilities=['CAPABILITY_IAM'],
                timeout_in_minutes=30)
            wait_for_status(['UPDATE_COMPLETE'], ['ROLLBACK_COMPLETE', 'ROLLBACK_IN_PROGRESS'])
        except boto.exception.BotoServerError as e:
            if -1 != str(e).find('No updates are to be performed'):
                print "Nothing to update"
            else:
                raise

    stack = get_stack()
    status = stack.stack_status
    if status in ['CREATE_COMPLETE', 'UPDATE_COMPLETE']:
        print_stack(stack)
        sys.exit(0)
    else:
        print 'stack creation failed !:', status
        sys.exit(-1)

elif sys.argv[1] == 'status': print_stack(conn.describe_stacks(stackname)[0])

elif sys.argv[1] == 'release':
    release_lock()
    sys.exit(0)

elif sys.argv[1] == 'destroy':
    subprocess.call("./undeploy.sh", shell=True)
    clean_buckets()
    conn.delete_stack(stackname)
    if (wait_for_status(['DELETE_COMPLETE', 'NONE_COMPLETE'], ['DELETE_FAILED'], timeout=40)):
        sys.exit(0)
    else:
        print 'CloudFormation stack deletion failed. Please delete manually from the AWS web console: (1) delete VPC, (2) destroy CloudFormation stack.'
        sys.exit(-1)

説明:
- describe_stacks:
The call to describe_stacks should return a list of Stack objects.

import boto.cloudformation conn = boto.cloudformation.connect_to_region('us-west-2') # or your favorite region stacks = conn.describe_stacks('MyStackID') if len(stacks) == 1: stack = stacks[0] else:

Raise an exception or something because your stack isn't there

At this point the variable stack is a Stack object. The outputs of the stack are available as the outputs attribute of stack. This attribute will contain a list of Output objects which, in turn, have a key, value, and description attribute. So, this would print all of the outputs:

for output in stack.outputs: print('%s=%s (%s)' % (output.key, output.value, output.description))

- stack.stack_status
- stack.outputs[index]. key(, vaulue, description)
- conn.create_stack
- conn.update_stack
- conn.delete_stack

- boto.connect_s3
- s3.get_bucket

def get_lock(owner_name): print lock_bucket_name s3 = boto.connect_s3() bucket = s3.get_bucket(lock_bucket_name) wait = True while wait: wait = False rs = bucket.list() for key in rs: print 'Stack is used by: %s for %d min' % (key.get_contents_as_string(), (int(time.time()) - int(key.name)) / 60) wait = True if wait: time.sleep(60) key = bucket.new_key(str(int(time.time()))) key.set_contents_from_string(owner_name)

def release_lock(): print lock_bucket_name s3 = boto.connect_s3() try: bucket = s3.get_bucket(lock_bucket_name) rs = bucket.list() for key in rs: key.delete() except boto.exception.S3ResponseError as e: if e.status != 404: raise



AWS CloudFormation は無料サービスです。ただし、スタックに追加する AWS リソースには現在の料金が課金されます。
rainit2006 commented 6 years ago

S3 操作 バケットにはKeyオブジェクトとしてファイルを保存できる。

S3.Bucket オブジェクトを通して、バケットへアクセスすることができる。

import boto3

# バケット名
AWS_S3_BUCKET_NAME = 'hogehoge'

s3 = boto3.resource('s3')
bucket = s3.Bucket(AWS_S3_BUCKET_NAME)

print(bucket.name)
# => hogehoge

属性 objects を通して、バケットに保存されているS3オブジェクトの情報にアクセスできる。 この属性は Bucket.objectsCollectionManager クラスのインスタンスで、 all(), delete(), filter(), limit(), page_size() のメソッドが利用できる。

print(bucket.objects.all())
# => s3.Bucket.objectsCollection(s3.Bucket(name='hogehoge'), s3.ObjectSummary)

print([obj_summary.key for obj_summary in bucket.objects.all()])
# => ['hayabusa.txt']

class S3.Object(bucket_name, key) http://boto3.readthedocs.io/en/latest/reference/services/s3.html#object These are the resource's available identifiers:

bucket_name
key

These are the resource's available attributes:

accept_ranges
cache_control
content_disposition
content_encoding
content_language
content_length
content_type
delete_marker
e_tag
expiration
expires
last_modified
metadata
missing_meta
parts_count
replication_status
request_charged
restore
server_side_encryption
sse_customer_algorithm
sse_customer_key_md5
ssekms_key_id
storage_class
version_id
website_redirect_location

These are the resource's available actions:

copy()
copy_from()
delete()
download_file()
download_fileobj()
get()
get_available_subresources()
initiate_multipart_upload()
load()
put()
reload()
restore_object()
upload_file()
upload_fileobj()

These are the resource's available sub-resources:

Acl()
Bucket()
MultipartUpload()
Version()

These are the resource's available waiters:

wait_until_exists()
wait_until_not_exists()

botoを使ってS3にファイルをアップロードする http://tokibito.hatenablog.com/entry/20110624/1308844554 1.S3へのバケットの用意 アップロード先のバケットを用意する。 botoのAPIで作成することもできるが、今回はAWSのコンソールから作成しておく。

  1. botoのコネクション
    from boto.s3.connection import S3Connection
    conn = S3Connection('アクセスキーの文字列', 'シークレットアクセスキーの文字列')

    このconnオブジェクトのメソッドからゴニョゴニョ開始する。 中身の通信はHTTPSでXML投げっこ。

  2. フォルダの作成
    >>> bucket = conn.get_bucket('test-boto.nullpobug.com')
    >>> bucket
    <Bucket: test-boto.nullpobug.com>

    バケットにはKeyオブジェクトとしてファイルを保存できる。 フォルダもファイル。というかフォルダという概念がないので、S3用のツール類などからフォルダとして見えるのは、keyの最後がセパレータのスラッシュ(/)になってるものだったり、拡張子が "_$folder$" となってるものみたい。 バケットの中身をとりあえず確認するには、list関数で見ればよい。

    >>> list(bucket)
    []

    フォルダを作ってみる。 コンテンツは空でよいので空文字列を指定。set_contents_from_stringを呼び出したタイミングでリクエストを投げてるみたいです。

    >>> from boto.s3.key import Key
    >>> k = Key(bucket)
    >>> k.key = 'test_folder/'
    >>> k.set_contents_from_string('')

    これでtest_folderという名前のフォルダが作られる。 Management Consoleから見るとこんな感じ。 image

ファイルをアップロードする ファイルも同様にKeyオブジェクトを作成すればアップロードできます。

>>> f = Key(bucket)
>>> f.key = 'test.txt'
>>> f.set_contents_from_filename('test.txt')