Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aws
GitHub Repository: aws/aws-cli
Path: blob/develop/awscli/customizations/dlm/createdefaultrole.py
1567 views
1
# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
#
3
# Licensed under the Apache License, Version 2.0 (the "License"). You
4
# may not use this file except in compliance with the License. A copy of
5
# the License is located at
6
#
7
# http://aws.amazon.com/apache2.0/
8
#
9
# or in the "license" file accompanying this file. This file is
10
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11
# ANY KIND, either express or implied. See the License for the specific
12
# language governing permissions and limitations under the License.
13
14
# Class to create default roles for lifecycle
15
import logging
16
from awscli.clidriver import CLIOperationCaller
17
from awscli.customizations.utils import get_policy_arn_suffix
18
from awscli.customizations.commands import BasicCommand
19
from awscli.customizations.dlm.iam import IAM
20
from awscli.customizations.dlm.constants \
21
import RESOURCES, \
22
LIFECYCLE_DEFAULT_ROLE_ASSUME_POLICY, \
23
POLICY_ARN_PATTERN, \
24
RESOURCE_TYPE_SNAPSHOT, \
25
RESOURCE_TYPE_IMAGE
26
from awscli.utils import create_nested_client
27
28
LOG = logging.getLogger(__name__)
29
30
31
def _construct_result(create_role_response, get_policy_response):
32
get_policy_response.pop('ResponseMetadata', None)
33
create_role_response.pop('ResponseMetadata', None)
34
result = {'RolePolicy': get_policy_response}
35
result.update(create_role_response)
36
return result
37
38
39
# Display the result as formatted json
40
def display_response(session, operation_name, result, parsed_globals):
41
if result is not None:
42
cli_operation_caller = CLIOperationCaller(session)
43
# Calling a private method. Should be changed after the functionality
44
# is moved outside CliOperationCaller.
45
cli_operation_caller._display_response(
46
operation_name, result, parsed_globals)
47
48
49
# Get policy arn from region and policy name
50
def get_policy_arn(region, policy_name):
51
region_suffix = get_policy_arn_suffix(region)
52
role_arn = POLICY_ARN_PATTERN.format(region_suffix, policy_name)
53
return role_arn
54
55
56
# Method to parse the arguments to get the region value
57
def get_region(session, parsed_globals):
58
region = parsed_globals.region
59
if region is None:
60
region = session.get_config_variable('region')
61
return region
62
63
64
class CreateDefaultRole(BasicCommand):
65
NAME = "create-default-role"
66
DESCRIPTION = ('Creates the default IAM role '
67
' which will be used by Lifecycle service.\n'
68
'If the role does not exist, create-default-role '
69
'will automatically create it and set its policy.'
70
' If the role has been already '
71
'created, create-default-role'
72
' will not update its policy.'
73
'\n')
74
ARG_TABLE = [
75
{'name': 'iam-endpoint',
76
'no_paramfile': True,
77
'help_text': '<p>The IAM endpoint to call for creating the roles.'
78
' This is optional and should only be specified when a'
79
' custom endpoint should be called for IAM operations'
80
'.</p>'},
81
{'name': 'resource-type',
82
'default': RESOURCE_TYPE_SNAPSHOT,
83
'choices': [RESOURCE_TYPE_SNAPSHOT, RESOURCE_TYPE_IMAGE],
84
'help_text': (
85
"<p>The resource type for which the role needs to be created."
86
" The available options are '%s' and '%s'."
87
" This parameter defaults to '%s'.</p>"
88
% (RESOURCE_TYPE_SNAPSHOT, RESOURCE_TYPE_IMAGE,
89
RESOURCE_TYPE_SNAPSHOT))}
90
91
]
92
93
def __init__(self, session):
94
super(CreateDefaultRole, self).__init__(session)
95
96
def _run_main(self, parsed_args, parsed_globals):
97
"""Call to run the commands"""
98
99
self._region = get_region(self._session, parsed_globals)
100
self._endpoint_url = parsed_args.iam_endpoint
101
self._resource_type = parsed_args.resource_type
102
from awscli.utils import create_nested_client
103
self._iam_client = IAM(create_nested_client(
104
self._session, 'iam',
105
region_name=self._region,
106
endpoint_url=self._endpoint_url,
107
verify=parsed_globals.verify_ssl
108
))
109
110
result = self._create_default_role_if_not_exists(parsed_globals)
111
112
display_response(
113
self._session,
114
'create_role',
115
result,
116
parsed_globals
117
)
118
119
return 0
120
121
def _create_default_role_if_not_exists(self, parsed_globals):
122
"""Method to create default lifecycle role
123
if it doesn't exist already
124
"""
125
126
role_name = RESOURCES[self._resource_type]['default_role_name']
127
assume_role_policy = LIFECYCLE_DEFAULT_ROLE_ASSUME_POLICY
128
129
if self._iam_client.check_if_role_exists(role_name):
130
LOG.debug('Role %s exists', role_name)
131
return None
132
133
LOG.debug('Role %s does not exist. '
134
'Creating default role for Lifecycle', role_name)
135
136
# Get Region
137
region = get_region(self._session, parsed_globals)
138
139
if region is None:
140
raise ValueError('You must specify a region. '
141
'You can also configure your region '
142
'by running "aws configure".')
143
144
managed_policy_arn = get_policy_arn(
145
region,
146
RESOURCES[self._resource_type]['default_policy_name']
147
)
148
149
# Don't proceed if managed policy does not exist
150
if not self._iam_client.check_if_policy_exists(managed_policy_arn):
151
LOG.debug('Managed Policy %s does not exist.', managed_policy_arn)
152
return None
153
154
LOG.debug('Managed Policy %s exists.', managed_policy_arn)
155
# Create default role
156
create_role_response = \
157
self._iam_client.create_role_with_trust_policy(
158
role_name,
159
assume_role_policy
160
)
161
# Attach policy to role
162
self._iam_client.attach_policy_to_role(
163
managed_policy_arn,
164
role_name
165
)
166
167
# Construct result
168
get_policy_response = self._iam_client.get_policy(managed_policy_arn)
169
return _construct_result(create_role_response, get_policy_response)
170
171