fog-aws 3.5.2 → 3.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +16 -3
  4. data/LICENSE.md +1 -1
  5. data/README.md +39 -6
  6. data/bin/console +14 -0
  7. data/bin/setup +8 -0
  8. data/fog-aws.gemspec +2 -2
  9. data/lib/fog/aws.rb +4 -0
  10. data/lib/fog/aws/elasticache.rb +4 -2
  11. data/lib/fog/aws/elb.rb +1 -1
  12. data/lib/fog/aws/elbv2.rb +72 -0
  13. data/lib/fog/aws/models/compute/flavors.rb +1544 -122
  14. data/lib/fog/aws/models/compute/snapshot.rb +7 -6
  15. data/lib/fog/aws/models/compute/vpc.rb +7 -1
  16. data/lib/fog/aws/models/storage/directory.rb +0 -1
  17. data/lib/fog/aws/models/storage/file.rb +3 -0
  18. data/lib/fog/aws/parsers/compute/create_snapshot.rb +1 -1
  19. data/lib/fog/aws/parsers/compute/create_subnet.rb +33 -6
  20. data/lib/fog/aws/parsers/compute/describe_subnets.rb +33 -6
  21. data/lib/fog/aws/parsers/dns/create_hosted_zone.rb +1 -1
  22. data/lib/fog/aws/parsers/dns/get_hosted_zone.rb +3 -3
  23. data/lib/fog/aws/parsers/dns/list_hosted_zones.rb +3 -1
  24. data/lib/fog/aws/parsers/elbv2/create_load_balancer.rb +88 -0
  25. data/lib/fog/aws/parsers/elbv2/describe_listeners.rb +110 -0
  26. data/lib/fog/aws/parsers/elbv2/describe_load_balancers.rb +88 -0
  27. data/lib/fog/aws/parsers/elbv2/describe_tags.rb +53 -0
  28. data/lib/fog/aws/parsers/elbv2/empty.rb +10 -0
  29. data/lib/fog/aws/parsers/storage/get_object_tagging.rb +33 -0
  30. data/lib/fog/aws/parsers/sts/assume_role_with_web_identity.rb +1 -1
  31. data/lib/fog/aws/requests/compute/create_vpc.rb +2 -2
  32. data/lib/fog/aws/requests/elbv2/add_tags.rb +45 -0
  33. data/lib/fog/aws/requests/elbv2/create_load_balancer.rb +160 -0
  34. data/lib/fog/aws/requests/elbv2/describe_listeners.rb +38 -0
  35. data/lib/fog/aws/requests/elbv2/describe_load_balancers.rb +100 -0
  36. data/lib/fog/aws/requests/elbv2/describe_tags.rb +50 -0
  37. data/lib/fog/aws/requests/elbv2/remove_tags.rb +45 -0
  38. data/lib/fog/aws/requests/storage/get_object_tagging.rb +41 -0
  39. data/lib/fog/aws/requests/storage/put_object_tagging.rb +42 -0
  40. data/lib/fog/aws/requests/sts/assume_role_with_web_identity.rb +7 -6
  41. data/lib/fog/aws/storage.rb +2 -0
  42. data/lib/fog/aws/version.rb +1 -1
  43. data/tests/parsers/elbv2/create_load_balancer_tests.rb +48 -0
  44. data/tests/parsers/elbv2/describe_listeners_tests.rb +76 -0
  45. data/tests/parsers/elbv2/describe_load_balancers_tests.rb +54 -0
  46. data/tests/parsers/elbv2/describe_tags_tests.rb +35 -0
  47. data/tests/requests/compute/vpc_tests.rb +6 -0
  48. data/tests/requests/elbv2/helper.rb +66 -0
  49. data/tests/requests/elbv2/load_balancer_tests.rb +50 -0
  50. metadata +35 -10
@@ -0,0 +1,50 @@
1
+ module Fog
2
+ module AWS
3
+ class ELBV2
4
+ class Real
5
+ require 'fog/aws/parsers/elbv2/describe_tags'
6
+
7
+ # returns a Hash of tags for a load balancer
8
+ # http://docs.aws.amazon.com/ElasticLoadBalancing/latest/APIReference/API_DescribeTags.html
9
+ # ==== Parameters
10
+ # * resource_arns <~Array> - ARN(s) of the ELB instance whose tags are to be retrieved
11
+ # ==== Returns
12
+ # * response<~Excon::Response>:
13
+ # * body<~Hash>:
14
+ def describe_tags(resource_arns)
15
+ request({
16
+ 'Action' => 'DescribeTags',
17
+ :parser => Fog::Parsers::AWS::ELBV2::DescribeTags.new
18
+ }.merge!(Fog::AWS.indexed_param('ResourceArns.member.%d', [*resource_arns]))
19
+ )
20
+ end
21
+ end
22
+
23
+ class Mock
24
+ def describe_tags(resource_arns)
25
+ response = Excon::Response.new
26
+ resource_arns = [*resource_arns]
27
+
28
+ tag_describtions = resource_arns.map do |resource_arn|
29
+ if self.data[:load_balancers_v2][resource_arn]
30
+ {
31
+ "Tags"=>self.data[:tags][resource_arn],
32
+ "ResourceArn"=>resource_arn
33
+ }
34
+ else
35
+ raise Fog::AWS::ELBV2::NotFound.new("Elastic load balancer #{resource_arns} not found")
36
+ end
37
+ end
38
+
39
+ response.status = 200
40
+ response.body = {
41
+ "ResponseMetadata"=>{"RequestId"=> Fog::AWS::Mock.request_id },
42
+ "DescribeTagsResult"=>{"TagDescriptions"=> tag_describtions}
43
+ }
44
+
45
+ response
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,45 @@
1
+ module Fog
2
+ module AWS
3
+ class ELBV2
4
+ class Real
5
+ require 'fog/aws/parsers/elbv2/empty'
6
+
7
+ # removes tags from an elastic load balancer instance
8
+ # http://docs.aws.amazon.com/ElasticLoadBalancing/latest/APIReference/API_RemoveTags.html
9
+ # ==== Parameters
10
+ # * resource_arn <~String> - ARN of the ELB instance whose tags are to be retrieved
11
+ # * keys <~Array> A list of String keys for the tags to remove
12
+ # ==== Returns
13
+ # * response<~Excon::Response>:
14
+ # * body<~Hash>:
15
+ def remove_tags(resource_arn, keys)
16
+ request(
17
+ { 'Action' => 'RemoveTags',
18
+ 'ResourceArns.member.1' => resource_arn,
19
+ :parser => Fog::Parsers::AWS::ELBV2::Empty.new,
20
+ }.merge(Fog::AWS.indexed_param('TagKeys.member.%d', keys))
21
+ )
22
+ end
23
+
24
+ end
25
+
26
+ class Mock
27
+
28
+ def remove_tags(resource_arn, keys)
29
+ response = Excon::Response.new
30
+ if self.data[:load_balancers_v2][resource_arn]
31
+ keys.each {|key| self.data[:tags][resource_arn].delete key}
32
+ response.status = 200
33
+ response.body = {
34
+ "ResponseMetadata"=>{ "RequestId"=> Fog::AWS::Mock.request_id }
35
+ }
36
+ response
37
+ else
38
+ raise Fog::AWS::ELBV2::NotFound.new("Elastic load balancer #{resource_arn} not found")
39
+ end
40
+ end
41
+
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,41 @@
1
+ module Fog
2
+ module AWS
3
+ class Storage
4
+ class Real
5
+ require 'fog/aws/parsers/storage/get_object_tagging'
6
+
7
+ # Get tags for an S3 object
8
+ #
9
+ # @param bucket_name [String] Name of bucket to read from
10
+ # @param object_name [String] Name of object to get tags for
11
+ #
12
+ # @return [Excon::Response] response:
13
+ # * body [Hash]:
14
+ # * ObjectTagging [Hash]:
15
+ # * Key [String] - tag key
16
+ # * Value [String] - tag value
17
+ # @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html
18
+
19
+ def get_object_tagging(bucket_name, object_name)
20
+ unless bucket_name
21
+ raise ArgumentError.new('bucket_name is required')
22
+ end
23
+ unless object_name
24
+ raise ArgumentError.new('object_name is required')
25
+ end
26
+
27
+ request({
28
+ :expects => 200,
29
+ :headers => {},
30
+ :bucket_name => bucket_name,
31
+ :object_name => object_name,
32
+ :idempotent => true,
33
+ :method => 'GET',
34
+ :parser => Fog::Parsers::AWS::Storage::GetObjectTagging.new,
35
+ :query => {'tagging' => nil}
36
+ })
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,42 @@
1
+ module Fog
2
+ module AWS
3
+ class Storage
4
+ class Real
5
+ # Change tag set for an S3 object
6
+ #
7
+ # @param bucket_name [String] Name of bucket to modify object in
8
+ # @param object_name [String] Name of object to modify
9
+ #
10
+ # @param tags [Hash]:
11
+ # * Key [String]: tag key
12
+ # * Value [String]: tag value
13
+ #
14
+ # @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectTagging.html
15
+
16
+ def put_object_tagging(bucket_name, object_name, tags)
17
+ tagging = tags.map do |k,v|
18
+ "<Tag><Key>#{k}</Key><Value>#{v}</Value></Tag>"
19
+ end.join("\n")
20
+ data =
21
+ <<-DATA
22
+ <Tagging xmlns="http://doc.s3.amazonaws.com/2006-03-01" >
23
+ <TagSet>
24
+ #{tagging}
25
+ </TagSet>
26
+ </Tagging>
27
+ DATA
28
+
29
+ request({
30
+ :body => data,
31
+ :expects => 200,
32
+ :headers => {'Content-MD5' => Base64.encode64(OpenSSL::Digest::MD5.digest(data)).chomp!, 'Content-Type' => 'application/xml'},
33
+ :bucket_name => bucket_name,
34
+ :object_name => object_name,
35
+ :method => 'PUT',
36
+ :query => {'tagging' => nil}
37
+ })
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -6,12 +6,13 @@ module Fog
6
6
 
7
7
  def assume_role_with_web_identity(role_arn, web_identity_token, role_session_name, options={})
8
8
  request_unsigned(
9
- 'Action' => 'AssumeRoleWithWebIdentity',
10
- 'RoleArn' => role_arn,
11
- 'RoleSessionName' => role_session_name,
12
- 'DurationSeconds' => options[:duration] || 3600,
13
- :idempotent => true,
14
- :parser => Fog::Parsers::AWS::STS::AssumeRoleWithWebIdentity.new
9
+ 'Action' => 'AssumeRoleWithWebIdentity',
10
+ 'RoleArn' => role_arn,
11
+ 'RoleSessionName' => role_session_name,
12
+ 'WebIdentityToken' => web_identity_token,
13
+ 'DurationSeconds' => options[:duration] || 3600,
14
+ :idempotent => true,
15
+ :parser => Fog::Parsers::AWS::STS::AssumeRoleWithWebIdentity.new
15
16
  )
16
17
  end
17
18
  end
@@ -84,6 +84,7 @@ module Fog
84
84
  request :get_object_http_url
85
85
  request :get_object_https_url
86
86
  request :get_object_url
87
+ request :get_object_tagging
87
88
  request :get_request_payment
88
89
  request :get_service
89
90
  request :head_bucket
@@ -107,6 +108,7 @@ module Fog
107
108
  request :put_object
108
109
  request :put_object_acl
109
110
  request :put_object_url
111
+ request :put_object_tagging
110
112
  request :put_request_payment
111
113
  request :sync_clock
112
114
  request :upload_part
@@ -1,5 +1,5 @@
1
1
  module Fog
2
2
  module AWS
3
- VERSION = "3.5.2"
3
+ VERSION = "3.6.2"
4
4
  end
5
5
  end
@@ -0,0 +1,48 @@
1
+ require 'fog/xml'
2
+ require 'fog/aws/parsers/elbv2/create_load_balancer'
3
+
4
+ CREATE_LOAD_BALANCER_RESULT = <<-EOF
5
+ <CreateLoadBalancerResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2015-12-01/">
6
+ <CreateLoadBalancerResult>
7
+ <LoadBalancers>
8
+ <member>
9
+ <LoadBalancerArn>arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-internal-load-balancer/50dc6c495c0c9188</LoadBalancerArn>
10
+ <Scheme>internet-facing</Scheme>
11
+ <LoadBalancerName>my-load-balancer</LoadBalancerName>
12
+ <VpcId>vpc-3ac0fb5f</VpcId>
13
+ <CanonicalHostedZoneId>Z2P70J7EXAMPLE</CanonicalHostedZoneId>
14
+ <CreatedTime>2016-03-25T21:29:48.850Z</CreatedTime>
15
+ <AvailabilityZones>
16
+ <member>
17
+ <SubnetId>subnet-8360a9e7</SubnetId>
18
+ <ZoneName>us-west-2a</ZoneName>
19
+ </member>
20
+ <member>
21
+ <SubnetId>subnet-b7d581c0</SubnetId>
22
+ <ZoneName>us-west-2b</ZoneName>
23
+ </member>
24
+ </AvailabilityZones>
25
+ <SecurityGroups>
26
+ <member>sg-5943793c</member>
27
+ </SecurityGroups>
28
+ <DNSName>my-load-balancer-424835706.us-west-2.elb.amazonaws.com</DNSName>
29
+ <State>
30
+ <Code>provisioning</Code>
31
+ </State>
32
+ <Type>application</Type>
33
+ </member>
34
+ </LoadBalancers>
35
+ </CreateLoadBalancerResult>
36
+ <ResponseMetadata>
37
+ <RequestId>32d531b2-f2d0-11e5-9192-3fff33344cfa</RequestId>
38
+ </ResponseMetadata>
39
+ </CreateLoadBalancerResponse>
40
+ EOF
41
+
42
+ Shindo.tests('AWS::ELBV2 | parsers | create_load_balancer', %w[aws elb parser]) do
43
+ tests('parses the xml').formats(AWS::ELBV2::Formats::CREATE_LOAD_BALANCER) do
44
+ parser = Nokogiri::XML::SAX::Parser.new(Fog::Parsers::AWS::ELBV2::CreateLoadBalancer.new)
45
+ parser.parse(CREATE_LOAD_BALANCER_RESULT)
46
+ parser.document.response
47
+ end
48
+ end
@@ -0,0 +1,76 @@
1
+ require 'fog/xml'
2
+ require 'fog/aws/parsers/elbv2/describe_listeners'
3
+
4
+ DESCRIBE_LISTENERS_RESULT = <<-EOF
5
+ <DescribeListenersResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2015-12-01/">
6
+ <DescribeListenersResult>
7
+ <Listeners>
8
+ <member>
9
+ <LoadBalancerArn>arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188</LoadBalancerArn>
10
+ <Protocol>HTTPS</Protocol>
11
+ <Port>80</Port>
12
+ <ListenerArn>arn:aws:elasticloadbalancing:us-west-2:123456789012:listener/app/my-load-balancer/50dc6c495c0c9188/f2f7dc8efc522ab2</ListenerArn>
13
+ <SslPolicy>polucy</SslPolicy>
14
+ <DefaultActions>
15
+ <member>
16
+ <Type>forward</Type>
17
+ <Order>1</Order>
18
+ <TargetGroupArn>arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067</TargetGroupArn>
19
+ <RedirectConfig>
20
+ <Protocol>HTTPS</Protocol>
21
+ <Port>443</Port>
22
+ <Path>\#{path}</Path>
23
+ <Query>\#{query}</Query>
24
+ <Host>\#{host}</Host>
25
+ <StatusCode>HTTP_301</StatusCode>
26
+ <Type>redirect</Type>
27
+ </RedirectConfig>
28
+ </member>
29
+ </DefaultActions>
30
+ <Certificates>
31
+ <member>
32
+ <CertificateArn>arn:aws:elasticloadbalancing:us-west-2:123456789012:certificate/56d36256-1245-40d6-916e-6f5a95e2b4c6</CertificateArn>
33
+ </member>
34
+ </Certificates>
35
+ </member>
36
+ <member>
37
+ <LoadBalancerArn>arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188</LoadBalancerArn>
38
+ <Protocol>HTTPS</Protocol>
39
+ <Port>80</Port>
40
+ <ListenerArn>arn:aws:elasticloadbalancing:us-west-2:123456789012:listener/app/my-load-balancer/50dc6c495c0c9188/f2f7dc8efc522ab2</ListenerArn>
41
+ <SslPolicy>polucy</SslPolicy>
42
+ <DefaultActions>
43
+ <member>
44
+ <Type>forward</Type>
45
+ <Order>2</Order>
46
+ <TargetGroupArn>arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067</TargetGroupArn>
47
+ <ForwardConfig>
48
+ <TargetGroupStickinessConfig><Enable>true</Enable></TargetGroupStickinessConfig>
49
+ <TargetGroups>
50
+ <Weight>1</Weight>
51
+ <TargetGroupArn>arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067</TargetGroupArn>
52
+ </TargetGroups>
53
+ </ForwardConfig>
54
+ </member>
55
+ </DefaultActions>
56
+ <Certificates>
57
+ <member>
58
+ <CertificateArn>arn:aws:elasticloadbalancing:us-west-2:123456789012:certificate/56d36256-1245-40d6-916e-6f5a95e2b4c6</CertificateArn>
59
+ </member>
60
+ </Certificates>
61
+ </member>
62
+ </Listeners>
63
+ </DescribeListenersResult>
64
+ <ResponseMetadata>
65
+ <RequestId>18e470d3-f39c-11e5-a53c-67205c0d10fd</RequestId>
66
+ </ResponseMetadata>
67
+ </DescribeListenersResponse>
68
+ EOF
69
+
70
+ Shindo.tests('AWS::ELBV2 | parsers | describe_listeners', %w[aws elb parser]) do
71
+ tests('parses the xml').formats(AWS::ELBV2::Formats::DESCRIBE_LISTENERS) do
72
+ parser = Nokogiri::XML::SAX::Parser.new(Fog::Parsers::AWS::ELBV2::DescribeListeners.new)
73
+ parser.parse(DESCRIBE_LISTENERS_RESULT)
74
+ parser.document.response
75
+ end
76
+ end
@@ -0,0 +1,54 @@
1
+ require 'fog/xml'
2
+ require 'fog/aws/parsers/elbv2/describe_load_balancers'
3
+
4
+ DESCRIBE_LOAD_BALANCERS_RESULT = <<-EOF
5
+ <DescribeLoadBalancersResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2015-12-01/">
6
+ <DescribeLoadBalancersResult>
7
+ <LoadBalancers>
8
+ <member>
9
+ <LoadBalancerArn>arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188</LoadBalancerArn>
10
+ <Scheme>internet-facing</Scheme>
11
+ <LoadBalancerName>my-load-balancer</LoadBalancerName>
12
+ <VpcId>vpc-3ac0fb5f</VpcId>
13
+ <CanonicalHostedZoneId>Z2P70J7EXAMPLE</CanonicalHostedZoneId>
14
+ <CreatedTime>2016-03-25T21:26:12.920Z</CreatedTime>
15
+ <AvailabilityZones>
16
+ <member>
17
+ <SubnetId>subnet-8360a9e7</SubnetId>
18
+ <ZoneName>us-west-2a</ZoneName>
19
+ </member>
20
+ <member>
21
+ <SubnetId>subnet-b7d581c0</SubnetId>
22
+ <ZoneName>us-west-2b</ZoneName>
23
+ <LoadBalancerAddresses>
24
+ <member>
25
+ <IpAddress>127.0.0.1</IpAddress>
26
+ <AllocationId>eipalloc-1c2ab192c131q2377</AllocationId>
27
+ </member>
28
+ </LoadBalancerAddresses>
29
+ </member>
30
+ </AvailabilityZones>
31
+ <SecurityGroups>
32
+ <member>sg-5943793c</member>
33
+ </SecurityGroups>
34
+ <DNSName>my-load-balancer-424835706.us-west-2.elb.amazonaws.com</DNSName>
35
+ <State>
36
+ <Code>active</Code>
37
+ </State>
38
+ <Type>application</Type>
39
+ </member>
40
+ </LoadBalancers>
41
+ </DescribeLoadBalancersResult>
42
+ <ResponseMetadata>
43
+ <RequestId>6581c0ac-f39f-11e5-bb98-57195a6eb84a</RequestId>
44
+ </ResponseMetadata>
45
+ </DescribeLoadBalancersResponse>
46
+ EOF
47
+
48
+ Shindo.tests('AWS::ELBV2 | parsers | describe_load_balancers', %w[aws elb parser]) do
49
+ tests('parses the xml').formats(AWS::ELBV2::Formats::DESCRIBE_LOAD_BALANCERS) do
50
+ parser = Nokogiri::XML::SAX::Parser.new(Fog::Parsers::AWS::ELBV2::DescribeLoadBalancers.new)
51
+ parser.parse(DESCRIBE_LOAD_BALANCERS_RESULT)
52
+ parser.document.response
53
+ end
54
+ end
@@ -0,0 +1,35 @@
1
+ require 'fog/xml'
2
+ require 'fog/aws/parsers/elbv2/describe_tags'
3
+
4
+ DESCRIBE_TAGS_RESULT = <<-EOF
5
+ <DescribeTagsResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2015-12-01/">
6
+ <DescribeTagsResult>
7
+ <TagDescriptions>
8
+ <member>
9
+ <ResourceArn>arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188</ResourceArn>
10
+ <Tags>
11
+ <member>
12
+ <Value>lima</Value>
13
+ <Key>project</Key>
14
+ </member>
15
+ <member>
16
+ <Value>digital-media</Value>
17
+ <Key>department</Key>
18
+ </member>
19
+ </Tags>
20
+ </member>
21
+ </TagDescriptions>
22
+ </DescribeTagsResult>
23
+ <ResponseMetadata>
24
+ <RequestId>34f144db-f2d9-11e5-a53c-67205c0d10fd</RequestId>
25
+ </ResponseMetadata>
26
+ </DescribeTagsResponse>
27
+ EOF
28
+
29
+ Shindo.tests('AWS::ELBV2 | parsers | describe_tags', %w[aws elb parser]) do
30
+ tests('parses the xml').formats(AWS::ELBV2::Formats::DESCRIBE_TAGS) do
31
+ parser = Nokogiri::XML::SAX::Parser.new(Fog::Parsers::AWS::ELBV2::DescribeTags.new)
32
+ parser.parse(DESCRIBE_TAGS_RESULT)
33
+ parser.document.response
34
+ end
35
+ end
@@ -68,6 +68,12 @@ Shindo.tests('Fog::Compute[:aws] | vpc requests', ['aws']) do
68
68
  data
69
69
  end
70
70
 
71
+ tests("#create_vpc('10.255.254.0/28', {'InstanceTenancy' => 'dedicated'})").returns('dedicated') do
72
+ data = Fog::Compute[:aws].create_vpc('10.255.254.0/28',
73
+ {'InstanceTenancy' => 'dedicated'}).body
74
+ data['vpcSet'].first['instanceTenancy']
75
+ end
76
+
71
77
  tests('#describe_vpcs').formats(@describe_vpcs_format) do
72
78
  Fog::Compute[:aws].describe_vpcs.body
73
79
  end