Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add boto3action to aws pack #37

Closed
wants to merge 11 commits into from
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,3 +288,7 @@ This trigger is emitted when a single message is received from a queue.
}
```


## Boto3Action

`aws.boto3action` added as an option to use boto3 actions dynamically. More on [boto3action](boto3action.md).
33 changes: 33 additions & 0 deletions actions/assume_role.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import json
import boto3

from st2actions.runners.pythonrunner import Action

from lib.util import json_serial


# pylint: disable=too-few-public-methods
class Boto3AssumeRoleRunner(Action):
def run(
self, role_arn, role_session_name, policy,
duration, external_id, serial_number, token_code):
client = boto3.client('sts')
kwargs = {}
kwargs['RoleArn'] = role_arn
kwargs['RoleSessionName'] = role_session_name
kwargs['DurationSeconds'] = duration
if policy is not None:
kwargs['Policy'] = policy

if external_id is not None:
kwargs['ExternalId'] = external_id

if serial_number is not None:
kwargs['SerialNumber'] = serial_number

if token_code is not None:
kwargs['TokenCode'] = token_code

response = client.assume_role(**kwargs)
response = json.loads(json.dumps(response, default=json_serial))
return (True, response)
32 changes: 32 additions & 0 deletions actions/assume_role.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
name: "assume_role"
runner_type: "python-script"
description: "Assume a role to use with boto3action"
enabled: true
entry_point: "assume_role.py"
pack: "aws"
parameters:
role_arn:
type: "string"
description: "ARN of the role"
required: true
role_session_name:
type: "string"
description: "Name for the session"
default: "DefaultAssumeSession"
policy:
type: "string"
description: "Policy document"
duration:
type: integer
description: "Duration for the session"
default: 3600
external_id:
type: "string"
description: "External Id"
serial_number:
type: "string"
description: "Serial number of the MFA"
token_code:
type: "string"
description: "Token code from the MFA"
32 changes: 32 additions & 0 deletions actions/boto3action.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import json
import boto3

from st2actions.runners.pythonrunner import Action
from lib.util import json_serial


# pylint: disable=too-few-public-methods
class Boto3ActionRunner(Action):
def run(self, service, region, action_name, credentials, params):
client = None
response = None

if credentials is not None:
session = boto3.Session(
aws_access_key_id=credentials['Credentials']['AccessKeyId'],
aws_secret_access_key=credentials['Credentials']['SecretAccessKey'],
aws_session_token=credentials['Credentials']['SessionToken'])
client = session.client(service, region_name=region)
else:
client = boto3.client(service, region_name=region)

if client is None:
return (False, 'boto3 client creation failed')

if params is not None:
response = getattr(client, action_name)(**params)
else:
response = getattr(client, action_name)()

response = json.loads(json.dumps(response, default=json_serial))
return (True, response)
27 changes: 27 additions & 0 deletions actions/boto3action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
name: "boto3action"
runner_type: "python-script"
description: "Run any boto3 action"
enabled: true
entry_point: "boto3action.py"
pack: "aws"
parameters:
service:
type: "string"
description: "Name of the service to create client"
required: true
region:
type: "string"
description: "Region where action is performed"
required: true
action_name:
type: "string"
description: "Name of the action to run"
required: true
credentials:
type: "object"
description: "Response from assume role"
params:
type: object
description: "Parameters for the action"

9 changes: 9 additions & 0 deletions actions/lib/util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from datetime import date, datetime


# pylint: disable=too-few-public-methods
def json_serial(obj):
if isinstance(obj, (datetime, date)):
serial = obj.isoformat()
return serial
raise TypeError("Type %s not serializable" % type(obj))
Loading