File: create_volume.rb

package info (click to toggle)
ruby-fog-aws 3.18.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 8,140 kB
  • sloc: ruby: 73,328; javascript: 14; makefile: 9; sh: 4
file content (129 lines) | stat: -rw-r--r-- 6,147 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
module Fog
  module AWS
    class Compute
      class Real
        require 'fog/aws/parsers/compute/create_volume'

        # Create an EBS volume
        #
        # ==== Parameters
        # * availability_zone<~String> - availability zone to create volume in
        # * size<~Integer> - Size in GiBs for volume.  Must be between 1 and 1024.
        # * options<~Hash>
        #   * 'SnapshotId'<~String> - Optional, snapshot to create volume from
        #   * 'VolumeType'<~String> - Optional, volume type. standard or io1, default is standard.
        #   * 'Iops'<~Integer> - Number of IOPS the volume supports. Required if VolumeType is io1, must be between 1 and 4000.
        #   * 'Encrypted'<~Boolean> - Optional, specifies whether the volume should be encrypted, default is false.
        #
        # ==== Returns
        # * response<~Excon::Response>:
        #   * body<~Hash>:
        #     * 'availabilityZone'<~String> - Availability zone for volume
        #     * 'createTime'<~Time> - Timestamp for creation
        #     * 'size'<~Integer> - Size in GiBs for volume
        #     * 'snapshotId'<~String> - Snapshot volume was created from, if any
        #     * 'status'<~String> - State of volume
        #     * 'volumeId'<~String> - Reference to volume
        #     * 'volumeType'<~String> - Type of volume
        #     * 'iops'<~Integer> - Number of IOPS the volume supports
        #     * 'encrypted'<~Boolean> - Indicates whether the volume will be encrypted
        #
        # {Amazon API Reference}[http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CreateVolume.html]
        def create_volume(availability_zone, size, options = {})
          unless options.is_a?(Hash)
            Fog::Logger.deprecation("create_volume with a bare snapshot_id is deprecated, use create_volume(availability_zone, size, 'SnapshotId' => snapshot_id) instead [light_black](#{caller.first})[/]")
            options = { 'SnapshotId' => options }
          end

          request({
            'Action'            => 'CreateVolume',
            'AvailabilityZone'  => availability_zone,
            'Size'              => size,
            :parser             => Fog::Parsers::AWS::Compute::CreateVolume.new
          }.merge(options))
        end
      end

      class Mock
        def create_volume(availability_zone, size, options = {})
          unless options.is_a?(Hash)
            Fog::Logger.deprecation("create_volume with a bare snapshot_id is deprecated, use create_volume(availability_zone, size, 'SnapshotId' => snapshot_id) instead [light_black](#{caller.first})[/]")
            options = { 'SnapshotId' => options }
          end

          response = Excon::Response.new
          if availability_zone && (size || options['SnapshotId'])
            snapshot = self.data[:snapshots][options['SnapshotId']]
            if options['SnapshotId'] && !snapshot
              raise Fog::AWS::Compute::NotFound.new("The snapshot '#{options['SnapshotId']}' does not exist.")
            end

            if snapshot && size && size < snapshot['volumeSize']
              raise Fog::AWS::Compute::NotFound.new("The snapshot '#{options['SnapshotId']}' has size #{snapshot['volumeSize']} which is greater than #{size}.")
            elsif snapshot && !size
              size = snapshot['volumeSize']
            end

            if options['VolumeType'] == 'io1'
              iops = options['Iops']
              if !iops
                raise Fog::AWS::Compute::Error.new("InvalidParameterCombination => The parameter iops must be specified for io1 volumes.")
              end

              if size < 10
                raise Fog::AWS::Compute::Error.new("InvalidParameterValue => Volume of #{size}GiB is too small; minimum is 10GiB.")
              end

              if (iops_to_size_ratio = iops.to_f / size.to_f) > 30.0
                raise Fog::AWS::Compute::Error.new("InvalidParameterValue => Iops to volume size ratio of #{"%.1f" % iops_to_size_ratio} is too high; maximum is 30.0")
              end

              if iops < 100
                raise Fog::AWS::Compute::Error.new("VolumeIOPSLimit => Volume iops of #{iops} is too low; minimum is 100.")
              end

              if iops > 4000
                raise Fog::AWS::Compute::Error.new("VolumeIOPSLimit => Volume iops of #{iops} is too high; maximum is 4000.")
              end
            end

            if options['KmsKeyId'] && !options['Encrypted']
              raise Fog::AWS::Compute::Error.new("InvalidParameterDependency => The parameter KmsKeyId requires the parameter Encrypted to be set.")
            end

            response.status = 200
            volume_id = Fog::AWS::Mock.volume_id
            data = {
              'availabilityZone' => availability_zone,
              'attachmentSet'    => [],
              'createTime'       => Time.now,
              'iops'             => options['Iops'],
              'encrypted'        => options['Encrypted'] || false,
              'size'             => size,
              'snapshotId'       => options['SnapshotId'],
              'kmsKeyId'         => options['KmsKeyId'] || nil, # @todo validate
              'status'           => 'creating',
              'volumeId'         => volume_id,
              'volumeType'       => options['VolumeType'] || 'standard'
            }
            self.data[:volumes][volume_id] = data
            response.body = {
              'requestId' => Fog::AWS::Mock.request_id
            }.merge!(data.reject {|key,value| !['availabilityZone','createTime','encrypted','size','snapshotId','status','volumeId','volumeType'].include?(key) })
          else
            response.status = 400
            response.body = {
              'Code' => 'MissingParameter'
            }
            unless availability_zone
              response.body['Message'] = 'The request must contain the parameter availability_zone'
            else
              response.body['Message'] = 'The request must contain the parameter size'
            end
          end
          response
        end
      end
    end
  end
end