Path: blob/develop/awscli/customizations/datapipeline/createdefaultroles.py
1567 views
# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.1#2# Licensed under the Apache License, Version 2.0 (the "License"). You3# may not use this file except in compliance with the License. A copy of4# the License is located at5#6# http://aws.amazon.com/apache2.0/7#8# or in the "license" file accompanying this file. This file is9# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF10# ANY KIND, either express or implied. See the License for the specific11# language governing permissions and limitations under the License.1213# Class to create default roles for datapipeline1415import logging16import warnings17from awscli.customizations.datapipeline.constants \18import DATAPIPELINE_DEFAULT_SERVICE_ROLE_NAME, \19DATAPIPELINE_DEFAULT_RESOURCE_ROLE_NAME, \20DATAPIPELINE_DEFAULT_SERVICE_ROLE_ARN, \21DATAPIPELINE_DEFAULT_RESOURCE_ROLE_ARN, \22DATAPIPELINE_DEFAULT_SERVICE_ROLE_ASSUME_POLICY, \23DATAPIPELINE_DEFAULT_RESOURCE_ROLE_ASSUME_POLICY24from awscli.customizations.commands import BasicCommand25from awscli.customizations.datapipeline.translator \26import display_response, dict_to_string, get_region27from awscli.utils import create_nested_client2829from botocore.exceptions import ClientError3031LOG = logging.getLogger(__name__)323334_DEPRECATION_NOTICE = """35Support for this command has been deprecated and may fail to create these roles36if they do not already exist. For more information on managing these policies37manually see the following documentation:3839https://docs.aws.amazon.com/datapipeline/latest/DeveloperGuide/dp-iam-roles.html40"""4142_DESCRIPTION = """43NOTE: {}4445Creates the default IAM role "{}" and "{}" which are used while creating an EMR46cluster.4748If these roles do not exist, create-default-roles will automatically create49them and set their policies.5051If these roles have already been created create-default-roles will not update52their policies.53"""545556class CreateDefaultRoles(BasicCommand):5758NAME = "create-default-roles"59_UNDOCUMENTED = True60DESCRIPTION = _DESCRIPTION.format(61_DEPRECATION_NOTICE,62DATAPIPELINE_DEFAULT_SERVICE_ROLE_NAME,63DATAPIPELINE_DEFAULT_RESOURCE_ROLE_NAME,64)6566def __init__(self, session, formatter=None):67super(CreateDefaultRoles, self).__init__(session)6869def _run_main(self, parsed_args, parsed_globals, **kwargs):70"""Call to run the commands"""71self._region = get_region(self._session, parsed_globals)72self._endpoint_url = parsed_globals.endpoint_url73self._iam_client = create_nested_client(74self._session, 'iam',75region_name=self._region,76endpoint_url=self._endpoint_url,77verify=parsed_globals.verify_ssl78)79warnings.warn(_DEPRECATION_NOTICE)80return self._create_default_roles(parsed_args, parsed_globals)8182def _create_role(self, role_name, role_arn, role_policy):83"""Method to create a role for a given role name and arn84if it does not exist85"""8687role_result = None88role_policy_result = None89# Check if the role with the name exists90if self._check_if_role_exists(role_name):91LOG.debug('Role ' + role_name + ' exists.')92else:93LOG.debug('Role ' + role_name + ' does not exist.'94' Creating default role for EC2: ' + role_name)95# Create a create using the IAM Client with a particular triplet96# (role_name, role_arn, assume_role_policy)97role_result = self._create_role_with_role_policy(role_name,98role_policy,99role_arn)100role_policy_result = self._get_role_policy(role_arn)101return role_result, role_policy_result102103def _construct_result(self, dpl_default_result,104dpl_default_policy,105dpl_default_res_result,106dpl_default_res_policy):107"""Method to create a resultant list of responses for create roles108for service and resource role109"""110111result = []112self._construct_role_and_role_policy_structure(result,113dpl_default_result,114dpl_default_policy)115self._construct_role_and_role_policy_structure(result,116dpl_default_res_result,117dpl_default_res_policy)118return result119120def _create_default_roles(self, parsed_args, parsed_globals):121122# Setting the role name and arn value123(datapipline_default_result,124datapipline_default_policy) = self._create_role(125DATAPIPELINE_DEFAULT_SERVICE_ROLE_NAME,126DATAPIPELINE_DEFAULT_SERVICE_ROLE_ARN,127DATAPIPELINE_DEFAULT_SERVICE_ROLE_ASSUME_POLICY)128129(datapipline_default_resource_result,130datapipline_default_resource_policy) = self._create_role(131DATAPIPELINE_DEFAULT_RESOURCE_ROLE_NAME,132DATAPIPELINE_DEFAULT_RESOURCE_ROLE_ARN,133DATAPIPELINE_DEFAULT_RESOURCE_ROLE_ASSUME_POLICY)134135# Check if the default EC2 Instance Profile for DataPipeline exists.136instance_profile_name = DATAPIPELINE_DEFAULT_RESOURCE_ROLE_NAME137if self._check_if_instance_profile_exists(instance_profile_name):138LOG.debug('Instance Profile ' + instance_profile_name + ' exists.')139else:140LOG.debug('Instance Profile ' + instance_profile_name +141'does not exist. Creating default Instance Profile ' +142instance_profile_name)143self._create_instance_profile_with_role(instance_profile_name,144instance_profile_name)145146result = self._construct_result(datapipline_default_result,147datapipline_default_policy,148datapipline_default_resource_result,149datapipline_default_resource_policy)150151display_response(self._session, 'create_role', result, parsed_globals)152153return 0154155def _get_role_policy(self, arn):156"""Method to get the Policy for a particular ARN157This is used to display the policy contents to the user158"""159pol_det = self._iam_client.get_policy(PolicyArn=arn)160policy_version_details = self._iam_client.get_policy_version(161PolicyArn=arn, VersionId=pol_det["Policy"]["DefaultVersionId"])162return policy_version_details["PolicyVersion"]["Document"]163164def _create_role_with_role_policy(165self, role_name, assume_role_policy, role_arn):166"""Method to create role with a given rolename, assume_role_policy167and role_arn168"""169# Create a role using IAM client CreateRole API170create_role_response = self._iam_client.create_role(171RoleName=role_name, AssumeRolePolicyDocument=dict_to_string(172assume_role_policy))173174# Create a role using IAM client AttachRolePolicy API175self._iam_client.attach_role_policy(PolicyArn=role_arn,176RoleName=role_name)177178return create_role_response179180def _construct_role_and_role_policy_structure(181self, list_val, response, policy):182"""Method to construct the message to be displayed to the user"""183# If the response is not none they we get the role name184# from the response and185# append the policy information to the response186if response is not None and response['Role'] is not None:187list_val.append({'Role': response['Role'], 'RolePolicy': policy})188return list_val189190def _check_if_instance_profile_exists(self, instance_profile_name):191"""Method to verify if a particular role exists"""192try:193# Client call to get the instance profile with that name194self._iam_client.get_instance_profile(195InstanceProfileName=instance_profile_name)196197except ClientError as e:198# If the instance profile does not exist then the error message199# would contain the required message200if e.response['Error']['Code'] == 'NoSuchEntity':201# No instance profile error.202return False203else:204# Some other error. raise.205raise e206207return True208209def _check_if_role_exists(self, role_name):210"""Method to verify if a particular role exists"""211try:212# Client call to get the role213self._iam_client.get_role(RoleName=role_name)214except ClientError as e:215# If the role does not exist then the error message216# would contain the required message.217if e.response['Error']['Code'] == 'NoSuchEntity':218# No role error.219return False220else:221# Some other error. raise.222raise e223224return True225226def _create_instance_profile_with_role(self, instance_profile_name,227role_name):228"""Method to create the instance profile with the role"""229# Setting the value for instance profile name230# Client call to create an instance profile231self._iam_client.create_instance_profile(232InstanceProfileName=instance_profile_name)233234# Adding the role to the Instance Profile235self._iam_client.add_role_to_instance_profile(236InstanceProfileName=instance_profile_name, RoleName=role_name)237238239