fog-brightbox 1.5.0 → 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +37 -0
  3. data/lib/fog/brightbox/compute/shared.rb +26 -10
  4. data/lib/fog/brightbox/compute.rb +11 -0
  5. data/lib/fog/brightbox/config.rb +12 -0
  6. data/lib/fog/brightbox/models/compute/account.rb +30 -18
  7. data/lib/fog/brightbox/models/compute/api_client.rb +10 -2
  8. data/lib/fog/brightbox/models/compute/application.rb +8 -0
  9. data/lib/fog/brightbox/models/compute/cloud_ip.rb +11 -11
  10. data/lib/fog/brightbox/models/compute/collaboration.rb +11 -0
  11. data/lib/fog/brightbox/models/compute/config_map.rb +14 -0
  12. data/lib/fog/brightbox/models/compute/config_maps.rb +22 -0
  13. data/lib/fog/brightbox/models/compute/database_server.rb +19 -15
  14. data/lib/fog/brightbox/models/compute/database_snapshot.rb +13 -6
  15. data/lib/fog/brightbox/models/compute/database_type.rb +6 -3
  16. data/lib/fog/brightbox/models/compute/event.rb +5 -4
  17. data/lib/fog/brightbox/models/compute/firewall_policy.rb +10 -4
  18. data/lib/fog/brightbox/models/compute/firewall_rule.rb +9 -6
  19. data/lib/fog/brightbox/models/compute/flavor.rb +3 -3
  20. data/lib/fog/brightbox/models/compute/image.rb +16 -14
  21. data/lib/fog/brightbox/models/compute/load_balancer.rb +12 -8
  22. data/lib/fog/brightbox/models/compute/server.rb +19 -17
  23. data/lib/fog/brightbox/models/compute/server_group.rb +13 -5
  24. data/lib/fog/brightbox/models/compute/user.rb +9 -4
  25. data/lib/fog/brightbox/models/compute/user_collaboration.rb +11 -0
  26. data/lib/fog/brightbox/models/compute/volume.rb +15 -14
  27. data/lib/fog/brightbox/models/compute/zone.rb +3 -4
  28. data/lib/fog/brightbox/models/storage/directory.rb +2 -2
  29. data/lib/fog/brightbox/oauth2.rb +47 -7
  30. data/lib/fog/brightbox/requests/compute/create_config_map.rb +22 -0
  31. data/lib/fog/brightbox/requests/compute/delete_config_map.rb +20 -0
  32. data/lib/fog/brightbox/requests/compute/get_config_map.rb +18 -0
  33. data/lib/fog/brightbox/requests/compute/list_config_maps.rb +18 -0
  34. data/lib/fog/brightbox/requests/compute/update_config_map.rb +22 -0
  35. data/lib/fog/brightbox/version.rb +1 -1
  36. data/spec/fog/brightbox/compute/credentials_spec.rb +41 -0
  37. data/spec/fog/brightbox/compute/get_access_token_spec.rb +305 -0
  38. data/spec/fog/brightbox/compute/two_factor_spec.rb +53 -0
  39. data/spec/fog/brightbox/oauth2/user_credentials_strategy_spec.rb +20 -0
  40. metadata +14 -1
@@ -5,32 +5,34 @@ module Fog
5
5
  include Fog::Brightbox::Compute::ResourceLocking
6
6
 
7
7
  identity :id
8
- attribute :url
9
8
  attribute :resource_type
9
+ attribute :url
10
10
 
11
11
  attribute :name
12
- attribute :username
13
12
  attribute :status
14
13
  attribute :description
15
14
 
16
- attribute :source
17
- attribute :source_type
18
15
  attribute :arch
19
- attribute :virtual_size
20
- attribute :disk_size
16
+ attribute :disk_size, type: :integer
21
17
  attribute :licence_name
18
+ attribute :min_ram, type: :integer
19
+ attribute :source
20
+ attribute :source_trigger
21
+ attribute :source_type
22
+ attribute :username
23
+ attribute :virtual_size, type: :integer
22
24
 
23
25
  # Boolean flags
24
- attribute :public
25
- attribute :official
26
- attribute :compatibility_mode
26
+ attribute :compatibility_mode, type: :boolean
27
+ attribute :official, type: :boolean
28
+ attribute :public, type: :boolean
27
29
 
28
- # Times
29
- attribute :created_at, :type => :time
30
+ # Timestamps
31
+ attribute :created_at, type: :time
30
32
 
31
- # Links - to be replaced
32
- attribute :ancestor_id, :aliases => "ancestor", :squash => "id"
33
- attribute :owner_id, :aliases => "owner", :squash => "id"
33
+ # Links
34
+ attribute :ancestor_id, aliases: "ancestor", squash: "id"
35
+ attribute :owner_id, aliases: "owner", squash: "id"
34
36
 
35
37
  def ready?
36
38
  status == "available"
@@ -5,13 +5,13 @@ module Fog
5
5
  include Fog::Brightbox::Compute::ResourceLocking
6
6
 
7
7
  identity :id
8
- attribute :url
9
8
  attribute :resource_type
9
+ attribute :url
10
10
 
11
11
  attribute :name
12
12
  attribute :status
13
13
 
14
- attribute :buffer_size
14
+ attribute :buffer_size, type: :integer
15
15
 
16
16
  attribute :policy
17
17
  attribute :nodes
@@ -34,14 +34,18 @@ module Fog
34
34
  # List of domains for ACME
35
35
  attribute :domains
36
36
 
37
- # Times
38
- attribute :created_at, :type => :time
39
- attribute :deleted_at, :type => :time
37
+ # Booleans
38
+ attribute :https_redirect, type: :boolean
39
+
40
+ # Timestamps
41
+ attribute :created_at, type: :time
42
+ attribute :deleted_at, type: :time
40
43
 
41
- # Links - to be replaced
44
+ # Links
42
45
  attribute :account
43
- attribute :server
44
- attribute :cloud_ip
46
+
47
+ attribute :nodes
48
+ attribute :cloud_ips
45
49
 
46
50
  def ready?
47
51
  status == "active"
@@ -14,35 +14,37 @@ module Fog
14
14
  attribute :url
15
15
 
16
16
  attribute :name
17
- attribute :state, :aliases => "status"
17
+ attribute :state, aliases: "status"
18
18
 
19
- attribute :hostname
20
- attribute :fqdn
21
- attribute :user_data
19
+ attribute :console_token
22
20
  attribute :console_url
23
21
  attribute :fqdn
24
- attribute :console_token
22
+ attribute :hostname
23
+ attribute :user_data
25
24
 
26
- attribute :disk_encrypted
25
+ # Boolean flags
26
+ attribute :compatibility_mode, type: :boolean
27
+ attribute :disk_encrypted, type: :boolean
27
28
 
28
- # Times
29
- attribute :created_at, :type => :time
30
- attribute :started_at, :type => :time
31
- attribute :console_token_expires, :type => :time
32
- attribute :deleted_at, :type => :time
29
+ # Timestamps
30
+ attribute :created_at, type: :time
31
+ attribute :started_at, type: :time
32
+ attribute :console_token_expires, type: :time
33
+ attribute :deleted_at, type: :time
33
34
 
34
- # Links - to be replaced
35
- attribute :account_id, :aliases => "account", :squash => "id"
36
- attribute :image_id, :aliases => "image", :squash => "id"
35
+ # Links
36
+ attribute :account_id, aliases: "account", squash: "id"
37
+ attribute :image_id, aliases: "image", squash: "id"
37
38
 
38
- attribute :snapshots
39
+ attribute :server_type
40
+ attribute :zone
39
41
  attribute :cloud_ip # Creation option only
42
+
40
43
  attribute :cloud_ips
41
44
  attribute :interfaces
42
45
  attribute :server_groups
46
+ attribute :snapshots
43
47
  attribute :volumes
44
- attribute :zone
45
- attribute :server_type
46
48
 
47
49
  def initialize(attributes = {})
48
50
  # Call super first to initialize the service object for our default image
@@ -6,15 +6,23 @@ module Fog
6
6
  # Certain actions can accept a server group and affect all members
7
7
  class ServerGroup < Fog::Brightbox::Model
8
8
  identity :id
9
-
10
- attribute :url
11
9
  attribute :resource_type
10
+ attribute :url
11
+
12
12
  attribute :name
13
13
  attribute :description
14
- attribute :default
15
- attribute :created_at, :type => :time
14
+ attribute :fqdn
15
+
16
+ # Booleans
17
+ attribute :default, type: :boolean
18
+
19
+ # Timestamps
20
+ attribute :created_at, type: :time
16
21
 
17
- attribute :server_ids, :aliases => "servers"
22
+ # Links
23
+ attribute :account_id, aliases: "account", squash: "id"
24
+ attribute :firewall_policy_id, aliases: "firewall_policy", squash: "id"
25
+ attribute :server_ids, aliases: "servers"
18
26
 
19
27
  def save
20
28
  options = {
@@ -11,13 +11,18 @@ module Fog
11
11
  attribute :ssh_key
12
12
 
13
13
  # Boolean flags
14
- attribute :email_verified
15
- attribute :messaging_pref
14
+ attribute :email_verified, type: :boolean
16
15
 
17
- # Links - to be replaced
18
- attribute :account_id, :aliases => "default_account", :squash => "id"
16
+ # Timestamps
17
+ attribute :created_at, type: :time
18
+
19
+ # Links
20
+ attribute :account_id, aliases: "default_account", squash: "id"
19
21
  attribute :accounts
20
22
 
23
+ # Deprecated
24
+ attribute :messaging_pref, type: :boolean
25
+
21
26
  def save
22
27
  requires :identity
23
28
 
@@ -3,10 +3,21 @@ module Fog
3
3
  class Compute
4
4
  class UserCollaboration < Fog::Brightbox::Model
5
5
  identity :id
6
+ # resource_type is buggy for this resource
7
+ attribute :url
8
+
6
9
  attribute :status
10
+
7
11
  attribute :email
8
12
  attribute :role
9
13
  attribute :role_label
14
+
15
+ # Timestamps
16
+ attribute :created_at, type: :time
17
+ attribute :started_at, type: :time
18
+ attribute :finished_at, type: :time
19
+
20
+ # Links
10
21
  attribute :account
11
22
  attribute :user
12
23
  attribute :inviter
@@ -5,34 +5,35 @@ module Fog
5
5
  include Fog::Brightbox::Compute::ResourceLocking
6
6
 
7
7
  identity :id
8
- attribute :url
9
8
  attribute :resource_type
9
+ attribute :url
10
10
 
11
11
  attribute :name
12
- attribute :state, :aliases => "status"
13
-
12
+ attribute :state, aliases: "status"
14
13
  attribute :description
14
+
15
15
  attribute :filesystem_label
16
16
  attribute :filesystem_type
17
17
  attribute :serial
18
- attribute :size
18
+ attribute :size, type: :integer
19
19
  attribute :source
20
20
  attribute :source_type
21
21
  attribute :storage_type
22
22
 
23
- attribute :boot
24
- attribute :delete_with_server
25
- attribute :encrypted
23
+ # Boolean flags
24
+ attribute :boot, type: :boolean
25
+ attribute :delete_with_server, type: :boolean
26
+ attribute :encrypted, type: :boolean
26
27
 
27
- # Times
28
- attribute :created_at, :type => :time
29
- attribute :updated_at, :type => :time
30
- attribute :deleted_at, :type => :time
28
+ # Timestamps
29
+ attribute :created_at, type: :time
30
+ attribute :updated_at, type: :time
31
+ attribute :deleted_at, type: :time
31
32
 
32
33
  # Links
33
- attribute :account_id, :aliases => "account", :squash => "id"
34
- attribute :image_id, :aliases => "image", :squash => "id"
35
- attribute :server_id, :aliases => "server", :squash => "id"
34
+ attribute :account_id, aliases: "account", squash: "id"
35
+ attribute :image_id, aliases: "image", squash: "id"
36
+ attribute :server_id, aliases: "server", squash: "id"
36
37
 
37
38
  def attach(server)
38
39
  requires :identity
@@ -3,13 +3,12 @@ module Fog
3
3
  class Compute
4
4
  class Zone < Fog::Brightbox::Model
5
5
  identity :id
6
- attribute :url
7
6
  attribute :resource_type
8
-
9
- attribute :status
10
- attribute :handle
7
+ attribute :url
11
8
 
12
9
  attribute :description
10
+ attribute :handle
11
+ attribute :status
13
12
  end
14
13
  end
15
14
  end
@@ -31,8 +31,8 @@ module Fog
31
31
  attr_writer :public
32
32
 
33
33
  def public_url
34
- # raise NotImplementedError
35
- ""
34
+ requires :key
35
+ @public_url ||= [service.management_url , Fog::Brightbox::Storage.escape(key, "/")].join("/")
36
36
  end
37
37
 
38
38
  def save
@@ -6,6 +6,10 @@ module Fog
6
6
  # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-10
7
7
  #
8
8
  module OAuth2
9
+ TWO_FACTOR_HEADER = "X-Brightbox-OTP".freeze
10
+
11
+ class TwoFactorMissingError < StandardError; end
12
+
9
13
  # This builds the simplest form of requesting an access token
10
14
  # based on the arguments passed in
11
15
  #
@@ -13,16 +17,38 @@ module Fog
13
17
  # @param [CredentialSet] credentials
14
18
  #
15
19
  # @return [Excon::Response]
20
+ # @raise [Excon::Errors::Unauthorized] if the credentials are rejected by the server
21
+ # @raise [Fog::Brightbox::OAuth2::TwoFactorMissingError] if opted in to 2FA and server reports header is required
16
22
  def request_access_token(connection, credentials)
17
23
  token_strategy = credentials.best_grant_strategy
18
24
 
19
- connection.request(
20
- :path => "/token",
21
- :expects => 200,
22
- :headers => token_strategy.headers,
23
- :method => "POST",
24
- :body => Fog::JSON.encode(token_strategy.authorization_body_data)
25
- )
25
+ if two_factor?
26
+ # When 2FA opt-in is set, we can expect 401 responses as well
27
+ response = connection.request(
28
+ :path => "/token",
29
+ :expects => [200, 401],
30
+ :headers => token_strategy.headers,
31
+ :method => "POST",
32
+ :body => Fog::JSON.encode(token_strategy.authorization_body_data)
33
+ )
34
+
35
+ if response.status == 401 && response.headers[Fog::Brightbox::OAuth2::TWO_FACTOR_HEADER] == "required"
36
+ raise TwoFactorMissingError
37
+ elsif response.status == 401
38
+ raise Excon::Errors.status_error({ expects: 200 }, status: 401)
39
+ else
40
+ response
41
+ end
42
+ else
43
+ # Use classic behaviour and return Excon::
44
+ connection.request(
45
+ :path => "/token",
46
+ :expects => 200,
47
+ :headers => token_strategy.headers,
48
+ :method => "POST",
49
+ :body => Fog::JSON.encode(token_strategy.authorization_body_data)
50
+ )
51
+ end
26
52
  end
27
53
 
28
54
  # Encapsulates credentials required to request access tokens from the
@@ -33,12 +59,14 @@ module Fog
33
59
  class CredentialSet
34
60
  attr_reader :client_id, :client_secret, :username, :password
35
61
  attr_reader :access_token, :refresh_token, :expires_in
62
+ attr_reader :one_time_password
36
63
  #
37
64
  # @param [String] client_id
38
65
  # @param [String] client_secret
39
66
  # @param [Hash] options
40
67
  # @option options [String] :username
41
68
  # @option options [String] :password
69
+ # @option options [String] :one_time_password One Time Password for Two Factor authentication
42
70
  #
43
71
  def initialize(client_id, client_secret, options = {})
44
72
  @client_id = client_id
@@ -48,6 +76,7 @@ module Fog
48
76
  @access_token = options[:access_token]
49
77
  @refresh_token = options[:refresh_token]
50
78
  @expires_in = options[:expires_in]
79
+ @one_time_password = options[:one_time_password]
51
80
  end
52
81
 
53
82
  # Returns true if user details are available
@@ -142,6 +171,17 @@ module Fog
142
171
  "password" => @credentials.password
143
172
  }
144
173
  end
174
+
175
+ def headers
176
+ {
177
+ "Authorization" => authorization_header,
178
+ "Content-Type" => "application/json"
179
+ }.tap do |headers|
180
+ if @credentials.one_time_password
181
+ headers[TWO_FACTOR_HEADER] = @credentials.one_time_password
182
+ end
183
+ end
184
+ end
145
185
  end
146
186
 
147
187
  # This strategy attempts to use a refresh_token gained during an earlier
@@ -0,0 +1,22 @@
1
+ module Fog
2
+ module Brightbox
3
+ class Compute
4
+ class Real
5
+ # Create a new config map
6
+ #
7
+ # @param [Hash] options
8
+ # @option options [String] :name to identify this config map
9
+ # @option options [Hash] :data key/values to expose in config map
10
+ # @option options [Boolean] :nested passed through with the API request. When true nested resources are expanded.
11
+ #
12
+ # @return [Hash] if successful Hash version of JSON object
13
+ # @return [NilClass] if no options were passed
14
+ #
15
+ def create_config_map(options)
16
+ return nil if options.empty? || options.nil?
17
+ wrapped_request("post", "/1.0/config_maps", [200], options)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,20 @@
1
+ module Fog
2
+ module Brightbox
3
+ class Compute
4
+ class Real
5
+ # Destroy the config map
6
+ #
7
+ # @param [String] identifier Unique reference to identify the resource
8
+ # @param [Hash] options
9
+ # @option options [Boolean] :nested passed through with the API request. When true nested resources are expanded.
10
+ #
11
+ # @return [Hash] if successful Hash version of JSON object
12
+ #
13
+ def delete_config_map(identifier, options = {})
14
+ return nil if identifier.nil? || identifier == ""
15
+ wrapped_request("delete", "/1.0/config_maps/#{identifier}", [200], options)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,18 @@
1
+ module Fog
2
+ module Brightbox
3
+ class Compute
4
+ class Real
5
+ # @param [String] identifier Unique reference to identify the resource
6
+ # @param [Hash] options
7
+ # @option options [Boolean] :nested passed through with the API request. When true nested resources are expanded.
8
+ #
9
+ # @return [Hash] if successful Hash version of JSON object
10
+ #
11
+ def get_config_map(identifier, options = {})
12
+ return nil if identifier.nil? || identifier == ""
13
+ wrapped_request("get", "/1.0/config_maps/#{identifier}", [200], options)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ module Fog
2
+ module Brightbox
3
+ class Compute
4
+ class Real
5
+ # Lists summary details of config maps owned by the account.
6
+ #
7
+ # @param [Hash] options
8
+ # @option options [Boolean] :nested passed through with the API request. When true nested resources are expanded.
9
+ #
10
+ # @return [Hash] if successful Hash version of JSON object
11
+ #
12
+ def list_config_maps(options = {})
13
+ wrapped_request("get", "/1.0/config_maps", [200], options)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ module Fog
2
+ module Brightbox
3
+ class Compute
4
+ class Real
5
+ # @param [String] identifier Unique reference to identify the resource
6
+ # @param [Hash] options
7
+ # @option options [String] :name to identifier this config map
8
+ # @option options [Hash] :data key/values to expose in config map
9
+ # @option options [Boolean] :nested passed through with the API request. When true nested resources are expanded.
10
+ #
11
+ # @return [Hash] if successful Hash version of JSON object
12
+ # @return [NilClass] if no options were passed
13
+ #
14
+ def update_config_map(identifier, options)
15
+ return nil if identifier.nil? || identifier == ""
16
+ return nil if options.empty? || options.nil?
17
+ wrapped_request("put", "/1.0/config_maps/#{identifier}", [200], options)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -1,5 +1,5 @@
1
1
  module Fog
2
2
  module Brightbox
3
- VERSION = "1.5.0"
3
+ VERSION = "1.7.1"
4
4
  end
5
5
  end
@@ -0,0 +1,41 @@
1
+ require "spec_helper"
2
+
3
+ describe Fog::Brightbox::Compute, "#credentials" do
4
+ describe "when 2FA support is disabled" do
5
+ before do
6
+ @options = {
7
+ brightbox_client_id: "app-12345",
8
+ brightbox_secret: "1234567890",
9
+ brightbox_username: "jason.null@brightbox.com",
10
+ brightbox_password: "HR4life",
11
+ brightbox_one_time_password: "123456"
12
+ }
13
+ @service = Fog::Brightbox::Compute.new(@options)
14
+ end
15
+
16
+ it "does not add passed OTP to credentials" do
17
+ assert_kind_of Fog::Brightbox::OAuth2::CredentialSet, @service.credentials
18
+ assert_nil @service.credentials.one_time_password
19
+ end
20
+ end
21
+
22
+ describe "with 2FA support is enabled" do
23
+ before do
24
+ @expected_otp = "123456"
25
+ @options = {
26
+ brightbox_client_id: "app-12345",
27
+ brightbox_secret: "1234567890",
28
+ brightbox_username: "jason.null@brightbox.com",
29
+ brightbox_password: "HR4life",
30
+ brightbox_support_two_factor: true,
31
+ brightbox_one_time_password: @expected_otp
32
+ }
33
+ @service = Fog::Brightbox::Compute.new(@options)
34
+ end
35
+
36
+ it "adds passed OTP to credentials" do
37
+ assert_kind_of Fog::Brightbox::OAuth2::CredentialSet, @service.credentials
38
+ assert @expected_otp, @service.credentials.one_time_password
39
+ end
40
+ end
41
+ end