diff --git a/lib/fog/brightbox/compute.rb b/lib/fog/brightbox/compute.rb index 3e21628219..8444f9701e 100644 --- a/lib/fog/brightbox/compute.rb +++ b/lib/fog/brightbox/compute.rb @@ -1,14 +1,12 @@ require 'fog/brightbox' require 'fog/compute' -require 'fog/brightbox/oauth2' +require 'fog/brightbox/compute/shared' require 'fog/brightbox/compute/image_selector' module Fog module Compute class Brightbox < Fog::Service - API_URL = "https://api.gb1.brightbox.com/" - # Client credentials requires :brightbox_client_id, :brightbox_secret @@ -34,6 +32,8 @@ class Brightbox < Fog::Service model :application collection :api_clients model :api_client + collection :collaborations + model :collaboration collection :servers model :server collection :server_groups @@ -54,17 +54,22 @@ class Brightbox < Fog::Service model :cloud_ip collection :users model :user + collection :user_collaborations + model :user_collaboration request_path 'fog/brightbox/requests/compute' + request :accept_user_collaboration request :activate_console_server request :add_listeners_load_balancer request :add_nodes_load_balancer request :add_servers_server_group request :apply_to_firewall_policy + request :accept_user_collaboration request :remove_firewall_policy request :create_api_client request :create_application request :create_cloud_ip + request :create_collaboration request :create_firewall_policy request :create_firewall_rule request :create_image @@ -74,17 +79,20 @@ class Brightbox < Fog::Service request :delete_api_client request :delete_application request :delete_cloud_ip + request :delete_collaboration request :delete_firewall_policy request :delete_firewall_rule request :delete_image request :delete_load_balancer request :delete_server request :delete_server_group + request :delete_user_collaboration request :get_account request :get_api_client request :get_application request :get_authenticated_user request :get_cloud_ip + request :get_collaboration request :get_firewall_policy request :get_firewall_rule request :get_image @@ -95,11 +103,13 @@ class Brightbox < Fog::Service request :get_server_group request :get_server_type request :get_user + request :get_user_collaboration request :get_zone request :list_accounts request :list_api_clients request :list_applications request :list_cloud_ips + request :list_collaborations request :list_firewall_policies request :list_images request :list_load_balancers @@ -107,16 +117,21 @@ class Brightbox < Fog::Service request :list_server_types request :list_servers request :list_users + request :list_user_collaborations request :list_zones request :map_cloud_ip request :move_servers_server_group + request :reject_user_collaboration request :remove_listeners_load_balancer request :remove_nodes_load_balancer request :remove_servers_server_group + request :resend_collaboration request :reset_ftp_password_account request :reset_ftp_password_scoped_account request :reset_secret_api_client request :reset_secret_application + request :resend_collaboration + request :reject_user_collaboration request :shutdown_server request :snapshot_server request :start_server @@ -135,220 +150,13 @@ class Brightbox < Fog::Service request :update_server_group request :update_user - module Shared - include Fog::Brightbox::OAuth2 - - # Creates a new instance of the Brightbox Compute service - # - # @note If you create service using just a refresh token when it - # expires the service will no longer be able to authenticate. - # - # @param [Hash] options - # @option options [String] :brightbox_api_url Override the default (or configured) API endpoint - # @option options [String] :brightbox_auth_url Override the default (or configured) API authentication endpoint - # @option options [String] :brightbox_client_id Client identifier to authenticate with (overrides configured) - # @option options [String] :brightbox_secret Client secret to authenticate with (overrides configured) - # @option options [String] :brightbox_username Email or user identifier for user based authentication - # @option options [String] :brightbox_password Password for user based authentication - # @option options [String] :brightbox_account Account identifier to scope this connection to - # @option options [String] :connection_options Settings to pass to underlying {Fog::Connection} - # @option options [Boolean] :persistent Sets a persistent HTTP {Fog::Connection} - # @option options [String] :brightbox_access_token Sets the OAuth access token to use rather than requesting a new token - # @option options [String] :brightbox_refresh_token Sets the refresh token to use when requesting a newer access token - # @option options [String] :brightbox_token_management Overide the existing behaviour to request access tokens if expired (default is `true`) - # - def initialize(options) - # Currently authentication and api endpoints are the same but may change - @auth_url = options[:brightbox_auth_url] || Fog.credentials[:brightbox_auth_url] || API_URL - @auth_connection = Fog::Connection.new(@auth_url) - - @api_url = options[:brightbox_api_url] || Fog.credentials[:brightbox_api_url] || API_URL - @connection_options = options[:connection_options] || {} - @persistent = options[:persistent] || false - @connection = Fog::Connection.new(@api_url, @persistent, @connection_options) - - # Authentication options - client_id = options[:brightbox_client_id] || Fog.credentials[:brightbox_client_id] - client_secret = options[:brightbox_secret] || Fog.credentials[:brightbox_secret] - - username = options[:brightbox_username] || Fog.credentials[:brightbox_username] - password = options[:brightbox_password] || Fog.credentials[:brightbox_password] - @configured_account = options[:brightbox_account] || Fog.credentials[:brightbox_account] - # Request account can be changed at anytime and changes behaviour of future requests - @scoped_account = @configured_account - - credential_options = {:username => username, :password => password} - @credentials = CredentialSet.new(client_id, client_secret, credential_options) - - # If existing tokens have been cached, allow continued use of them in the service - @credentials.update_tokens(options[:brightbox_access_token], options[:brightbox_refresh_token]) - - @token_management = options.fetch(:brightbox_token_management, true) - end - - # Sets the scoped account for future requests - # @param [String] scoped_account Identifier of the account to scope request to - def scoped_account=(scoped_account) - @scoped_account = scoped_account - end - - # This returns the account identifier that the request should be scoped by - # based on the options passed to the request and current configuration - # - # @param [String] options_account Any identifier passed into the request - # - # @return [String, nil] The account identifier to scope the request to or nil - def scoped_account(options_account = nil) - [options_account, @scoped_account].compact.first - end - - # Resets the scoped account back to intially configured one - def scoped_account_reset - @scoped_account = @configured_account - end - - # Returns the scoped account being used for requests - # - # * For API clients this is the owning account - # * For User applications this is the account specified by either +account_id+ - # option on the service or the +brightbox_account+ setting in your configuration - # - # @return [Fog::Compute::Brightbox::Account] - # - def account - account_data = get_scoped_account.merge(:service => self) - Fog::Compute::Brightbox::Account.new(account_data) - end - - # Returns true if authentication is being performed as a user - # @return [Boolean] - def authenticating_as_user? - @credentials.user_details? - end - - # Returns true if an access token is set - # @return [Boolean] - def access_token_available? - !! @credentials.access_token - end - - # Returns the current access token or nil - # @return [String,nil] - def access_token - @credentials.access_token - end - - # Returns the current refresh token or nil - # @return [String,nil] - def refresh_token - @credentials.refresh_token - end - - # Returns the current token expiry time in seconds or nil - # @return [Number,nil] - def expires_in - @credentials.expires_in - end - - # Requests a new access token - # - # @return [String] New access token - def get_access_token - begin - get_access_token! - rescue Excon::Errors::Unauthorized, Excon::Errors::BadRequest - @credentials.update_tokens(nil, nil) - end - @credentials.access_token - end - - # Requests a new access token and raises if there is a problem - # - # @return [String] New access token - # @raise [Excon::Errors::BadRequest] The credentials are expired or incorrect - # - def get_access_token! - response = request_access_token(@auth_connection, @credentials) - update_credentials_from_response(@credentials, response) - @credentials.access_token - end - - # Returns an identifier for the default image for use - # - # Currently tries to find the latest version of Ubuntu (i686) from - # Brightbox. - # - # Highly recommended that you actually select the image you want to run - # on your servers yourself! - # - # @return [String] if image is found, returns the identifier - # @return [NilClass] if no image is found or an error occurs - # - def default_image - return @default_image_id unless @default_image_id.nil? - @default_image_id = Fog.credentials[:brightbox_default_image] || select_default_image - end - - private - - # This makes a request of the API based on the configured setting for - # token management. - # - # @param [Hash] options Excon compatible options - # @see https://github.com/geemus/excon/blob/master/lib/excon/connection.rb - # - # @return [Hash] Data of response body - # - def make_request(options) - if @token_management - managed_token_request(options) - else - authenticated_request(options) - end - end - - # This request checks for access tokens and will ask for a new one if - # it receives Unauthorized from the API before repeating the request - # - # @param [Hash] options Excon compatible options - # - # @return [Excon::Response] - def managed_token_request(options) - begin - get_access_token unless access_token_available? - response = authenticated_request(options) - rescue Excon::Errors::Unauthorized - get_access_token - response = authenticated_request(options) - end - end - - # This request makes an authenticated request of the API using currently - # setup credentials. - # - # @param [Hash] options Excon compatible options - # - # @see https://github.com/geemus/excon/blob/master/lib/excon/connection.rb - # - # @return [Excon::Response] - def authenticated_request(options) - headers = options[:headers] || {} - headers.merge!("Authorization" => "OAuth #{@credentials.access_token}", "Content-Type" => "application/json") - options[:headers] = headers - # TODO This is just a wrapper around a call to Excon::Connection#request - # so can be extracted from Compute by passing in the connection, - # credentials and options - @connection.request(options) - end - end - # The Mock Service allows you to run a fake instance of the Service # which makes no real connections. # # @todo Implement # class Mock - include Shared + include Fog::Brightbox::Compute::Shared def request(method, path, expected_responses, parameters = {}) _request @@ -373,7 +181,7 @@ def select_default_image # service. # class Real - include Shared + include Fog::Brightbox::Compute::Shared # Makes an API request to the given path using passed options or those # set with the service setup diff --git a/lib/fog/brightbox/compute/shared.rb b/lib/fog/brightbox/compute/shared.rb new file mode 100644 index 0000000000..b889b4f3e2 --- /dev/null +++ b/lib/fog/brightbox/compute/shared.rb @@ -0,0 +1,232 @@ +require "fog/brightbox/oauth2" + +module Fog + module Brightbox + module Compute + + # The Shared module consists of code that was duplicated between the Real + # and Mock implementations. + # + module Shared + include Fog::Brightbox::OAuth2 + + API_URL = "https://api.gb1.brightbox.com/" + + # Creates a new instance of the Brightbox Compute service + # + # @note If you create service using just a refresh token when it + # expires the service will no longer be able to authenticate. + # + # @param [Hash] options + # @option options [String] :brightbox_api_url + # Override the default (or configured) API endpoint + # @option options [String] :brightbox_auth_url + # Override the default (or configured) API authentication endpoint + # @option options [String] :brightbox_client_id + # Client identifier to authenticate with (overrides configured) + # @option options [String] :brightbox_secret + # Client secret to authenticate with (overrides configured) + # @option options [String] :brightbox_username + # Email or user identifier for user based authentication + # @option options [String] :brightbox_password + # Password for user based authentication + # @option options [String] :brightbox_account + # Account identifier to scope this connection to + # @option options [String] :connection_options + # Settings to pass to underlying {Fog::Connection} + # @option options [Boolean] :persistent + # Sets a persistent HTTP {Fog::Connection} + # @option options [String] :brightbox_access_token + # Sets the OAuth access token to use rather than requesting a new token + # @option options [String] :brightbox_refresh_token + # Sets the refresh token to use when requesting a newer access token + # @option options [String] (true) :brightbox_token_management + # Overide the existing behaviour to request access tokens if expired + # + def initialize(options) + # Currently authentication and api endpoints are the same but may change + @auth_url = options[:brightbox_auth_url] || Fog.credentials[:brightbox_auth_url] || API_URL + @auth_connection = Fog::Connection.new(@auth_url) + + @api_url = options[:brightbox_api_url] || Fog.credentials[:brightbox_api_url] || API_URL + @connection_options = options[:connection_options] || {} + @persistent = options[:persistent] || false + @connection = Fog::Connection.new(@api_url, @persistent, @connection_options) + + # Authentication options + client_id = options[:brightbox_client_id] || Fog.credentials[:brightbox_client_id] + client_secret = options[:brightbox_secret] || Fog.credentials[:brightbox_secret] + + username = options[:brightbox_username] || Fog.credentials[:brightbox_username] + password = options[:brightbox_password] || Fog.credentials[:brightbox_password] + @configured_account = options[:brightbox_account] || Fog.credentials[:brightbox_account] + # Request account can be changed at anytime and changes behaviour of future requests + @scoped_account = @configured_account + + credential_options = {:username => username, :password => password} + @credentials = CredentialSet.new(client_id, client_secret, credential_options) + + # If existing tokens have been cached, allow continued use of them in the service + @credentials.update_tokens(options[:brightbox_access_token], options[:brightbox_refresh_token]) + + @token_management = options.fetch(:brightbox_token_management, true) + end + + # Sets the scoped account for future requests + # @param [String] scoped_account Identifier of the account to scope request to + def scoped_account=(scoped_account) + @scoped_account = scoped_account + end + + # This returns the account identifier that the request should be scoped by + # based on the options passed to the request and current configuration + # + # @param [String] options_account Any identifier passed into the request + # + # @return [String, nil] The account identifier to scope the request to or nil + def scoped_account(options_account = nil) + [options_account, @scoped_account].compact.first + end + + # Resets the scoped account back to intially configured one + def scoped_account_reset + @scoped_account = @configured_account + end + + # Returns the scoped account being used for requests + # + # * For API clients this is the owning account + # * For User applications this is the account specified by either +account_id+ + # option on the service or the +brightbox_account+ setting in your configuration + # + # @return [Fog::Compute::Brightbox::Account] + # + def account + account_data = get_scoped_account.merge(:service => self) + Fog::Compute::Brightbox::Account.new(account_data) + end + + # Returns true if authentication is being performed as a user + # @return [Boolean] + def authenticating_as_user? + @credentials.user_details? + end + + # Returns true if an access token is set + # @return [Boolean] + def access_token_available? + !! @credentials.access_token + end + + # Returns the current access token or nil + # @return [String,nil] + def access_token + @credentials.access_token + end + + # Returns the current refresh token or nil + # @return [String,nil] + def refresh_token + @credentials.refresh_token + end + + # Returns the current token expiry time in seconds or nil + # @return [Number,nil] + def expires_in + @credentials.expires_in + end + + # Requests a new access token + # + # @return [String] New access token + def get_access_token + begin + get_access_token! + rescue Excon::Errors::Unauthorized, Excon::Errors::BadRequest + @credentials.update_tokens(nil, nil) + end + @credentials.access_token + end + + # Requests a new access token and raises if there is a problem + # + # @return [String] New access token + # @raise [Excon::Errors::BadRequest] The credentials are expired or incorrect + # + def get_access_token! + response = request_access_token(@auth_connection, @credentials) + update_credentials_from_response(@credentials, response) + @credentials.access_token + end + + # Returns an identifier for the default image for use + # + # Currently tries to find the latest version of Ubuntu (i686) from + # Brightbox. + # + # Highly recommended that you actually select the image you want to run + # on your servers yourself! + # + # @return [String] if image is found, returns the identifier + # @return [NilClass] if no image is found or an error occurs + # + def default_image + return @default_image_id unless @default_image_id.nil? + @default_image_id = Fog.credentials[:brightbox_default_image] || select_default_image + end + + private + + # This makes a request of the API based on the configured setting for + # token management. + # + # @param [Hash] options Excon compatible options + # @see https://github.com/geemus/excon/blob/master/lib/excon/connection.rb + # + # @return [Hash] Data of response body + # + def make_request(options) + if @token_management + managed_token_request(options) + else + authenticated_request(options) + end + end + + # This request checks for access tokens and will ask for a new one if + # it receives Unauthorized from the API before repeating the request + # + # @param [Hash] options Excon compatible options + # + # @return [Excon::Response] + def managed_token_request(options) + begin + get_access_token unless access_token_available? + response = authenticated_request(options) + rescue Excon::Errors::Unauthorized + get_access_token + response = authenticated_request(options) + end + end + + # This request makes an authenticated request of the API using currently + # setup credentials. + # + # @param [Hash] options Excon compatible options + # + # @see https://github.com/geemus/excon/blob/master/lib/excon/connection.rb + # + # @return [Excon::Response] + def authenticated_request(options) + headers = options[:headers] || {} + headers.merge!("Authorization" => "OAuth #{@credentials.access_token}", "Content-Type" => "application/json") + options[:headers] = headers + # TODO This is just a wrapper around a call to Excon::Connection#request + # so can be extracted from Compute by passing in the connection, + # credentials and options + @connection.request(options) + end + end + end + end +end diff --git a/lib/fog/brightbox/models/compute/collaboration.rb b/lib/fog/brightbox/models/compute/collaboration.rb new file mode 100644 index 0000000000..f2660cb8f2 --- /dev/null +++ b/lib/fog/brightbox/models/compute/collaboration.rb @@ -0,0 +1,43 @@ +require 'fog/core/model' + +module Fog + module Compute + class Brightbox + class Collaboration < Fog::Model + identity :id + attribute :status + attribute :email + attribute :role + attribute :role_label + attribute :account + attribute :user + attribute :inviter + + def account_id + account['id'] || account[:id] + end + + def save + raise Fog::Errors::Error.new('Resaving an existing object may create a duplicate') if identity + + options = { + :role => role, + :email => email + }.delete_if { |k, v| v.nil? || v == "" } + + data = connection.create_collaboration(options) + merge_attributes(data) + true + end + + def destroy + requires :identity + connection.destroy_collaboration(identity) + true + end + + end + end + end +end + diff --git a/lib/fog/brightbox/models/compute/collaborations.rb b/lib/fog/brightbox/models/compute/collaborations.rb new file mode 100644 index 0000000000..b8e4494656 --- /dev/null +++ b/lib/fog/brightbox/models/compute/collaborations.rb @@ -0,0 +1,23 @@ +require "fog/core/collection" +require "fog/brightbox/models/compute/collaboration" + +module Fog + module Compute + class Brightbox + class Collaborations < Fog::Collection + model Fog::Compute::Brightbox::Collaboration + + def all + data = connection.list_collaborations + load(data) + end + + def destroy + requires :identity + connection.destroy_collaboration(identity) + true + end + end + end + end +end diff --git a/lib/fog/brightbox/models/compute/user_collaboration.rb b/lib/fog/brightbox/models/compute/user_collaboration.rb new file mode 100644 index 0000000000..88a7bbc1bb --- /dev/null +++ b/lib/fog/brightbox/models/compute/user_collaboration.rb @@ -0,0 +1,29 @@ +require 'fog/core/model' + +module Fog + module Compute + class Brightbox + class UserCollaboration < Fog::Model + identity :id + attribute :status + attribute :email + attribute :role + attribute :role_label + attribute :account + attribute :user + attribute :inviter + + def account_id + account['id'] || account[:id] + end + + def destroy + requires :identity + connection.destroy_user_collaboration(identity) + true + end + + end + end + end +end diff --git a/lib/fog/brightbox/models/compute/user_collaborations.rb b/lib/fog/brightbox/models/compute/user_collaborations.rb new file mode 100644 index 0000000000..43a963d925 --- /dev/null +++ b/lib/fog/brightbox/models/compute/user_collaborations.rb @@ -0,0 +1,23 @@ +require "fog/core/collection" +require "fog/brightbox/models/compute/user_collaboration" + +module Fog + module Compute + class Brightbox + class UserCollaborations < Fog::Collection + model Fog::Compute::Brightbox::UserCollaboration + + def all + data = connection.list_user_collaborations + load(data) + end + + def destroy + requires :identity + connection.destroy_user_collaboration(identity) + true + end + end + end + end +end diff --git a/lib/fog/brightbox/requests/compute/accept_user_collaboration.rb b/lib/fog/brightbox/requests/compute/accept_user_collaboration.rb new file mode 100644 index 0000000000..d9f8a353e9 --- /dev/null +++ b/lib/fog/brightbox/requests/compute/accept_user_collaboration.rb @@ -0,0 +1,21 @@ +module Fog + module Compute + class Brightbox + class Real + # Accepts the collaboration and gaining permitted access + # + # @param [String] identifier Unique reference to identify the resource + # + # @return [Hash] if successful Hash version of JSON object + # + # @see https://api.gb1.brightbox.com/1.0/#user_collaboration_accept_user_collaboration + # + def accept_user_collaboration(identifier) + return nil if identifier.nil? || identifier == "" + wrapped_request("post", "/1.0/user/collaborations/#{identifier}/accept", [200]) + end + + end + end + end +end diff --git a/lib/fog/brightbox/requests/compute/create_collaboration.rb b/lib/fog/brightbox/requests/compute/create_collaboration.rb new file mode 100644 index 0000000000..13088c36f1 --- /dev/null +++ b/lib/fog/brightbox/requests/compute/create_collaboration.rb @@ -0,0 +1,23 @@ +module Fog + module Compute + class Brightbox + class Real + # Creates a new collaboration for a user for the account + # + # @param [Hash] options + # @option options [String] :email Email address of user to invite + # @option options [String] :role Role to grant to the user. Currently only `admin` + # + # @return [Hash] if successful Hash version of JSON object + # @return [NilClass] if no options were passed + # + # @see https://api.gb1.brightbox.com/1.0/#collaboration_create_collaboration + # + def create_collaboration(options) + wrapped_request("post", "/1.0/collaborations", [201], options) + end + + end + end + end +end diff --git a/lib/fog/brightbox/requests/compute/delete_collaboration.rb b/lib/fog/brightbox/requests/compute/delete_collaboration.rb new file mode 100644 index 0000000000..39eef88f1a --- /dev/null +++ b/lib/fog/brightbox/requests/compute/delete_collaboration.rb @@ -0,0 +1,28 @@ +module Fog + module Compute + class Brightbox + class Real + # Cancels or completes the collaboration + # + # @param [String] identifier Unique reference to identify the resource + # + # @return [Hash] if successful Hash version of JSON object + # + # @see https://api.gb1.brightbox.com/1.0/#collaboration_delete_collaboration + # + def delete_collaboration(identifier) + return nil if identifier.nil? || identifier == "" + wrapped_request("delete", "/1.0/collaborations/#{identifier}", [200]) + end + + # Old format of the delete request. + # + # @deprecated Use +#delete_collaboration+ instead + # + def destroy_collaboration(identifier) + delete_collaboration(identifier) + end + end + end + end +end diff --git a/lib/fog/brightbox/requests/compute/delete_user_collaboration.rb b/lib/fog/brightbox/requests/compute/delete_user_collaboration.rb new file mode 100644 index 0000000000..2aad328ca7 --- /dev/null +++ b/lib/fog/brightbox/requests/compute/delete_user_collaboration.rb @@ -0,0 +1,28 @@ +module Fog + module Compute + class Brightbox + class Real + # Ends an existing 'accepted' collaboration + # + # @param [String] identifier Unique reference to identify the resource + # + # @return [Hash] if successful Hash version of JSON object + # + # @see https://api.gb1.brightbox.com/1.0/#user_collaboration_delete_user_collaboration + # + def delete_user_collaboration(identifier) + return nil if identifier.nil? || identifier == "" + wrapped_request("delete", "/1.0/user/collaborations/#{identifier}", [200]) + end + + # Old format of the delete request. + # + # @deprecated Use +#delete_user_collaboration+ instead + # + def destroy_user_collaboration(identifier) + delete_user_collaboration(identifier) + end + end + end + end +end diff --git a/lib/fog/brightbox/requests/compute/destroy_user_collaboration.rb b/lib/fog/brightbox/requests/compute/destroy_user_collaboration.rb new file mode 100644 index 0000000000..139b146092 --- /dev/null +++ b/lib/fog/brightbox/requests/compute/destroy_user_collaboration.rb @@ -0,0 +1,21 @@ +module Fog + module Compute + class Brightbox + class Real + # Ends an existing 'accepted' collaboration + # + # @param [String] identifier Unique reference to identify the resource + # + # @return [Hash] The JSON response parsed to a Hash + # + # @see https://api.gb1.brightbox.com/1.0/#user_collaboration_destroy_user_collaboration + # + def destroy_user_collaboration(identifier) + return nil if identifier.nil? || identifier == "" + wrapped_request("delete", "/1.0/user/collaborations/#{identifier}", [200]) + end + + end + end + end +end diff --git a/lib/fog/brightbox/requests/compute/get_collaboration.rb b/lib/fog/brightbox/requests/compute/get_collaboration.rb new file mode 100644 index 0000000000..27140ea302 --- /dev/null +++ b/lib/fog/brightbox/requests/compute/get_collaboration.rb @@ -0,0 +1,21 @@ +module Fog + module Compute + class Brightbox + class Real + # Shows details of one collaboration + # + # @param [String] identifier Unique reference to identify the resource + # + # @return [Hash] if successful Hash version of JSON object + # + # @see https://api.gb1.brightbox.com/1.0/#collaboration_get_collaboration + # + def get_collaboration(identifier) + return nil if identifier.nil? || identifier == "" + wrapped_request("get", "/1.0/collaborations/#{identifier}", [200]) + end + + end + end + end +end diff --git a/lib/fog/brightbox/requests/compute/get_user_collaboration.rb b/lib/fog/brightbox/requests/compute/get_user_collaboration.rb new file mode 100644 index 0000000000..4ff7c538bd --- /dev/null +++ b/lib/fog/brightbox/requests/compute/get_user_collaboration.rb @@ -0,0 +1,21 @@ +module Fog + module Compute + class Brightbox + class Real + # Shows details of one collaboration + # + # @param [String] identifier Unique reference to identify the resource + # + # @return [Hash] if successful Hash version of JSON object + # + # @see https://api.gb1.brightbox.com/1.0/#user_collaboration_get_user_collaboration + # + def get_user_collaboration(identifier) + return nil if identifier.nil? || identifier == "" + wrapped_request("get", "/1.0/user/collaborations/#{identifier}", [200]) + end + + end + end + end +end diff --git a/lib/fog/brightbox/requests/compute/list_collaborations.rb b/lib/fog/brightbox/requests/compute/list_collaborations.rb new file mode 100644 index 0000000000..c57615672c --- /dev/null +++ b/lib/fog/brightbox/requests/compute/list_collaborations.rb @@ -0,0 +1,19 @@ +module Fog + module Compute + class Brightbox + class Real + # Lists all the account collaborations + # + # + # @return [Hash] if successful Hash version of JSON object + # + # @see https://api.gb1.brightbox.com/1.0/#collaboration_list_collaborations + # + def list_collaborations + wrapped_request("get", "/1.0/collaborations", [200]) + end + + end + end + end +end diff --git a/lib/fog/brightbox/requests/compute/list_user_collaborations.rb b/lib/fog/brightbox/requests/compute/list_user_collaborations.rb new file mode 100644 index 0000000000..0033fe2406 --- /dev/null +++ b/lib/fog/brightbox/requests/compute/list_user_collaborations.rb @@ -0,0 +1,19 @@ +module Fog + module Compute + class Brightbox + class Real + # Lists all collaborations the user is involved with + # + # + # @return [Hash] if successful Hash version of JSON object + # + # @see https://api.gb1.brightbox.com/1.0/#user_collaboration_list_user_collaborations + # + def list_user_collaborations + wrapped_request("get", "/1.0/user/collaborations", [200]) + end + + end + end + end +end diff --git a/lib/fog/brightbox/requests/compute/reject_user_collaboration.rb b/lib/fog/brightbox/requests/compute/reject_user_collaboration.rb new file mode 100644 index 0000000000..ff12cb48c2 --- /dev/null +++ b/lib/fog/brightbox/requests/compute/reject_user_collaboration.rb @@ -0,0 +1,21 @@ +module Fog + module Compute + class Brightbox + class Real + # Rejects the collaboration and removes the offer + # + # @param [String] identifier Unique reference to identify the resource + # + # @return [Hash] if successful Hash version of JSON object + # + # @see https://api.gb1.brightbox.com/1.0/#user_collaboration_reject_user_collaboration + # + def reject_user_collaboration(identifier) + return nil if identifier.nil? || identifier == "" + wrapped_request("post", "/1.0/user/collaborations/#{identifier}/reject", [200]) + end + + end + end + end +end diff --git a/lib/fog/brightbox/requests/compute/resend_collaboration.rb b/lib/fog/brightbox/requests/compute/resend_collaboration.rb new file mode 100644 index 0000000000..f003c58b8e --- /dev/null +++ b/lib/fog/brightbox/requests/compute/resend_collaboration.rb @@ -0,0 +1,21 @@ +module Fog + module Compute + class Brightbox + class Real + # Resends the invitation email to the collaborator + # + # @param [String] identifier Unique reference to identify the resource + # + # @return [Hash] if successful Hash version of JSON object + # + # @see https://api.gb1.brightbox.com/1.0/#collaboration_resend_collaboration + # + def resend_collaboration(identifier) + return nil if identifier.nil? || identifier == "" + wrapped_request("post", "/1.0/collaborations/#{identifier}/resend", [200]) + end + + end + end + end +end diff --git a/tests/brightbox/requests/compute/collaboration_tests.rb b/tests/brightbox/requests/compute/collaboration_tests.rb new file mode 100644 index 0000000000..b389615748 --- /dev/null +++ b/tests/brightbox/requests/compute/collaboration_tests.rb @@ -0,0 +1,41 @@ +Shindo.tests('Fog::Compute[:brightbox] | collaboration requests', ['brightbox']) do + + tests('success') do + + tests("#create_collaboration") do + pending if Fog.mocking? + collaboration = Fog::Compute[:brightbox].create_collaboration(:email => "paul@example.com", :role => "admin") + @collaboration_id = collaboration['id'] + formats(Brightbox::Compute::Formats::Full::COLLABORATION, false) { collaboration } + end + + + tests("#list_collaborations") do + pending if Fog.mocking? + result = Fog::Compute[:brightbox].list_collaborations + + formats(Brightbox::Compute::Formats::Collection::COLLABORATIONS, false) { result } + end + + tests("#get_collaboration") do + pending if Fog.mocking? + result = Fog::Compute[:brightbox].get_collaboration(@collaboration_id) + formats(Brightbox::Compute::Formats::Full::COLLABORATION, false) { result } + end + + + tests("#destroy_collaboration") do + pending if Fog.mocking? + result = Fog::Compute[:brightbox].destroy_collaboration(@collaboration_id) + formats(Brightbox::Compute::Formats::Full::COLLABORATION, false) { result } + end + end + + tests("failure") do + tests("get_collaboration('col-abcde')").raises(Excon::Errors::NotFound) do + pending if Fog.mocking? + Fog::Compute[:brightbox].get_collaboration("col-abcde") + end + end + +end diff --git a/tests/brightbox/requests/compute/helper.rb b/tests/brightbox/requests/compute/helper.rb index c8fa7e907b..04ab579e2c 100644 --- a/tests/brightbox/requests/compute/helper.rb +++ b/tests/brightbox/requests/compute/helper.rb @@ -8,6 +8,7 @@ module Interface; end module LoadBalancer; end module Server; end module ServerGroup; end + module User; end module Zone; end end end @@ -34,6 +35,9 @@ module Zone; end Hash.send :include, Fog::Brightbox::Nullable::ServerGroup NilClass.send :include, Fog::Brightbox::Nullable::ServerGroup +Hash.send :include, Fog::Brightbox::Nullable::User +NilClass.send :include, Fog::Brightbox::Nullable::User + Hash.send :include, Fog::Brightbox::Nullable::Zone NilClass.send :include, Fog::Brightbox::Nullable::Zone @@ -75,8 +79,8 @@ def self.select_testing_image_from_api raise "No available images!" if images.empty? images.select { |img| img["official"] && img["virtual_size"] != 0 }.sort_by { |img| img["disk_size"] }.first || images.first end - end + module Formats module Struct CIP_PORT_TRANSLATOR = { @@ -231,6 +235,20 @@ module Nested "email_address" => String } + + COLLABORATION = { + "id" => String, + "resource_type" => String, + "url" => String, + "status" => String, + "email" => Fog::Nullable::String, + "role" => String, + "role_label" => String, + "user" => Fog::Brightbox::Nullable::User, + "account" => Brightbox::Compute::Formats::Nested::ACCOUNT, + "inviter" => Brightbox::Compute::Formats::Nested::USER + } + ZONE = { "id" => String, "resource_type" => String, @@ -413,6 +431,19 @@ module Collected "default_account" => NilClass } + COLLABORATION = { + "id" => String, + "resource_type" => String, + "url" => String, + "status" => String, + "role" => String, + "role_label" => String, + "email" => Fog::Nullable::String, + "user" => Fog::Brightbox::Nullable::User, + "account" => Brightbox::Compute::Formats::Nested::ACCOUNT, + "inviter" => Brightbox::Compute::Formats::Nested::USER + } + ZONE = { "id" => String, "resource_type" => String, @@ -656,13 +687,25 @@ module Full "messaging_pref" => Fog::Boolean } + COLLABORATION = { + "id" => String, + "resource_type" => String, + "url" => String, + "status" => String, + "role" => String, + "role_label" => String, + "email" => Fog::Nullable::String, + "user" => Fog::Brightbox::Nullable::User, + "account" => Brightbox::Compute::Formats::Nested::ACCOUNT, + "inviter" => Brightbox::Compute::Formats::Nested::USER + } + ZONE = { "id" => String, "resource_type" => String, "url" => String, "handle" => String } - end module Collection @@ -678,6 +721,7 @@ module Collection SERVER_TYPES = [Brightbox::Compute::Formats::Collected::SERVER_TYPE] USERS = [Brightbox::Compute::Formats::Collected::USER] ZONES = [Brightbox::Compute::Formats::Collected::ZONE] + COLLABORATIONS = [Brightbox::Compute::Formats::Collected::COLLABORATION] end end diff --git a/tests/brightbox/requests/compute/user_collaboration_tests.rb b/tests/brightbox/requests/compute/user_collaboration_tests.rb new file mode 100644 index 0000000000..79ee9f14cd --- /dev/null +++ b/tests/brightbox/requests/compute/user_collaboration_tests.rb @@ -0,0 +1,67 @@ +Shindo.tests('Fog::Compute[:brightbox] | user collaboration requests', ['brightbox']) do + + @service = Fog::Compute[:brightbox] + + tests("when accessing with user application") do + pending unless @service.authenticating_as_user? + tests("success") do + tests("#list_user_collaborations") do + pending if Fog.mocking? + result = @service.list_user_collaborations + + formats(Brightbox::Compute::Formats::Collection::COLLABORATIONS, false) { result } + end + end + + tests("failure") do + tests("get_user_collaboration('col-abcde')").raises(Excon::Errors::NotFound) do + pending if Fog.mocking? + + @service.get_user_collaboration('col-abcde') + end + + tests("accept_user_collaboration('col-abcde')").raises(Excon::Errors::NotFound) do + pending if Fog.mocking? + + @service.accept_user_collaboration('col-abcde') + end + + tests("reject_user_collaboration('col-abcde')").raises(Excon::Errors::NotFound) do + pending if Fog.mocking? + + @service.reject_user_collaboration('col-abcde') + end + end + end + + tests("when accessing with API client") do + pending if @service.authenticating_as_user? + tests("forbidden") do + + tests("#list_user_collaborations").raises(Excon::Errors::Forbidden) do + pending if Fog.mocking? + result = @service.list_user_collaborations + + formats(Brightbox::Compute::Formats::Collection::COLLABORATIONS, false) { result } + end + + tests("get_user_collaboration('col-abcde')").raises(Excon::Errors::Forbidden) do + pending if Fog.mocking? + + @service.get_user_collaboration('col-abcde') + end + + tests("accept_user_collaboration('col-abcde')").raises(Excon::Errors::Forbidden) do + pending if Fog.mocking? + + @service.accept_user_collaboration('col-abcde') + end + + tests("reject_user_collaboration('col-abcde')").raises(Excon::Errors::Forbidden) do + pending if Fog.mocking? + + @service.reject_user_collaboration('col-abcde') + end + end + end +end