From 0cc42793330102698d14c35d998f87ffa3a8fd53 Mon Sep 17 00:00:00 2001 From: Josh Lane Date: Thu, 28 May 2015 13:20:48 -0700 Subject: [PATCH] model managed policies * list attached group/user policies * fix policy paging * default managed policy listing --- Gemfile | 5 +- lib/fog/aws/iam.rb | 51 +- lib/fog/aws/iam/default_policies.rb | 1600 +++++++++++++++++ lib/fog/aws/iam/paged_collection.rb | 54 + lib/fog/aws/models/iam/group.rb | 35 +- lib/fog/aws/models/iam/groups.rb | 24 +- lib/fog/aws/models/iam/managed_policies.rb | 63 + lib/fog/aws/models/iam/managed_policy.rb | 31 + lib/fog/aws/models/iam/policies.rb | 34 +- lib/fog/aws/models/iam/user.rb | 36 +- .../aws/parsers/iam/list_managed_policies.rb | 13 + lib/fog/aws/region_methods.rb | 2 +- .../aws/requests/iam/attach_group_policy.rb | 26 + .../aws/requests/iam/attach_user_policy.rb | 34 +- .../aws/requests/iam/detach_group_policy.rb | 26 + .../aws/requests/iam/detach_user_policy.rb | 26 + lib/fog/aws/requests/iam/get_policy.rb | 57 + .../iam/list_attached_group_policies.rb | 89 + .../iam/list_attached_user_policies.rb | 89 + lib/fog/aws/requests/iam/list_policies.rb | 49 +- tests/models/iam/managed_policies_tests.rb | 54 + 21 files changed, 2332 insertions(+), 66 deletions(-) create mode 100644 lib/fog/aws/iam/default_policies.rb create mode 100644 lib/fog/aws/iam/paged_collection.rb create mode 100644 lib/fog/aws/models/iam/managed_policies.rb create mode 100644 lib/fog/aws/models/iam/managed_policy.rb create mode 100644 lib/fog/aws/requests/iam/get_policy.rb create mode 100644 lib/fog/aws/requests/iam/list_attached_group_policies.rb create mode 100644 lib/fog/aws/requests/iam/list_attached_user_policies.rb create mode 100644 tests/models/iam/managed_policies_tests.rb diff --git a/Gemfile b/Gemfile index 2fa492106..98deaec60 100644 --- a/Gemfile +++ b/Gemfile @@ -2,5 +2,8 @@ source 'https://rubygems.org' # Specify your gem's dependencies in fog-aws.gemspec gemspec -gem 'pry-nav', group: :test + +group :test, :default do + gem 'pry-nav' +end gem "codeclimate-test-reporter", group: :test, require: nil diff --git a/lib/fog/aws/iam.rb b/lib/fog/aws/iam.rb index af5e22166..a1bb43181 100644 --- a/lib/fog/aws/iam.rb +++ b/lib/fog/aws/iam.rb @@ -43,19 +43,22 @@ module Fog request :detach_group_policy request :detach_role_policy request :detach_user_policy - request :get_account_summary request :get_account_password_policy + request :get_account_summary request :get_group request :get_group_policy request :get_instance_profile - request :get_role_policy request :get_login_profile - request :get_server_certificate + request :get_policy request :get_role + request :get_role_policy + request :get_server_certificate request :get_user request :get_user_policy request :list_access_keys request :list_account_aliases + request :list_attached_group_policies + request :list_attached_user_policies request :list_group_policies request :list_groups request :list_groups_for_user @@ -63,8 +66,8 @@ module Fog request :list_instance_profiles_for_role request :list_mfa_devices request :list_policies - request :list_roles request :list_role_policies + request :list_roles request :list_server_certificates request :list_signing_certificates request :list_user_policies @@ -89,6 +92,8 @@ module Fog collection :access_keys model :group collection :groups + model :managed_policy + collection :managed_policies model :policy collection :policies model :role @@ -96,11 +101,15 @@ module Fog model :user collection :users + require 'fog/aws/iam/default_policies' + class Mock def self.data @data ||= Hash.new do |hash, key| + owner_id = Fog::AWS::Mock.owner_id + hash[key] = { - :owner_id => Fog::AWS::Mock.owner_id, + :owner_id => owner_id, :server_certificates => {}, :access_keys => [{ "Status" => "Active", @@ -111,29 +120,33 @@ module Fog :serial_number => 'R1234', :user_name => 'Bob' }], + :markers => Hash.new { |mhash, mkey| mhash[mkey] = [] }, + :managed_policies => Fog::AWS::IAM::Mock.default_policies.inject({}) { |r,p| r.merge(p['Arn'] => p) }, :users => Hash.new do |uhash, ukey| uhash[ukey] = { - :user_id => Fog::AWS::Mock.key_id, - :path => '/', - :arn => "arn:aws:iam::#{Fog::AWS::Mock.owner_id}:user/#{ukey}", - :access_keys => [], - :created_at => Time.now, - :policies => {} + :access_keys => [], + :arn => "arn:aws:iam::#{owner_id}:user/#{ukey}", + :attached_policies => [], + :created_at => Time.now, + :path => '/', + :policies => {}, + :user_id => Fog::AWS::Mock.key_id } end, :groups => Hash.new do |ghash, gkey| ghash[gkey] = { - :group_id => Fog::AWS::Mock.key_id, - :arn => "arn:aws:iam::#{Fog::AWS::Mock.owner_id}:group/#{gkey}", - :members => [], - :created_at => Time.now, - :policies => {} + :arn => "arn:aws:iam::#{owner_id}:group/#{gkey}", + :attached_policies => [], + :created_at => Time.now, + :group_id => Fog::AWS::Mock.key_id, + :members => [], + :policies => {} } end, :roles => Hash.new do |rhash, rkey| rhash[rkey] = { :role_id => Fog::AWS::Mock.key_id, - :arn => "arn:aws:iam:#{Fog::AWS::Mock.owner_id}:role/#{rkey}", + :arn => "arn:aws:iam:#{owner_id}:role/#{rkey}", :create_date => Time.now, :assume_role_policy_document => { "Version" => "2012-10-17", @@ -174,6 +187,10 @@ module Fog self.class.data[@aws_access_key_id] end + def account_id + self.data[:owner_id] + end + def reset_data self.class.data.delete(@aws_access_key_id) current_user diff --git a/lib/fog/aws/iam/default_policies.rb b/lib/fog/aws/iam/default_policies.rb new file mode 100644 index 000000000..cf93b1e3a --- /dev/null +++ b/lib/fog/aws/iam/default_policies.rb @@ -0,0 +1,1600 @@ +module Fog + module AWS + class IAM + class Mock + def self.default_policies + [ + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:08 UTC", + "PolicyId"=>"ANPAI23HZ27SI6FQMGNQ2", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSDirectConnectReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AWSDirectConnectReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:40:08 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:27 UTC", + "PolicyId"=>"ANPAI2D5NJKMU274MET4E", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonGlacierReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonGlacierReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:40:27 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-11 17:21:45 UTC", + "PolicyId"=>"ANPAI2DV5ULJSO2FYVPYG", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSMarketplaceFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AWSMarketplaceFullAccess", + "CreateDate"=>"2015-02-11 17:21:45 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:52 UTC", + "PolicyId"=>"ANPAI3R4QMOG6Q5A4VWVG", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonRDSFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonRDSFullAccess", + "CreateDate"=>"2015-02-06 18:40:52 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:15 UTC", + "PolicyId"=>"ANPAI3VAJF5ZCRZ7MCQE6", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonEC2FullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonEC2FullAccess", + "CreateDate"=>"2015-02-06 18:40:15 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:19 UTC", + "PolicyId"=>"ANPAI47KNGXDAXFD4SDHG", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSElasticBeanstalkReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AWSElasticBeanstalkReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:40:19 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:41:07 UTC", + "PolicyId"=>"ANPAI65L554VRJ33ECQS6", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonSQSFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonSQSFullAccess", + "CreateDate"=>"2015-02-06 18:41:07 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-04-09 15:53:53 UTC", + "PolicyId"=>"ANPAI6E2CYYMI4XI7AA5K", + "DefaultVersionId"=>"v2", + "IsAttachable"=>true, + "PolicyName"=>"AWSLambdaFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AWSLambdaFullAccess", + "CreateDate"=>"2015-02-06 18:40:45 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/service-role/", + "UpdateDate"=>"2015-02-06 18:41:23 UTC", + "PolicyId"=>"ANPAI7QIUU4GC66SF26WE", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSCloudHSMRole", + "Arn"=>"arn:aws:iam::aws:policy/service-role/AWSCloudHSMRole", + "CreateDate"=>"2015-02-06 18:41:23 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:38 UTC", + "PolicyId"=>"ANPAI7XKCFMBPM3QQRRVQ", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"IAMFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/IAMFullAccess", + "CreateDate"=>"2015-02-06 18:40:38 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:20 UTC", + "PolicyId"=>"ANPAIA2V44CPHAUAAECKG", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonElastiCacheFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonElastiCacheFullAccess", + "CreateDate"=>"2015-02-06 18:40:20 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/service-role/", + "UpdateDate"=>"2015-05-19 18:10:14 UTC", + "PolicyId"=>"ANPAIAZKXZ27TAJ4PVWGK", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonEC2RoleforAWSCodeDeploy", + "Arn"=> + "arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforAWSCodeDeploy", + "CreateDate"=>"2015-05-19 18:10:14 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:48 UTC", + "PolicyId"=>"ANPAICN26VXMXASXKOQCG", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSOpsWorksFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AWSOpsWorksFullAccess", + "CreateDate"=>"2015-02-06 18:40:48 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/service-role/", + "UpdateDate"=>"2015-05-13 21:21:30 UTC", + "PolicyId"=>"ANPAIDI2BQT2LKXZG36TW", + "DefaultVersionId"=>"v2", + "IsAttachable"=>true, + "PolicyName"=>"AmazonElasticMapReduceRole", + "Arn"=>"arn:aws:iam::aws:policy/service-role/AmazonElasticMapReduceRole", + "CreateDate"=>"2015-02-06 18:41:20 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:57 UTC", + "PolicyId"=>"ANPAIDRINP6PPTRXYVQCI", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonRoute53DomainsReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonRoute53DomainsReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:40:57 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/service-role/", + "UpdateDate"=>"2015-02-06 18:41:27 UTC", + "PolicyId"=>"ANPAIDUTMOKHJFAPJV45W", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSOpsWorksRole", + "Arn"=>"arn:aws:iam::aws:policy/service-role/AWSOpsWorksRole", + "CreateDate"=>"2015-02-06 18:41:27 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:41:04 UTC", + "PolicyId"=>"ANPAIFE3AV6VE7EANYBVM", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"SimpleWorkflowFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/SimpleWorkflowFullAccess", + "CreateDate"=>"2015-02-06 18:41:04 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:58 UTC", + "PolicyId"=>"ANPAIFIR6V6BVTRAHWINE", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonS3FullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonS3FullAccess", + "CreateDate"=>"2015-02-06 18:40:58 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:41:10 UTC", + "PolicyId"=>"ANPAIFKCTUVOPD5NICXJK", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSStorageGatewayReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AWSStorageGatewayReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:41:10 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/service-role/", + "UpdateDate"=>"2015-05-13 21:27:21 UTC", + "PolicyId"=>"ANPAIGALS5RCDLZLB3PGS", + "DefaultVersionId"=>"v2", + "IsAttachable"=>true, + "PolicyName"=>"AmazonElasticMapReduceforEC2Role", + "Arn"=> + "arn:aws:iam::aws:policy/service-role/AmazonElasticMapReduceforEC2Role", + "CreateDate"=>"2015-02-06 18:41:21 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:51 UTC", + "PolicyId"=>"ANPAIGD46KSON64QBSEZM", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonRedshiftReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonRedshiftReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:40:51 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:17 UTC", + "PolicyId"=>"ANPAIGDT4SV4GSETWTBZK", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonEC2ReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:40:17 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:23 UTC", + "PolicyId"=>"ANPAIHP6NH2S6GYFCOINC", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonElasticMapReduceReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonElasticMapReduceReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:40:23 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:41:12 UTC", + "PolicyId"=>"ANPAIHWYO6WSDNCG64M2W", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSDirectoryServiceReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AWSDirectoryServiceReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:41:12 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-05-07 18:01:28 UTC", + "PolicyId"=>"ANPAIICZJNOJN36GTG6CM", + "DefaultVersionId"=>"v2", + "IsAttachable"=>true, + "PolicyName"=>"AmazonVPCReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonVPCReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:41:17 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:34 UTC", + "PolicyId"=>"ANPAIJIKLU2IJ7WJ6DZFG", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonMobileAnalyticsFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonMobileAnalyticsFullAccess", + "CreateDate"=>"2015-02-06 18:40:34 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/service-role/", + "UpdateDate"=>"2015-03-19 19:11:56 UTC", + "PolicyId"=>"ANPAIKCP6XS3ESGF4GLO2", + "DefaultVersionId"=>"v2", + "IsAttachable"=>true, + "PolicyName"=>"AWSDataPipelineRole", + "Arn"=>"arn:aws:iam::aws:policy/service-role/AWSDataPipelineRole", + "CreateDate"=>"2015-02-06 18:41:24 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:00 UTC", + "PolicyId"=>"ANPAIKEABORKUXN6DEAZU", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"CloudWatchFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/CloudWatchFullAccess", + "CreateDate"=>"2015-02-06 18:40:00 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-04-21 16:40:17 UTC", + "PolicyId"=>"ANPAILL3HVNFSB6DCOWYQ", + "DefaultVersionId"=>"v2", + "IsAttachable"=>true, + "PolicyName"=>"ReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/ReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:39:48 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-04-09 17:12:19 UTC", + "PolicyId"=>"ANPAILOI4HTQSFTF3GQSC", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonMachineLearningBatchPredictionsAccess", + "Arn"=> + "arn:aws:iam::aws:policy/AmazonMachineLearningBatchPredictionsAccess", + "CreateDate"=>"2015-04-09 17:12:19 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-05-19 18:21:32 UTC", + "PolicyId"=>"ANPAILZHHKCKB4NE7XOIQ", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSCodeDeployReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AWSCodeDeployReadOnlyAccess", + "CreateDate"=>"2015-05-19 18:21:32 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:39:56 UTC", + "PolicyId"=>"ANPAIM6OOWKQ7L7VBOZOC", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"CloudSearchFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/CloudSearchFullAccess", + "CreateDate"=>"2015-02-06 18:39:56 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:39:51 UTC", + "PolicyId"=>"ANPAIMBQYQZM7F63DA2UU", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSCloudHSMFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AWSCloudHSMFullAccess", + "CreateDate"=>"2015-02-06 18:39:51 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/service-role/", + "UpdateDate"=>"2015-05-18 23:28:05 UTC", + "PolicyId"=>"ANPAIMRTKHWK7ESSNETSW", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonEC2SpotFleetRole", + "Arn"=>"arn:aws:iam::aws:policy/service-role/AmazonEC2SpotFleetRole", + "CreateDate"=>"2015-05-18 23:28:05 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:25 UTC", + "PolicyId"=>"ANPAIN5WGARIKZ3E2UQOU", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonElasticTranscoderJobsSubmitter", + "Arn"=>"arn:aws:iam::aws:policy/AmazonElasticTranscoderJobsSubmitter", + "CreateDate"=>"2015-02-06 18:40:25 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:41:11 UTC", + "PolicyId"=>"ANPAINAW5ANUWTH3R4ANI", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSDirectoryServiceFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AWSDirectoryServiceFullAccess", + "CreateDate"=>"2015-02-06 18:41:11 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:11 UTC", + "PolicyId"=>"ANPAINUGF2JSOSUY76KYA", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonDynamoDBFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess", + "CreateDate"=>"2015-02-06 18:40:11 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:41:03 UTC", + "PolicyId"=>"ANPAINV2XPFRMWJJNSCGI", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonSESReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonSESReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:41:03 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/service-role/", + "UpdateDate"=>"2015-02-06 18:41:22 UTC", + "PolicyId"=>"ANPAIO2VMUPGDC5PZVXVA", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AutoScalingNotificationAccessRole", + "Arn"=> + "arn:aws:iam::aws:policy/service-role/AutoScalingNotificationAccessRole", + "CreateDate"=>"2015-02-06 18:41:22 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:30 UTC", + "PolicyId"=>"ANPAIOCMTDT5RLKZ2CAJO", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonKinesisReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonKinesisReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:40:30 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-05-19 18:13:23 UTC", + "PolicyId"=>"ANPAIONKN3TJZUKXCHXWC", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSCodeDeployFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AWSCodeDeployFullAccess", + "CreateDate"=>"2015-05-19 18:13:23 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/service-role/", + "UpdateDate"=>"2015-04-09 15:09:29 UTC", + "PolicyId"=>"ANPAIP7WNAGMIPYNW4WQG", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSLambdaDynamoDBExecutionRole", + "Arn"=> + "arn:aws:iam::aws:policy/service-role/AWSLambdaDynamoDBExecutionRole", + "CreateDate"=>"2015-04-09 15:09:29 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:56 UTC", + "PolicyId"=>"ANPAIPAFBMIYUILMOKL6G", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonRoute53DomainsFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonRoute53DomainsFullAccess", + "CreateDate"=>"2015-02-06 18:40:56 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:21 UTC", + "PolicyId"=>"ANPAIPDACSNQHSENWAKM2", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonElastiCacheReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonElastiCacheReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:40:21 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-05-27 16:25:25 UTC", + "PolicyId"=>"ANPAIPN5S4NE5JJOKVC4Y", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonElasticFileSystemReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonElasticFileSystemReadOnlyAccess", + "CreateDate"=>"2015-05-27 16:25:25 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-05-04 17:54:14 UTC", + "PolicyId"=>"ANPAIPRV52SH6HDCCFY6U", + "DefaultVersionId"=>"v2", + "IsAttachable"=>true, + "PolicyName"=>"CloudFrontFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/CloudFrontFullAccess", + "CreateDate"=>"2015-02-06 18:39:50 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/service-role/", + "UpdateDate"=>"2015-04-09 17:05:26 UTC", + "PolicyId"=>"ANPAIQ5UDYYMNN42BM4AK", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonMachineLearningRoleforRedshiftDataSource", + "Arn"=> + "arn:aws:iam::aws:policy/service-role/AmazonMachineLearningRoleforRedshiftDataSource", + "CreateDate"=>"2015-04-09 17:05:26 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:36 UTC", + "PolicyId"=>"ANPAIQLKQ4RXPUBBVVRDE", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonMobileAnalyticsNon-financialReportAccess", + "Arn"=> + "arn:aws:iam::aws:policy/AmazonMobileAnalyticsNon-financialReportAccess", + "CreateDate"=>"2015-02-06 18:40:36 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:39:58 UTC", + "PolicyId"=>"ANPAIQNUJTQYDRJPC3BNK", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSCloudTrailFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AWSCloudTrailFullAccess", + "CreateDate"=>"2015-02-06 18:39:58 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-03-24 17:22:23 UTC", + "PolicyId"=>"ANPAIQOKZ5BGKLCMTXH4W", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonCognitoDeveloperAuthenticatedIdentities", + "Arn"=> + "arn:aws:iam::aws:policy/AmazonCognitoDeveloperAuthenticatedIdentities", + "CreateDate"=>"2015-03-24 17:22:23 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/service-role/", + "UpdateDate"=>"2015-04-02 17:36:23 UTC", + "PolicyId"=>"ANPAIQRXRDRGJUA33ELIO", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSConfigRole", + "Arn"=>"arn:aws:iam::aws:policy/service-role/AWSConfigRole", + "CreateDate"=>"2015-04-02 17:36:23 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:50 UTC", + "PolicyId"=>"ANPAISEKCHH4YDB46B5ZO", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonRedshiftFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonRedshiftFullAccess", + "CreateDate"=>"2015-02-06 18:40:50 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:41:14 UTC", + "PolicyId"=>"ANPAISRCSSJNS3QPKZJPM", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonZocaloReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonZocaloReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:41:14 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:39:52 UTC", + "PolicyId"=>"ANPAISVCBSY7YDBOT67KE", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSCloudHSMReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AWSCloudHSMReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:39:52 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:55 UTC", + "PolicyId"=>"ANPAITOYK2ZAOQFXV2JNC", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonRoute53ReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonRoute53ReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:40:55 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:16 UTC", + "PolicyId"=>"ANPAIU6NBZVF2PCRW36ZW", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonEC2ReportsAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonEC2ReportsAccess", + "CreateDate"=>"2015-02-06 18:40:16 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:41:08 UTC", + "PolicyId"=>"ANPAIUGSSQY362XGCM6KW", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonSQSReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonSQSReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:41:08 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:29 UTC", + "PolicyId"=>"ANPAIVF32HAMOXCUYRAYE", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonKinesisFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonKinesisFullAccess", + "CreateDate"=>"2015-02-06 18:40:29 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-04-09 17:40:02 UTC", + "PolicyId"=>"ANPAIW5VYBCGEX56JCINC", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonMachineLearningReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonMachineLearningReadOnlyAccess", + "CreateDate"=>"2015-04-09 17:40:02 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/service-role/", + "UpdateDate"=>"2015-02-06 18:41:29 UTC", + "PolicyId"=>"ANPAIWKFXRLQG2ROKKXLE", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"RDSCloudHsmAuthorizationRole", + "Arn"=>"arn:aws:iam::aws:policy/service-role/RDSCloudHsmAuthorizationRole", + "CreateDate"=>"2015-02-06 18:41:29 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-04-09 17:25:41 UTC", + "PolicyId"=>"ANPAIWKW6AGSGYOQ5ERHC", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonMachineLearningFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonMachineLearningFullAccess", + "CreateDate"=>"2015-04-09 17:25:41 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:39:46 UTC", + "PolicyId"=>"ANPAIWMBCKSKIEE64ZLYK", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AdministratorAccess", + "Arn"=>"arn:aws:iam::aws:policy/AdministratorAccess", + "CreateDate"=>"2015-02-06 18:39:46 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-04-09 17:44:06 UTC", + "PolicyId"=>"ANPAIWMCNQPRWMWT36GVQ", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonMachineLearningRealTimePredictionOnlyAccess", + "Arn"=> + "arn:aws:iam::aws:policy/AmazonMachineLearningRealTimePredictionOnlyAccess", + "CreateDate"=>"2015-04-09 17:44:06 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-18 19:38:41 UTC", + "PolicyId"=>"ANPAIWTTSFJ7KKJE3MWGA", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSConfigUserAccess", + "Arn"=>"arn:aws:iam::aws:policy/AWSConfigUserAccess", + "CreateDate"=>"2015-02-18 19:38:41 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-04-21 16:47:16 UTC", + "PolicyId"=>"ANPAIX2T3QCXHR2OGGCTO", + "DefaultVersionId"=>"v2", + "IsAttachable"=>true, + "PolicyName"=>"SecurityAudit", + "Arn"=>"arn:aws:iam::aws:policy/SecurityAudit", + "CreateDate"=>"2015-02-06 18:41:01 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:12 UTC", + "PolicyId"=>"ANPAIY2XFNA232XJ6J7X2", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonDynamoDBReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonDynamoDBReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:40:12 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:41:06 UTC", + "PolicyId"=>"ANPAIZGQCQTFOFPMHSB6W", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonSNSReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonSNSReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:41:06 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-05-21 17:16:31 UTC", + "PolicyId"=>"ANPAIZP5JFP3AMSGINBB2", + "DefaultVersionId"=>"v3", + "IsAttachable"=>true, + "PolicyName"=>"AmazonElasticMapReduceFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonElasticMapReduceFullAccess", + "CreateDate"=>"2015-02-06 18:40:22 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:59 UTC", + "PolicyId"=>"ANPAIZTJ4DXE7G6AGAE6M", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonS3ReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:40:59 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:18 UTC", + "PolicyId"=>"ANPAIZYX2YLLBW2LJVUFW", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSElasticBeanstalkFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AWSElasticBeanstalkFullAccess", + "CreateDate"=>"2015-02-06 18:40:18 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/service-role/", + "UpdateDate"=>"2015-05-04 18:05:37 UTC", + "PolicyId"=>"ANPAJ2NKMKD73QS5NBFLA", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSCodeDeployRole", + "Arn"=>"arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole", + "CreateDate"=>"2015-05-04 18:05:37 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:41:02 UTC", + "PolicyId"=>"ANPAJ2P4NXCHAT7NDPNR4", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonSESFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonSESFullAccess", + "CreateDate"=>"2015-02-06 18:41:02 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:03 UTC", + "PolicyId"=>"ANPAJ2YIYDYSNNEHK3VKW", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"CloudWatchLogsReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/CloudWatchLogsReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:40:03 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:49 UTC", + "PolicyId"=>"ANPAJ3AB5ZBFPCQGTVDU4", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSOpsWorksRegisterCLI", + "Arn"=>"arn:aws:iam::aws:policy/AWSOpsWorksRegisterCLI", + "CreateDate"=>"2015-02-06 18:40:49 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:14 UTC", + "PolicyId"=>"ANPAJ3ORT7KDISSXGHJXA", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonDynamoDBFullAccesswithDataPipeline", + "Arn"=>"arn:aws:iam::aws:policy/AmazonDynamoDBFullAccesswithDataPipeline", + "CreateDate"=>"2015-02-06 18:40:14 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/service-role/", + "UpdateDate"=>"2015-03-19 19:21:14 UTC", + "PolicyId"=>"ANPAJ3Z5I2WAJE5DN2J36", + "DefaultVersionId"=>"v2", + "IsAttachable"=>true, + "PolicyName"=>"AmazonEC2RoleforDataPipelineRole", + "Arn"=> + "arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforDataPipelineRole", + "CreateDate"=>"2015-02-06 18:41:25 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:02 UTC", + "PolicyId"=>"ANPAJ3ZGNWK2R5HW5BQFO", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"CloudWatchLogsFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/CloudWatchLogsFullAccess", + "CreateDate"=>"2015-02-06 18:40:02 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:24 UTC", + "PolicyId"=>"ANPAJ4D5OJU75P5ZJZVNY", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonElasticTranscoderFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonElasticTranscoderFullAccess", + "CreateDate"=>"2015-02-06 18:40:24 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:37 UTC", + "PolicyId"=>"ANPAJ5TAWBBQC2FAL3G6G", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonMobileAnalyticsWriteOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonMobileAnalyticsWriteOnlyAccess", + "CreateDate"=>"2015-02-06 18:40:37 UTC" + }, + { + "AttachmentCount"=>1, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-19 22:40:45 UTC", + "PolicyId"=>"ANPAJ6YATONJHICG3DJ3U", + "DefaultVersionId"=>"v2", + "IsAttachable"=>true, + "PolicyName"=>"AWSConnector", + "Arn"=>"arn:aws:iam::aws:policy/AWSConnector", + "CreateDate"=>"2015-02-11 17:14:31 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-04-24 16:54:35 UTC", + "PolicyId"=>"ANPAJALOYVTPDZEMIACSM", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonEC2ContainerServiceFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonEC2ContainerServiceFullAccess", + "CreateDate"=>"2015-04-24 16:54:35 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-03-24 17:06:46 UTC", + "PolicyId"=>"ANPAJBFTRZD2GQGJHSVQK", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonCognitoReadOnly", + "Arn"=>"arn:aws:iam::aws:policy/AmazonCognitoReadOnly", + "CreateDate"=>"2015-03-24 17:06:46 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-05-07 18:07:43 UTC", + "PolicyId"=>"ANPAJBWPGNOVKZD3JI2P2", + "DefaultVersionId"=>"v3", + "IsAttachable"=>true, + "PolicyName"=>"AmazonVPCFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonVPCFullAccess", + "CreateDate"=>"2015-02-06 18:41:16 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:43 UTC", + "PolicyId"=>"ANPAJCQCT4JGTLC6722MQ", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSImportExportFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AWSImportExportFullAccess", + "CreateDate"=>"2015-02-06 18:40:43 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-04-09 17:18:09 UTC", + "PolicyId"=>"ANPAJDRUNIC2RYAMAT3CK", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonMachineLearningCreateOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonMachineLearningCreateOnlyAccess", + "CreateDate"=>"2015-04-09 17:18:09 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-03-12 20:16:47 UTC", + "PolicyId"=>"ANPAJDU7KJADWBSEQ3E7S", + "DefaultVersionId"=>"v2", + "IsAttachable"=>true, + "PolicyName"=>"AWSCloudTrailReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AWSCloudTrailReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:39:59 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:46 UTC", + "PolicyId"=>"ANPAJE5FX7FQZSU5XAKGO", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSLambdaExecute", + "Arn"=>"arn:aws:iam::aws:policy/AWSLambdaExecute", + "CreateDate"=>"2015-02-06 18:40:46 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:41:09 UTC", + "PolicyId"=>"ANPAJG5SSPAVOGK3SIDGU", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSStorageGatewayFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AWSStorageGatewayFullAccess", + "CreateDate"=>"2015-02-06 18:41:09 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:26 UTC", + "PolicyId"=>"ANPAJGPP7GPMJRRJMEP3Q", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonElasticTranscoderReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonElasticTranscoderReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:40:26 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:42 UTC", + "PolicyId"=>"ANPAJHF7J65E2QFKCWAJM", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonWorkMailReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonWorkMailReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:40:42 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/service-role/", + "UpdateDate"=>"2015-04-09 15:14:16 UTC", + "PolicyId"=>"ANPAJHOLKJPXV4GBRMJUQ", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSLambdaKinesisExecutionRole", + "Arn"=> + "arn:aws:iam::aws:policy/service-role/AWSLambdaKinesisExecutionRole", + "CreateDate"=>"2015-04-09 15:14:16 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:39:54 UTC", + "PolicyId"=>"ANPAJHXQTPI5I5JKAIU74", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"ResourceGroupsandTagEditorReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/ResourceGroupsandTagEditorReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:39:54 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-04-09 17:32:41 UTC", + "PolicyId"=>"ANPAJJL3PC3VCSVZP6OCI", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonMachineLearningManageRealTimeEndpointOnlyAccess", + "Arn"=> + "arn:aws:iam::aws:policy/AmazonMachineLearningManageRealTimeEndpointOnlyAccess", + "CreateDate"=>"2015-04-09 17:32:41 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-05-04 17:58:09 UTC", + "PolicyId"=>"ANPAJJZMNYOTZCNQP36LG", + "DefaultVersionId"=>"v2", + "IsAttachable"=>true, + "PolicyName"=>"CloudFrontReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/CloudFrontReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:39:55 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/service-role/", + "UpdateDate"=>"2015-02-06 18:41:30 UTC", + "PolicyId"=>"ANPAJK5GQB7CIK7KHY2GA", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonSNSRole", + "Arn"=>"arn:aws:iam::aws:policy/service-role/AmazonSNSRole", + "CreateDate"=>"2015-02-06 18:41:30 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:35 UTC", + "PolicyId"=>"ANPAJKJHO2R27TXKCWBU4", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonMobileAnalyticsFinancialReportAccess", + "Arn"=> + "arn:aws:iam::aws:policy/AmazonMobileAnalyticsFinancialReportAccess", + "CreateDate"=>"2015-02-06 18:40:35 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-04-21 16:03:51 UTC", + "PolicyId"=>"ANPAJKSO7NDY4T57MWDSQ", + "DefaultVersionId"=>"v2", + "IsAttachable"=>true, + "PolicyName"=>"IAMReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/IAMReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:40:39 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:53 UTC", + "PolicyId"=>"ANPAJKTTTYV2IIHKLZ346", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonRDSReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonRDSReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:40:53 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-03-24 17:14:56 UTC", + "PolicyId"=>"ANPAJKW5H2HNCPGCYGR6Y", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonCognitoPowerUser", + "Arn"=>"arn:aws:iam::aws:policy/AmazonCognitoPowerUser", + "CreateDate"=>"2015-03-24 17:14:56 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-05-27 16:22:28 UTC", + "PolicyId"=>"ANPAJKXTMNVQGIDNCKPBC", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonElasticFileSystemFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonElasticFileSystemFullAccess", + "CreateDate"=>"2015-05-27 16:22:28 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:41:13 UTC", + "PolicyId"=>"ANPAJLCDXYRINDMUXEVL6", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonZocaloFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonZocaloFullAccess", + "CreateDate"=>"2015-02-06 18:41:13 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-04-09 15:59:32 UTC", + "PolicyId"=>"ANPAJLDG7J3CGUHFN4YN6", + "DefaultVersionId"=>"v2", + "IsAttachable"=>true, + "PolicyName"=>"AWSLambdaReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AWSLambdaReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:40:44 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:41:19 UTC", + "PolicyId"=>"ANPAJLIB4VSBVO47ZSBB6", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSAccountUsageReportAccess", + "Arn"=>"arn:aws:iam::aws:policy/AWSAccountUsageReportAccess", + "CreateDate"=>"2015-02-06 18:41:19 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/service-role/", + "UpdateDate"=>"2015-03-19 18:45:18 UTC", + "PolicyId"=>"ANPAJLYJCVHC7TQHCSQDS", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonEC2ContainerServiceforEC2Role", + "Arn"=> + "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role", + "CreateDate"=>"2015-03-19 18:45:18 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:09 UTC", + "PolicyId"=>"ANPAJLZZXU2YQVGL4QDNC", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonAppStreamFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonAppStreamFullAccess", + "CreateDate"=>"2015-02-06 18:40:09 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:01 UTC", + "PolicyId"=>"ANPAJN23PDQP7SZQAE3QE", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"CloudWatchReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/CloudWatchReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:40:01 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/service-role/", + "UpdateDate"=>"2015-04-09 15:03:43 UTC", + "PolicyId"=>"ANPAJNCQGXC42545SKXIK", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSLambdaBasicExecutionRole", + "Arn"=>"arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "CreateDate"=>"2015-04-09 15:03:43 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:39:53 UTC", + "PolicyId"=>"ANPAJNOS54ZFXN4T2Y34A", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"ResourceGroupsandTagEditorFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/ResourceGroupsandTagEditorFullAccess", + "CreateDate"=>"2015-02-06 18:39:53 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:40 UTC", + "PolicyId"=>"ANPAJNPP7PPPPMJRV2SA4", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSKeyManagementServicePowerUser", + "Arn"=>"arn:aws:iam::aws:policy/AWSKeyManagementServicePowerUser", + "CreateDate"=>"2015-02-06 18:40:40 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:42 UTC", + "PolicyId"=>"ANPAJNTV4OG52ESYZHCNK", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSImportExportReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AWSImportExportReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:40:42 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/service-role/", + "UpdateDate"=>"2015-02-06 18:41:26 UTC", + "PolicyId"=>"ANPAJNW3WMKVXFJ2KPIQ2", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonElasticTranscoderRole", + "Arn"=>"arn:aws:iam::aws:policy/service-role/AmazonElasticTranscoderRole", + "CreateDate"=>"2015-02-06 18:41:26 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/service-role/", + "UpdateDate"=>"2015-04-09 16:14:19 UTC", + "PolicyId"=>"ANPAJO53W2XHNACG7V77Q", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonEC2ContainerServiceRole", + "Arn"=> + "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceRole", + "CreateDate"=>"2015-04-09 16:14:19 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:31 UTC", + "PolicyId"=>"ANPAJOOM6LETKURTJ3XZ2", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSMarketplaceRead-only", + "Arn"=>"arn:aws:iam::aws:policy/AWSMarketplaceRead-only", + "CreateDate"=>"2015-02-06 18:40:31 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-04-09 14:03:18 UTC", + "PolicyId"=>"ANPAJPRL4KYETIH7XGTSS", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonWorkSpacesApplicationManagerAdminAccess", + "Arn"=> + "arn:aws:iam::aws:policy/AmazonWorkSpacesApplicationManagerAdminAccess", + "CreateDate"=>"2015-04-09 14:03:18 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:07 UTC", + "PolicyId"=>"ANPAJQF2QKZSK74KTIHOW", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSDirectConnectFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AWSDirectConnectFullAccess", + "CreateDate"=>"2015-02-06 18:40:07 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:41:18 UTC", + "PolicyId"=>"ANPAJQRYCWMFX5J3E333K", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSAccountActivityAccess", + "Arn"=>"arn:aws:iam::aws:policy/AWSAccountActivityAccess", + "CreateDate"=>"2015-02-06 18:41:18 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:28 UTC", + "PolicyId"=>"ANPAJQSTZJWB2AXXAKHVQ", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonGlacierFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonGlacierFullAccess", + "CreateDate"=>"2015-02-06 18:40:28 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-03-24 18:16:18 UTC", + "PolicyId"=>"ANPAJQVKNMT7SVATQ4AUY", + "DefaultVersionId"=>"v2", + "IsAttachable"=>true, + "PolicyName"=>"AmazonWorkMailFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonWorkMailFullAccess", + "CreateDate"=>"2015-02-06 18:40:41 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:32 UTC", + "PolicyId"=>"ANPAJRDW2WIFN7QLUAKBQ", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSMarketplaceManageSubscriptions", + "Arn"=>"arn:aws:iam::aws:policy/AWSMarketplaceManageSubscriptions", + "CreateDate"=>"2015-02-06 18:40:32 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:41:11 UTC", + "PolicyId"=>"ANPAJSNKQX2OW67GF4S7E", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSSupportAccess", + "Arn"=>"arn:aws:iam::aws:policy/AWSSupportAccess", + "CreateDate"=>"2015-02-06 18:41:11 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:47 UTC", + "PolicyId"=>"ANPAJTHQ3EKCQALQDYG5G", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSLambdaInvocation-DynamoDB", + "Arn"=>"arn:aws:iam::aws:policy/AWSLambdaInvocation-DynamoDB", + "CreateDate"=>"2015-02-06 18:40:47 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-05-19 18:18:43 UTC", + "PolicyId"=>"ANPAJUWEPOMGLMVXJAPUI", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSCodeDeployDeployerAccess", + "Arn"=>"arn:aws:iam::aws:policy/AWSCodeDeployDeployerAccess", + "CreateDate"=>"2015-05-19 18:18:43 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:06 UTC", + "PolicyId"=>"ANPAJW53AHN6ZWYGU2GNO", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSDataPipelinePowerUser", + "Arn"=>"arn:aws:iam::aws:policy/AWSDataPipelinePowerUser", + "CreateDate"=>"2015-02-06 18:40:06 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:41:05 UTC", + "PolicyId"=>"ANPAJWEKLCXXUNT2SOLSG", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonSNSFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonSNSFullAccess", + "CreateDate"=>"2015-02-06 18:41:05 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:39:57 UTC", + "PolicyId"=>"ANPAJWPLX7N7BCC3RZLHW", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"CloudSearchReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/CloudSearchReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:39:57 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:39:49 UTC", + "PolicyId"=>"ANPAJWVBEE4I2POWLODLW", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSCloudFormationReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AWSCloudFormationReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:39:49 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:54 UTC", + "PolicyId"=>"ANPAJWVDLG5RPST6PHQ3A", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonRoute53FullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonRoute53FullAccess", + "CreateDate"=>"2015-02-06 18:40:54 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/service-role/", + "UpdateDate"=>"2015-02-06 18:41:28 UTC", + "PolicyId"=>"ANPAJX4DPCRGTC4NFDUXI", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSLambdaRole", + "Arn"=>"arn:aws:iam::aws:policy/service-role/AWSLambdaRole", + "CreateDate"=>"2015-02-06 18:41:28 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:10 UTC", + "PolicyId"=>"ANPAJXIFDGB4VBX23DX7K", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AmazonAppStreamReadOnlyAccess", + "Arn"=>"arn:aws:iam::aws:policy/AmazonAppStreamReadOnlyAccess", + "CreateDate"=>"2015-02-06 18:40:10 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:39:47 UTC", + "PolicyId"=>"ANPAJYRXTHIB4FOVS3ZXS", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"PowerUserAccess", + "Arn"=>"arn:aws:iam::aws:policy/PowerUserAccess", + "CreateDate"=>"2015-02-06 18:39:47 UTC" + }, + { + "AttachmentCount"=>0, + "Description"=>"", + "Path"=>"/", + "UpdateDate"=>"2015-02-06 18:40:05 UTC", + "PolicyId"=>"ANPAJZVYL5DGR3IHUEA2O", + "DefaultVersionId"=>"v1", + "IsAttachable"=>true, + "PolicyName"=>"AWSDataPipelineFullAccess", + "Arn"=>"arn:aws:iam::aws:policy/AWSDataPipelineFullAccess", + "CreateDate"=>"2015-02-06 18:40:05 UTC" + } + ] + end + end + end + end +end diff --git a/lib/fog/aws/iam/paged_collection.rb b/lib/fog/aws/iam/paged_collection.rb new file mode 100644 index 000000000..45aa68feb --- /dev/null +++ b/lib/fog/aws/iam/paged_collection.rb @@ -0,0 +1,54 @@ +module Fog + module AWS + class IAM + class PagedCollection < Fog::Collection + def self.inherited(klass) + klass.send(:attribute, :truncated, :aliases => 'IsTruncated', :type => :boolean) + klass.send(:attribute, :marker, :aliases => 'Marker') + + super + end + + def each_entry(*args, &block) + to_a.each(*args, &block) + end + + def each + if !block_given? + self + else + subset = dup.all + + subset.each_entry { |f| yield f } + + while subset.truncated + subset. + all(:marker => subset.marker, :limit => 1000). + each_entry { |f| yield f } + end + + self + end + end + + protected + + def page_params(options={}) + marker = options.fetch(:marker) { options.fetch('Marker') { self.marker } } + limit = options.fetch(:limit) { options['MaxItems'] } + params = {} + + if marker && !marker.empty? + params.merge!('Marker' => marker) + end + + if limit + params.merge!('MaxItems' => limit) + end + + params + end + end + end + end +end diff --git a/lib/fog/aws/models/iam/group.rb b/lib/fog/aws/models/iam/group.rb index 86eb99a66..9869f197a 100644 --- a/lib/fog/aws/models/iam/group.rb +++ b/lib/fog/aws/models/iam/group.rb @@ -23,10 +23,41 @@ module Fog merge_attributes(:users => self.users + [user]) end - def attach(policy_arn) + def attach(policy_or_arn) requires :name - service.attach_group_policy(self.name, policy_arn) + arn = if policy_or_arn.respond_to?(:arn) + policy_or_arn.arn + else + policy_or_arn + end + + service.attach_group_policy(self.name, arn) + end + + def attached_policies + requires :name + + service.managed_policies(:group_name => self.name) + end + + def destroy + requires :name + + service.delete_group(self.name) + true + end + + def detach(policy_or_arn) + requires :name + + arn = if policy_or_arn.respond_to?(:arn) + policy_or_arn.arn + else + policy_or_arn + end + + service.detach_group_policy(self.name, arn) end def save diff --git a/lib/fog/aws/models/iam/groups.rb b/lib/fog/aws/models/iam/groups.rb index 1920e0467..b442eef27 100644 --- a/lib/fog/aws/models/iam/groups.rb +++ b/lib/fog/aws/models/iam/groups.rb @@ -1,19 +1,16 @@ require 'fog/aws/models/iam/group' +require 'fog/aws/iam/paged_collection' module Fog module AWS class IAM - class Groups < Fog::Collection + class Groups < Fog::AWS::IAM::PagedCollection - attribute :truncated, :aliases => 'IsTruncated', :type => :boolean - attribute :marker, :aliases => 'Marker' attribute :username model Fog::AWS::IAM::Group def all(options = {}) - merge_attributes(options) - data, records = if self.username response = service.list_groups_for_user(self.username, options) [response.body, response.body['GroupsForUser']] @@ -36,23 +33,6 @@ module Fog rescue Fog::AWS::IAM::NotFound nil end - - def each - if !block_given? - self - else - subset = dup.all - - subset.each { |f| yield f } - - while subset.truncated - subset = subset.all('Marker' => subset.marker, 'MaxItems' => 1000) - subset.each { |f| yield f } - end - - self - end - end end end end diff --git a/lib/fog/aws/models/iam/managed_policies.rb b/lib/fog/aws/models/iam/managed_policies.rb new file mode 100644 index 000000000..9c5127dcf --- /dev/null +++ b/lib/fog/aws/models/iam/managed_policies.rb @@ -0,0 +1,63 @@ +require 'fog/aws/models/iam/managed_policy' +require 'fog/aws/iam/paged_collection' + +module Fog + module AWS + class IAM + class ManagedPolicies < Fog::AWS::IAM::PagedCollection + + attribute :username + attribute :group_name + + model Fog::AWS::IAM::ManagedPolicy + + def all(options={}) + data = if self.username + all_by_user(self.username, options) + elsif self.group_name + all_by_group(self.group_name, options) + else + all_policies(options) + end + + load(data) + end + + def get(identity) + response = service.get_policy(identity) + + new(response.body['Policy']) + rescue Fog::AWS::IAM::NotFound + nil + end + + protected + + def all_by_user(username, options={}) + body = service.list_attached_user_policies(username, page_params(options)).body + merge_attributes(body) + + body['Policies'].map do |policy| + service.get_policy(policy['PolicyArn']).body['Policy'] + end + end + + def all_by_group(group_name, options={}) + body = service.list_attached_group_policies(group_name, page_params(options)).body + merge_attributes(body) + + body['Policies'].map do |policy| + service.get_policy(policy['PolicyArn']).body['Policy'] + end + end + + def all_policies(options={}) + body = service.list_policies(page_params(options)).body + merge_attributes(body) + + body['Policies'] + end + end + end + end +end diff --git a/lib/fog/aws/models/iam/managed_policy.rb b/lib/fog/aws/models/iam/managed_policy.rb new file mode 100644 index 000000000..2381c0993 --- /dev/null +++ b/lib/fog/aws/models/iam/managed_policy.rb @@ -0,0 +1,31 @@ +module Fog + module AWS + class IAM + class ManagedPolicy < Fog::Model + identity :id, :aliases => 'PolicyId' + + attribute :arn, :aliases => 'Arn' + attribute :attachable, :aliases => 'IsAttachable', :type => :boolean + attribute :attachments, :aliases => 'AttachmentCount', :type => :integer + attribute :created_at, :aliases => 'CreateDate', :type => :time + attribute :default_version, :aliases => 'DefaultVersionId' + attribute :description, :aliases => 'Description' + attribute :name, :aliases => 'PolicyName' + attribute :path, :aliases => 'Path' + attribute :updated_at, :aliases => 'UpdateDate', :type => :time + + def attach(user_or_username) + requires :arn + + username = if user_or_username.respond_to?(:identity) + user_or_username.identity + else + user_or_username + end + + service.attach_user_policy(username, self.arn) + end + end + end + end +end diff --git a/lib/fog/aws/models/iam/policies.rb b/lib/fog/aws/models/iam/policies.rb index 03fb2d748..45031a48b 100644 --- a/lib/fog/aws/models/iam/policies.rb +++ b/lib/fog/aws/models/iam/policies.rb @@ -1,21 +1,23 @@ require 'fog/aws/models/iam/policy' +require 'fog/aws/iam/paged_collection' module Fog module AWS class IAM - class Policies < Fog::Collection + class Policies < Fog::AWS::IAM::PagedCollection + model Fog::AWS::IAM::Policy attribute :username attribute :group_name - def all + def all(options={}) requires_one :username, :group_name policies = if self.username - all_by_user(self.username) - else - all_by_group(self.group_name) + all_by_user(self.username, options) + else self.group_name + all_by_group(self.group_name, options) end load(policies) # data is an array of attribute hashes @@ -24,13 +26,13 @@ module Fog def get(identity) requires_one :username, :group_name - data = if self.username - service.get_user_policy(identity, self.username) - else - service.get_group_policy(identity, self.group_name) - end.body['Policy'] + response = if self.username + service.get_user_policy(identity, self.username) + else self.group_name + service.get_group_policy(identity, self.group_name) + end - new(data) + new(response.body['Policy']) rescue Fog::AWS::IAM::NotFound nil end @@ -44,16 +46,18 @@ module Fog # AWS method get_user_policy and list_group_policies only returns an array of policy names, this is kind of useless, # that's why it has to loop through the list to get the details of each element. I don't like it because it makes this method slow - def all_by_group(group_name) - response = service.list_group_policies(group_name) + def all_by_group(group_name, options={}) + response = service.list_group_policies(group_name, page_params(options)) + merge_attributes(response.body) response.body['PolicyNames'].map do |policy_name| service.get_group_policy(policy_name, group_name).body['Policy'] end end - def all_by_user(username) - response = service.list_user_policies(username) + def all_by_user(username, options={}) + response = service.list_user_policies(username, page_params(options)) + merge_attributes(response.body) response.body['PolicyNames'].map do |policy_name| service.get_user_policy(policy_name, username).body['Policy'] diff --git a/lib/fog/aws/models/iam/user.rb b/lib/fog/aws/models/iam/user.rb index 47ff3947e..15b5ec9fb 100644 --- a/lib/fog/aws/models/iam/user.rb +++ b/lib/fog/aws/models/iam/user.rb @@ -15,6 +15,36 @@ module Fog service.access_keys(:username => id) end + def attach(policy_or_arn) + requires :identity + + arn = if policy_or_arn.respond_to?(:arn) + policy_or_arn.arn + else + policy_or_arn + end + + service.attach_user_policy(self.identity, arn) + end + + def detach(policy_or_arn) + requires :identity + + arn = if policy_or_arn.respond_to?(:arn) + policy_or_arn.arn + else + policy_or_arn + end + + service.detach_user_policy(self.identity, arn) + end + + def attached_policies + requires :identity + + service.managed_policies(:username => self.identity) + end + def destroy requires :id @@ -23,13 +53,15 @@ module Fog end def groups + requires :identity + service.groups(:username => self.identity) end def policies - requires :id + requires :identity - service.policies(:username => id) + service.policies(:username => self.identity) end def password=(password) diff --git a/lib/fog/aws/parsers/iam/list_managed_policies.rb b/lib/fog/aws/parsers/iam/list_managed_policies.rb index a39f4b04a..81daac557 100644 --- a/lib/fog/aws/parsers/iam/list_managed_policies.rb +++ b/lib/fog/aws/parsers/iam/list_managed_policies.rb @@ -14,12 +14,25 @@ module Fog @response['Policies'] << policy end + def start_element(name, attrs = []) + case name + when 'member' + @policy = {} + end + super + end + def end_element(name) case name when 'RequestId', 'Marker' @response[name] = value + when 'PolicyArn', 'PolicyName' + @policy[name] = value when 'IsTruncated' @response[name] = (value == 'true') + when 'member' + finished_policy(@policy) + @policy = {} end super end diff --git a/lib/fog/aws/region_methods.rb b/lib/fog/aws/region_methods.rb index 0dc3810a0..bde5480ee 100644 --- a/lib/fog/aws/region_methods.rb +++ b/lib/fog/aws/region_methods.rb @@ -1,7 +1,7 @@ module Fog module AWS module RegionMethods - def validate_aws_region host, region + def validate_aws_region(host, region) if host.end_with?('.amazonaws.com') && !['ap-northeast-1', 'ap-southeast-1', 'ap-southeast-2', 'eu-west-1', 'us-east-1', 'us-west-1', 'us-west-2', 'sa-east-1', 'us-gov-west-1', 'eu-central-1'].include?(region) raise ArgumentError, "Unknown region: #{region.inspect}" end diff --git a/lib/fog/aws/requests/iam/attach_group_policy.rb b/lib/fog/aws/requests/iam/attach_group_policy.rb index 0b872d8f9..6e935bf66 100644 --- a/lib/fog/aws/requests/iam/attach_group_policy.rb +++ b/lib/fog/aws/requests/iam/attach_group_policy.rb @@ -27,6 +27,32 @@ module Fog ) end end + + class Mock + def attach_group_policy(group_name, policy_arn) + if policy_arn.nil? + raise Fog::AWS::IAM::ValidationError, "1 validation error detected: Value null at 'policyArn' failed to satisfy constraint: Member must not be null" + end + + managed_policy = self.data[:managed_policies][policy_arn] + + unless managed_policy + raise Fog::AWS::IAM::NotFound, "Policy #{policy_arn} does not exist." + end + + unless self.data[:groups].key?(group_name) + raise Fog::AWS::IAM::NotFound.new("The group with name #{group_name} cannot be found.") + end + + group = self.data[:groups][group_name] + group[:attached_policies] << policy_arn + + Excon::Response.new.tap { |response| + response.status = 200 + response.body = { "RequestId" => Fog::AWS::Mock.request_id } + } + end + end end end end diff --git a/lib/fog/aws/requests/iam/attach_user_policy.rb b/lib/fog/aws/requests/iam/attach_user_policy.rb index 8b4aaca87..cd88a5c8b 100644 --- a/lib/fog/aws/requests/iam/attach_user_policy.rb +++ b/lib/fog/aws/requests/iam/attach_user_policy.rb @@ -20,13 +20,39 @@ module Fog # def attach_user_policy(user_name, policy_arn) request( - 'Action' => 'AttachUserPolicy', - 'UserName' => user_name, - 'PolicyArn' => policy_arn, - :parser => Fog::Parsers::AWS::IAM::Basic.new + 'Action' => 'AttachUserPolicy', + 'UserName' => user_name, + 'PolicyArn' => policy_arn, + :parser => Fog::Parsers::AWS::IAM::Basic.new ) end end + + class Mock + def attach_user_policy(user_name, policy_arn) + if policy_arn.nil? + raise Fog::AWS::IAM::ValidationError, "1 validation error detected: Value null at 'policyArn' failed to satisfy constraint: Member must not be null" + end + + managed_policy = self.data[:managed_policies][policy_arn] + + unless managed_policy + raise Fog::AWS::IAM::NotFound, "Policy #{policy_arn} does not exist." + end + + unless self.data[:users].key?(user_name) + raise Fog::AWS::IAM::NotFound.new("The user with name #{user_name} cannot be found.") + end + + user = self.data[:users][user_name] + user[:attached_policies] << policy_arn + + Excon::Response.new.tap { |response| + response.status = 200 + response.body = { "RequestId" => Fog::AWS::Mock.request_id } + } + end + end end end end diff --git a/lib/fog/aws/requests/iam/detach_group_policy.rb b/lib/fog/aws/requests/iam/detach_group_policy.rb index fe8a1ab7e..33dd1f194 100644 --- a/lib/fog/aws/requests/iam/detach_group_policy.rb +++ b/lib/fog/aws/requests/iam/detach_group_policy.rb @@ -27,6 +27,32 @@ module Fog ) end end + + class Mock + def detach_group_policy(group_name, policy_arn) + if policy_arn.nil? + raise Fog::AWS::IAM::ValidationError, "1 validation error detected: Value null at 'policyArn' failed to satisfy constraint: Member must not be null" + end + + managed_policy = self.data[:managed_policies][policy_arn] + + unless managed_policy + raise Fog::AWS::IAM::NotFound, "Policy #{policy_arn} does not exist." + end + + unless self.data[:groups].key?(group_name) + raise Fog::AWS::IAM::NotFound.new("The group with name #{group_name} cannot be found.") + end + + group = self.data[:groups][group_name] + group[:attached_policies].delete(policy_arn) + + Excon::Response.new.tap { |response| + response.status = 200 + response.body = { "RequestId" => Fog::AWS::Mock.request_id } + } + end + end end end end diff --git a/lib/fog/aws/requests/iam/detach_user_policy.rb b/lib/fog/aws/requests/iam/detach_user_policy.rb index 1747c9c1e..8f46e570a 100644 --- a/lib/fog/aws/requests/iam/detach_user_policy.rb +++ b/lib/fog/aws/requests/iam/detach_user_policy.rb @@ -27,6 +27,32 @@ module Fog ) end end + + class Mock + def detach_user_policy(user_name, policy_arn) + if policy_arn.nil? + raise Fog::AWS::IAM::ValidationError, "1 validation error detected: Value null at 'policyArn' failed to satisfy constraint: Member must not be null" + end + + managed_policy = self.data[:managed_policies][policy_arn] + + unless managed_policy + raise Fog::AWS::IAM::NotFound, "Policy #{policy_arn} does not exist." + end + + unless self.data[:users].key?(user_name) + raise Fog::AWS::IAM::NotFound.new("The user with name #{user_name} cannot be found.") + end + + user = self.data[:users][user_name] + user[:attached_policies].delete(policy_arn) + + Excon::Response.new.tap { |response| + response.status = 200 + response.body = { "RequestId" => Fog::AWS::Mock.request_id } + } + end + end end end end diff --git a/lib/fog/aws/requests/iam/get_policy.rb b/lib/fog/aws/requests/iam/get_policy.rb new file mode 100644 index 000000000..fec3c9f4c --- /dev/null +++ b/lib/fog/aws/requests/iam/get_policy.rb @@ -0,0 +1,57 @@ +module Fog + module AWS + class IAM + class Real + require 'fog/aws/parsers/iam/single_policy' + + # Get Policy + # + # ==== Parameters + # * 'PolicyArn'<~String>: The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources. + # + # ==== Returns + # * response<~Excon::Response>: + # * body<~Hash>: + # * Arn<~String> The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources. + # * AttachmentCount<~Integer> The number of entities (users, groups, and roles) that the policy is attached to. + # * CreateDate<~DateTime> The date and time, in ISO 8601 date-time format, when the policy was created. + # * DefaultVersionId<~String> The identifier for the version of the policy that is set as the default version. + # * Description<~String> A friendly description of the policy. + # * IsAttachable<~Boolean> Specifies whether the policy can be attached to an IAM user, group, or role. + # * Path<~String> The path to the policy. + # * PolicyId<~String> The stable and unique string identifying the policy. + # * PolicyName<~String> The friendly name (not ARN) identifying the policy. + # * UpdateDate<~DateTime> The date and time, in ISO 8601 date-time format, when the policy was last updated. + # + # ==== See Also + # http://docs.aws.amazon.com/IAM/latest/APIReference/API_GetPolicy.html + # + def get_policy(policy_arn) + request({ + 'Action' => 'GetPolicy', + 'PolicyArn' => policy_arn, + :parser => Fog::Parsers::AWS::IAM::SinglePolicy.new + }) + end + end + + class Mock + def get_policy(policy_arn) + managed_policy = self.data[:managed_policies][policy_arn] + + unless managed_policy + raise Fog::AWS::IAM::NotFound, "Policy #{policy_arn} does not exist." + end + + Excon::Response.new.tap do |response| + response.body = { + 'Policy' => managed_policy, + 'RequestId' => Fog::AWS::Mock.request_id + } + response.status = 200 + end + end + end + end + end +end diff --git a/lib/fog/aws/requests/iam/list_attached_group_policies.rb b/lib/fog/aws/requests/iam/list_attached_group_policies.rb new file mode 100644 index 000000000..9124e38e4 --- /dev/null +++ b/lib/fog/aws/requests/iam/list_attached_group_policies.rb @@ -0,0 +1,89 @@ +module Fog + module AWS + class IAM + class Real + require 'fog/aws/parsers/iam/list_managed_policies' + + # Attaches a managed policy to a group + # + # ==== Parameters + # * group_name<~String>: name of the group + # + # ==== Returns + # * response<~Excon::Response>: + # * body<~Hash>: + # * 'RequestId'<~String> - Id of the request + # * AttachedPolicies + # * 'PolicyArn'<~String> - The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources. + # * 'PolicName'<~String> - The friendly name of the attached policy. + # + # ==== See Also + # http://docs.aws.amazon.com/IAM/latest/APIReference/API_AttachGroupPolicy.html + # + def list_attached_group_policies(group_name, options={}) + request({ + 'Action' => 'ListAttachedGroupPolicies', + 'GroupName' => group_name, + :parser => Fog::Parsers::AWS::IAM::ListManagedPolicies.new + }.merge(options)) + end + end + + class Mock + def list_attached_group_policies(group_name, options={}) + unless self.data[:groups].key?(group_name) + raise Fog::AWS::IAM::NotFound.new("The group with name #{group_name} cannot be found.") + end + + limit = options['MaxItems'] + marker = options['Marker'] + group = self.data[:groups][group_name] + + if limit + if limit > 1_000 + raise Fog::AWS::IAM::Error.new( + "ValidationError => 1 validation error detected: Value '#{limit}' at 'limit' failed to satisfy constraint: Member must have value less than or equal to 1000" + ) + elsif limit < 1 + raise Fog::AWS::IAM::Error.new( + "ValidationError => 1 validation error detected: Value '#{limit}' at 'limit' failed to satisfy constraint: Member must have value greater than or equal to 1" + ) + end + end + + data_set = if marker + self.data[:markers][marker] || [] + else + group[:attached_policies].map { |arn| + self.data[:managed_policies].fetch(arn) + }.map { |mp| + { "PolicyName" => mp.fetch("PolicyName"), "PolicyArn" => mp.fetch("Arn") } + } + end + + data = data_set.slice!(0, limit || 100) + truncated = data_set.size > 0 + marker = truncated && Base64.encode64("metadata/l/#{account_id}/#{UUID.uuid}") + + response = Excon::Response.new + + body = { + 'Policies' => data, + 'IsTruncated' => truncated, + 'RequestId' => Fog::AWS::Mock.request_id + } + + if marker + self.data[:markers][marker] = data_set + body.merge!('Marker' => marker) + end + + response.body = body + response.status = 200 + + response + end + end + end + end +end diff --git a/lib/fog/aws/requests/iam/list_attached_user_policies.rb b/lib/fog/aws/requests/iam/list_attached_user_policies.rb new file mode 100644 index 000000000..341d269ee --- /dev/null +++ b/lib/fog/aws/requests/iam/list_attached_user_policies.rb @@ -0,0 +1,89 @@ +module Fog + module AWS + class IAM + class Real + require 'fog/aws/parsers/iam/list_managed_policies' + + # Attaches a managed policy to a user + # + # ==== Parameters + # * user_name<~String>: name of the user + # + # ==== Returns + # * response<~Excon::Response>: + # * body<~Hash>: + # * 'RequestId'<~String> - Id of the request + # * AttachedPolicies + # * 'PolicyArn'<~String> - The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources. + # * 'PolicName'<~String> - The friendly name of the attached policy. + # + # ==== See Also + # http://docs.aws.amazon.com/IAM/latest/APIReference/API_AttachUserPolicy.html + # + def list_attached_user_policies(user_name, options={}) + request({ + 'Action' => 'ListAttachedUserPolicies', + 'UserName' => user_name, + :parser => Fog::Parsers::AWS::IAM::ListManagedPolicies.new + }.merge(options)) + end + end + + class Mock + def list_attached_user_policies(user_name, options={}) + unless self.data[:users].key?(user_name) + raise Fog::AWS::IAM::NotFound.new("The user with name #{user_name} cannot be found.") + end + + limit = options['MaxItems'] + marker = options['Marker'] + user = self.data[:users][user_name] + + if limit + if limit > 1_000 + raise Fog::AWS::IAM::Error.new( + "ValidationError => 1 validation error detected: Value '#{limit}' at 'limit' failed to satisfy constraint: Member must have value less than or equal to 1000" + ) + elsif limit < 1 + raise Fog::AWS::IAM::Error.new( + "ValidationError => 1 validation error detected: Value '#{limit}' at 'limit' failed to satisfy constraint: Member must have value greater than or equal to 1" + ) + end + end + + data_set = if marker + self.data[:markers][marker] || [] + else + user[:attached_policies].map { |arn| + self.data[:managed_policies].fetch(arn) + }.map { |mp| + { "PolicyName" => mp.fetch("PolicyName"), "PolicyArn" => mp.fetch("Arn") } + } + end + + data = data_set.slice!(0, limit || 100) + truncated = data_set.size > 0 + marker = truncated && Base64.encode64("metadata/l/#{account_id}/#{UUID.uuid}") + + response = Excon::Response.new + + body = { + 'Policies' => data, + 'IsTruncated' => truncated, + 'RequestId' => Fog::AWS::Mock.request_id + } + + if marker + self.data[:markers][marker] = data_set + body.merge!('Marker' => marker) + end + + response.body = body + response.status = 200 + + response + end + end + end + end +end diff --git a/lib/fog/aws/requests/iam/list_policies.rb b/lib/fog/aws/requests/iam/list_policies.rb index ece3a1785..ffea9912e 100644 --- a/lib/fog/aws/requests/iam/list_policies.rb +++ b/lib/fog/aws/requests/iam/list_policies.rb @@ -17,7 +17,7 @@ module Fog # * response<~Excon::Response>: # * body<~Hash>: # * 'RequestId'<~String> - Id of the request - # * 'IsTruncated'<~Boolean> + # * 'IsTruncated'<~Boolean> # * 'Marker'<~String> # * 'Policies'<~Array>: # * Arn @@ -41,7 +41,52 @@ module Fog end end - + class Mock + def list_policies(options={}) + limit = options['MaxItems'] + marker = options['Marker'] + + if limit + if limit > 1_000 + raise Fog::AWS::IAM::Error.new( + "ValidationError => 1 validation error detected: Value '#{limit}' at 'limit' failed to satisfy constraint: Member must have value less than or equal to 1000" + ) + elsif limit < 1 + raise Fog::AWS::IAM::Error.new( + "ValidationError => 1 validation error detected: Value '#{limit}' at 'limit' failed to satisfy constraint: Member must have value greater than or equal to 1" + ) + end + end + + data_set = if marker + self.data[:markers][marker] || [] + else + self.data[:managed_policies].values + end + + data = data_set.slice!(0, limit || 100) + truncated = data_set.size > 0 + marker = truncated && Base64.encode64("metadata/l/#{account_id}/#{UUID.uuid}") + + response = Excon::Response.new + + body = { + 'Policies' => data, + 'IsTruncated' => truncated, + 'RequestId' => Fog::AWS::Mock.request_id + } + + if marker + self.data[:markers][marker] = data_set + body.merge!('Marker' => marker) + end + + response.body = body + response.status = 200 + + response + end + end end end end diff --git a/tests/models/iam/managed_policies_tests.rb b/tests/models/iam/managed_policies_tests.rb new file mode 100644 index 000000000..2d0fdba51 --- /dev/null +++ b/tests/models/iam/managed_policies_tests.rb @@ -0,0 +1,54 @@ +Shindo.tests("Fog::Compute[:iam] | managed_policies", ['aws','iam']) do + + iam = Fog::AWS[:iam] + + tests('#all').succeeds do + iam.managed_policies.size == 100 + end + + tests('#each').succeeds do + policies = [] + + iam.managed_policies.each { |policy| policies << policy } + + policies.size > 100 + end + + policy = iam.managed_policies.get("arn:aws:iam::aws:policy/IAMReadOnlyAccess") + + tests("users") do + user = iam.users.create(:id => uniq_id("fog-test-user")) + + tests("#attach").succeeds do + user.attach(policy) + + user.attached_policies.map(&:identity) == [policy.identity] + end + + tests("#detach").succeeds do + user.detach(policy) + + user.attached_policies.map(&:identity) == [] + end + + user.destroy + end + + tests("groups") do + group = iam.groups.create(:name => uniq_id("fog-test-group")) + + tests("#attach").succeeds do + group.attach(policy) + + group.attached_policies.map(&:identity) == [policy.identity] + end + + tests("#detach").succeeds do + group.detach(policy) + + group.attached_policies.map(&:identity) == [] + end + + group.destroy + end +end