1
0
Fork 0
mirror of https://github.com/fog/fog.git synced 2022-11-09 13:51:43 -05:00

[google|sql] Add support for Instances

- Add models, requests and tests for Instances
This commit is contained in:
Ferran Rodenas 2014-07-29 20:15:11 -07:00
parent 3a9a63bf14
commit d29a5a296e
18 changed files with 1446 additions and 0 deletions

View file

@ -0,0 +1,353 @@
require 'fog/core/model'
module Fog
module Google
class SQL
class Instance < Fog::Model
identity :instance
attribute :current_disk_size, :aliases => 'currentDiskSize'
attribute :database_version, :aliases => 'databaseVersion'
attribute :etag
attribute :ip_addresses, :aliases => 'ipAddresses'
attribute :kind
attribute :max_disk_size, :aliases => 'maxDiskSize'
attribute :project
attribute :region
attribute :server_ca_cert, :aliases => 'serverCaCert'
attribute :settings
attribute :state
# These attributes are not available in the representation of an 'Instance' returned by the Google SQL API.
attribute :activation_policy
attribute :autorized_gae_applications
attribute :backup_configuration
attribute :database_flags
attribute :ip_configuration_authorized_networks
attribute :ip_configuration_enabled
attribute :ip_configuration_require_ssl
attribute :location_preference_zone_follow_gae_application
attribute :location_preference_zone
attribute :pricing_plan
attribute :replication_type
attribute :settings_version
attribute :tier
MAINTENANCE_STATE = 'MAINTENANCE'
PENDING_CREATE_STATE = 'PENDING_CREATE'
RUNNABLE_STATE = 'RUNNABLE'
SUSPENDED_STATE = 'SUSPENDED'
UNKNOWN_STATE = 'UNKNOWN_STATE'
##
# Returns the activation policy for this instance
#
# @return [String] The activation policy for this instance
def activation_policy
self.settings['activationPolicy']
end
##
# Returns the AppEngine app ids that can access this instance
#
# @return [Array<String>] The AppEngine app ids that can access this instance
def autorized_gae_applications
self.settings['authorizedGaeApplications']
end
##
# Returns the daily backup configuration for the instance
#
# @return [Array<Hash>] The daily backup configuration for the instance
def backup_configuration
self.settings['backupConfiguration']
end
##
# Creates a Cloud SQL instance as a clone of the source instance
#
# @param [String] destination_name Name of the Cloud SQL instance to be created as a clone
# @param [Hash] options Method options
# @option options [String] :log_filename Name of the binary log file for a Cloud SQL instance
# @option options [Integer] :log_position Position (offset) within the binary log file
# @option options [Boolean] :async If the operation must be performed asynchronously (true by default)
# @return [Fog::Google::SQL::Operation] A Operation resource
def clone(destination_name, options = {})
requires :identity
data = service.clone_instance(self.identity, destination_name, options)
operation = Fog::Google::SQL::Operations.new(:service => service).get(self.instance, data.body['operation'])
unless options.fetch(:async, true)
operation.wait_for { ready? }
end
operation
end
##
# Creates a Cloud SQL instance
#
# @return [Fog::Google::SQL::Instance] Instance resource
def create
requires :identity
data = service.insert_instance(self.identity, self.attributes[:tier], self.attributes)
operation = Fog::Google::SQL::Operations.new(:service => service).get(self.instance, data.body['operation'])
operation.wait_for { !pending? }
reload
end
##
# Returns the database flags passed to the instance at startup
#
# @return [Array<Hash>] The database flags passed to the instance at startup
def database_flags
self.settings['databaseFlags']
end
##
# Deletes a Cloud SQL instance
#
# @param [Hash] options Method options
# @option options [Boolean] :async If the operation must be performed asynchronously (true by default)
# @return [Fog::Google::SQL::Operation] A Operation resource
def destroy(options = {})
requires :identity
data = service.delete_instance(self.identity)
operation = Fog::Google::SQL::Operations.new(:service => service).get(self.instance, data.body['operation'])
unless options.fetch(:async, true)
# DISABLED: A delete instance operation never reachs a 'DONE' state (bug?)
# operation.wait_for { ready? }
end
operation
end
##
# Exports data from a Cloud SQL instance to a Google Cloud Storage bucket as a MySQL dump file
#
# @param [String] uri The path to the file in Google Cloud Storage where the export will be stored,
# or where it was already stored
# @param [Hash] options Method options
# @option options [Array<String>] :databases Databases (for example, guestbook) from which the export is made.
# If unspecified, all databases are exported.
# @option options [Array<String>] :tables Tables to export, or that were exported, from the specified database.
# If you specify tables, specify one and only one database.
# @option options [Boolean] :async If the operation must be performed asynchronously (true by default)
# @return [Fog::Google::SQL::Operation] A Operation resource
def export(uri, options = {})
requires :identity
data = service.export_instance(self.identity, uri, options)
operation = Fog::Google::SQL::Operations.new(:service => service).get(self.instance, data.body['operation'])
unless options.fetch(:async, true)
operation.wait_for { ready? }
end
operation
end
##
# Imports data into a Cloud SQL instance from a MySQL dump file in Google Cloud Storage
#
# @param [Array<String>] uri A path to the MySQL dump file in Google Cloud Storage from which the import is
# made
# @param [Hash] options Method options
# @option options [String] :database The database (for example, guestbook) to which the import is made.
# If not set, it is assumed that the database is specified in the file to be imported.
# @option options [Boolean] :async If the operation must be performed asynchronously (true by default)
# @return [Fog::Google::SQL::Operation] A Operation resource
def import(uri, options = {})
requires :identity
data = service.import_instance(self.identity, uri, options)
operation = Fog::Google::SQL::Operations.new(:service => service).get(self.instance, data.body['operation'])
unless options.fetch(:async, true)
operation.wait_for { ready? }
end
operation
end
##
# Returns the list of external networks that are allowed to connect to the instance using the IP
#
# @return [Array<String>] The list of external networks that are allowed to connect to the instance using the IP
def ip_configuration_authorized_networks
self.settings.fetch('ipConfiguration', {})['authorizedNetworks']
end
##
# Returns whether the instance should be assigned an IP address or not
#
# @return [Boolean] Whether the instance should be assigned an IP address or not
def ip_configuration_enabled
self.settings.fetch('ipConfiguration', {})['enabled']
end
##
# Returns whether the mysqld should default to 'REQUIRE X509' for users connecting over IP
#
# @return [Boolean] Whether the mysqld should default to 'REQUIRE X509' for users connecting over IP
def ip_configuration_require_ssl
self.settings.fetch('ipConfiguration', {})['requireSsl']
end
##
# Returns the AppEngine application to follow
#
# @return [String] The AppEngine application to follow
def location_preference_zone_follow_gae_application
self.settings.fetch('locationPreference', {})['followGaeApplication']
end
##
# Returns the preferred Compute Engine zone
#
# @return [String] The preferred Compute Engine zone
def location_preference_zone
self.settings.fetch('locationPreference', {})['zone']
end
##
# Returns the pricing plan for this instance
#
# @return [String] The pricing plan for this instance
def pricing_plan
self.settings['pricingPlan']
end
##
# Checks if the instance is running
#
# @return [Boolean] True if the instance is running; False otherwise
def ready?
self.state == RUNNABLE_STATE
end
##
# Returns the type of replication this instance uses
#
# @return [String] The type of replication this instance uses
def replication_type
self.settings['replicationType']
end
##
# Deletes all client certificates and generates a new server SSL certificate for the instance
#
# @param [Hash] options Method options
# @option options [Boolean] :async If the operation must be performed asynchronously (true by default)
# @return [Fog::Google::SQL::Operation] A Operation resource
def reset_ssl_config(options = {})
requires :identity
data = service.reset_instance_ssl_config(self.identity)
operation = Fog::Google::SQL::Operations.new(:service => service).get(self.instance, data.body['operation'])
unless options.fetch(:async, true)
operation.wait_for { ready? }
end
operation
end
##
# Restarts a Cloud SQL instance
#
# @param [Hash] options Method options
# @option options [Boolean] :async If the operation must be performed asynchronously (true by default)
# @return [Fog::Google::SQL::Operation] A Operation resource
def restart(options = {})
requires :identity
data = service.restart_instance(self.identity)
operation = Fog::Google::SQL::Operations.new(:service => service).get(self.instance, data.body['operation'])
unless options.fetch(:async, true)
operation.wait_for { ready? }
end
operation
end
##
# Restores a backup of a Cloud SQL instance
#
# @param [String] backup_configuration The identifier of the backup configuration
# @param [String] due_time The time when this run is due to start in RFC 3339 format
# @param [Hash] options Method options
# @option options [Boolean] :async If the operation must be performed asynchronously (true by default)
# @return [Fog::Google::SQL::Operation] A Operation resource
def restore_backup(backup_configuration, due_time, options = {})
requires :identity
data = service.restore_instance_backup(self.identity, backup_configuration, due_time)
operation = Fog::Google::SQL::Operations.new(:service => service).get(self.instance, data.body['operation'])
unless options.fetch(:async, true)
operation.wait_for { ready? }
end
operation
end
##
# Saves a Cloud SQL instance
#
# @return [Fog::Google::SQL::Instance] Instance resource
def save
self.etag ? update : create
end
##
# Sets the password for the root user
#
# @param [String] password The password for the root user
# @param [Hash] options Method options
# @option options [Boolean] :async If the operation must be performed asynchronously (true by default)
# @return [Fog::Google::SQL::Operation] A Operation resource
def set_root_password(password, options = {})
requires :identity
data = service.set_instance_root_password(self.identity, password)
operation = Fog::Google::SQL::Operations.new(:service => service).get(self.instance, data.body['operation'])
unless options.fetch(:async, true)
operation.wait_for { ready? }
end
operation
end
##
# Returns the version of instance settings
#
# @return [String] The version of instance settings
def settings_version
self.settings['settingsVersion']
end
##
# Lists all of the current SSL certificates for the instance
#
# @return [Array<Fog::Google::SQL::SslCert>] List of SSL certificate resources
def ssl_certs
requires :identity
service.ssl_certs.all(self.identity)
end
##
# Returns the tier of service for this instance
#
# @return [String] The tier of service for this instance
def tier
self.settings['tier']
end
##
# Updates settings of a Cloud SQL instance
#
# @return [Fog::Google::SQL::Instance] Instance resource
def update
requires :identity
data = service.update_instance(self.identity, self.settings_version, self.tier, self.attributes)
operation = Fog::Google::SQL::Operations.new(:service => service).get(self.instance, data.body['operation'])
operation.wait_for { !pending? }
reload
end
end
end
end
end

View file

@ -0,0 +1,39 @@
require 'fog/core/collection'
require 'fog/google/models/sql/instance'
module Fog
module Google
class SQL
class Instances < Fog::Collection
model Fog::Google::SQL::Instance
##
# Lists all instance
#
# @return [Array<Fog::Google::SQL::Instance>] List of instance resources
def all
data = service.list_instances.body['items'] || []
load(data)
end
##
# Retrieves an instance
#
# @param [String] instance_id Instance ID
# @return [Fog::Google::SQL::Instance] Instance resource
def get(instance_id)
if instance = service.get_instance(instance_id).body
new(instance)
end
rescue Fog::Errors::NotFound
nil
rescue Fog::Errors::Error => e
# Google SQL returns a 403 if we try to access a non-existing resource
# The default behaviour in Fog is to return a nil
return nil if e.message == 'The client is not authorized to make this request.'
raise e
end
end
end
end
end

View file

@ -0,0 +1,84 @@
module Fog
module Google
class SQL
##
# Creates a Cloud SQL instance as a clone of the source instance
#
# @see https://developers.google.com/cloud-sql/docs/admin-api/v1beta3/instances/clone
class Real
def clone_instance(instance_id, destination_name, options = {})
# The @sql.instances.clone method is overrided by the standard Ruby clone method
# so we cannot call it because it will just clone the @sql.instances instance.
# Instead we need to find the proper method trough the discovered_methods.
api_method = @sql.instances.discovered_methods.find { |x| x.id == 'sql.instances.clone' }
parameters = {
'project' => @project,
}
body = {
'cloneContext' => {
'kind' => 'sql#cloneContext',
'sourceInstanceName' => instance_id,
'destinationInstanceName' => destination_name,
}
}
if options[:log_position]
body['cloneContext']['binLogCoordinates'] = {
'kind' => 'sql#binLogCoordinates',
'binLogFileName' => options[:log_filename],
'binLogPosition' => options[:log_position],
}
end
request(api_method, parameters, body)
end
end
class Mock
def clone_instance(instance_id, destination_name, options = {})
self.data[:instances][destination_name] = self.data[:instances][instance_id]
self.data[:instances][destination_name]['instance'] = destination_name
self.data[:ssl_certs][destination_name] = {}
self.data[:backup_runs][destination_name] = {}
operation = self.random_operation
self.data[:operations][destination_name] ||= {}
self.data[:operations][destination_name][operation] = {
'kind' => 'sql#instanceOperation',
'instance' => destination_name,
'operation' => operation,
'operationType' => 'CREATE',
'state' => Fog::Google::SQL::Operation::DONE_STATE,
'userEmailAddress' => 'google_client_email@developer.gserviceaccount.com',
'enqueuedTime' => Time.now.iso8601,
'startTime' => Time.now.iso8601,
'endTime' => Time.now.iso8601,
}
operation = self.random_operation
self.data[:operations][instance_id] ||= {}
self.data[:operations][instance_id][operation] = {
'kind' => 'sql#instanceOperation',
'instance' => instance_id,
'operation' => operation,
'operationType' => 'CLONE',
'state' => Fog::Google::SQL::Operation::DONE_STATE,
'userEmailAddress' => 'google_client_email@developer.gserviceaccount.com',
'enqueuedTime' => Time.now.iso8601,
'startTime' => Time.now.iso8601,
'endTime' => Time.now.iso8601,
}
body = {
'kind' => 'sql#instancesClone',
'operation' => operation,
}
build_excon_response(body)
end
end
end
end
end

View file

@ -0,0 +1,67 @@
module Fog
module Google
class SQL
##
# Deletes a Cloud SQL instance
#
# @see https://developers.google.com/cloud-sql/docs/admin-api/v1beta3/instances/delete
class Real
def delete_instance(instance_id)
api_method = @sql.instances.delete
parameters = {
'project' => @project,
'instance' => instance_id,
}
request(api_method, parameters)
end
end
class Mock
def delete_instance(instance_id)
if self.data[:instances].has_key?(instance_id)
self.data[:instances].delete(instance_id)
self.data[:ssl_certs].delete(instance_id)
self.data[:backup_runs].delete(instance_id)
operation = self.random_operation
self.data[:operations][instance_id] ||= {}
self.data[:operations][instance_id][operation] = {
'kind' => 'sql#instanceOperation',
'instance' => instance_id,
'operation' => operation,
'operationType' => 'DELETE',
'state' => Fog::Google::SQL::Operation::PENDING_STATE,
'userEmailAddress' => 'google_client_email@developer.gserviceaccount.com',
'enqueuedTime' => Time.now.iso8601,
}
body = {
'kind' => 'sql#instancesDelete',
'operation' => operation,
}
status = 200
else
body = {
'error' => {
'errors' => [
{
'domain' => 'global',
'reason' => 'notAuthorized',
'message' => 'The client is not authorized to make this request.',
}
],
'code' => 403,
'message' => 'The client is not authorized to make this request.',
}
}
status = 403
end
build_excon_response(body, status)
end
end
end
end
end

View file

@ -0,0 +1,56 @@
module Fog
module Google
class SQL
##
# Exports data from a Cloud SQL instance to a Google Cloud Storage bucket as a MySQL dump file
#
# @see https://developers.google.com/cloud-sql/docs/admin-api/v1beta3/instances/export
class Real
def export_instance(instance_id, uri, options = {})
api_method = @sql.instances.export
parameters = {
'project' => @project,
'instance' => instance_id,
}
body = {
'exportContext' => {
'kind' => 'sql#exportContext',
'uri' => uri,
'database' => Array(options[:databases]),
'table' => Array(options[:tables]),
}
}
request(api_method, parameters, body)
end
end
class Mock
def export_instance(instance_id, uri, options = {})
operation = self.random_operation
self.data[:operations][instance_id] ||= {}
self.data[:operations][instance_id][operation] = {
'kind' => 'sql#instanceOperation',
'instance' => instance_id,
'operation' => operation,
'operationType' => 'EXPORT',
'state' => Fog::Google::SQL::Operation::DONE_STATE,
'userEmailAddress' => 'google_client_email@developer.gserviceaccount.com',
'enqueuedTime' => Time.now.iso8601,
'startTime' => Time.now.iso8601,
'endTime' => Time.now.iso8601,
}
body = {
'kind' => 'sql#instancesExport',
'operation' => operation,
}
build_excon_response(body)
end
end
end
end
end

View file

@ -0,0 +1,48 @@
module Fog
module Google
class SQL
##
# Retrieves a resource containing information about a Cloud SQL instance
#
# @see https://developers.google.com/cloud-sql/docs/admin-api/v1beta3/instances/get
class Real
def get_instance(instance_id)
api_method = @sql.instances.get
parameters = {
'project' => @project,
'instance' => instance_id,
}
request(api_method, parameters)
end
end
class Mock
def get_instance(instance_id)
if self.data[:instances].has_key?(instance_id)
body = self.data[:instances][instance_id]
status = 200
else
body = {
'error' => {
'errors' => [
{
'domain' => 'global',
'reason' => 'notAuthorized',
'message' => 'The client is not authorized to make this request.',
}
],
'code' => 403,
'message' => 'The client is not authorized to make this request.',
}
}
status = 403
end
build_excon_response(body, status)
end
end
end
end
end

View file

@ -0,0 +1,55 @@
module Fog
module Google
class SQL
##
# Imports data into a Cloud SQL instance from a MySQL dump file in Google Cloud Storage
#
# @see https://developers.google.com/cloud-sql/docs/admin-api/v1beta3/instances/import
class Real
def import_instance(instance_id, uri, options = {})
api_method = @sql.instances.import
parameters = {
'project' => @project,
'instance' => instance_id,
}
body = {
'importContext' => {
'kind' => 'sql#importContext',
'uri' => Array(uri),
'database' => options[:database],
}
}
request(api_method, parameters, body)
end
end
class Mock
def import_instance(instance_id, uri, options = {})
operation = self.random_operation
self.data[:operations][instance_id] ||= {}
self.data[:operations][instance_id][operation] = {
'kind' => 'sql#instanceOperation',
'instance' => instance_id,
'operation' => operation,
'operationType' => 'IMPORT',
'state' => Fog::Google::SQL::Operation::DONE_STATE,
'userEmailAddress' => 'google_client_email@developer.gserviceaccount.com',
'enqueuedTime' => Time.now.iso8601,
'startTime' => Time.now.iso8601,
'endTime' => Time.now.iso8601,
}
body = {
'kind' => 'sql#instancesImport',
'operation' => operation,
}
build_excon_response(body)
end
end
end
end
end

View file

@ -0,0 +1,165 @@
module Fog
module Google
class SQL
##
# Creates a new Cloud SQL instance
#
# @see https://developers.google.com/cloud-sql/docs/admin-api/v1beta3/instances/insert
class Real
def insert_instance(name, tier, options = {})
api_method = @sql.instances.insert
parameters = {
'project' => @project,
}
body = {
'project' => @project,
'instance' => name,
'settings' => {
'tier' => tier,
}
}
if options[:region]
body['region'] = options[:region]
end
if options[:activation_policy]
body['settings']['activationPolicy'] = options[:activation_policy]
end
if options[:autorized_gae_applications]
body['settings']['authorizedGaeApplications'] = Array(options[:autorized_gae_applications])
end
if options[:backup_configuration]
body['settings']['backupConfiguration'] = options[:backup_configuration]
end
if options[:ip_configuration_authorized_networks]
body['settings']['ipConfiguration'] ||= {}
body['settings']['ipConfiguration']['authorizedNetworks'] = Array(options[:ip_configuration_authorized_networks])
end
if options[:ip_configuration_enabled]
body['settings']['ipConfiguration'] ||= {}
body['settings']['ipConfiguration']['enabled'] = options[:ip_configuration_enabled]
end
if options[:ip_configuration_require_ssl]
body['settings']['ipConfiguration'] ||= {}
body['settings']['ipConfiguration']['requireSsl'] = options[:ip_configuration_require_ssl]
end
if options[:location_preference_zone_follow_gae_application]
body['settings']['locationPreference'] ||= {}
body['settings']['locationPreference']['followGaeApplication'] = options[:location_preference_zone_follow_gae_application]
end
if options[:location_preference_zone]
body['settings']['locationPreference'] ||= {}
body['settings']['locationPreference']['zone'] = options[:location_preference_zone]
end
if options[:pricing_plan]
body['settings']['pricingPlan'] = options[:pricing_plan]
end
if options[:replication_type]
body['settings']['replicationType'] = options[:replication_type]
end
request(api_method, parameters, body)
end
end
class Mock
def insert_instance(name, tier, options = {})
data = {
'kind' => 'sql#instance',
'instance' => name,
'etag' => Fog::Mock.random_base64(32),
'project' => @project,
'state' => Fog::Google::SQL::Instance::RUNNABLE_STATE ,
'databaseVersion' => 'MYSQL_5_5',
'region' => options[:region] || 'us-central',
'currentDiskSize' => '86245269',
'maxDiskSize' => '268435456000',
'settings' => {
'kind' => 'sql#settings',
'settingsVersion' => '1',
'tier' => tier,
'backupConfiguration' => [
{
'kind' => 'sql#backupConfiguration',
'startTime' => '04:00',
'enabled' => false,
'id' => Fog::Mock.random_hex(32),
'binaryLogEnabled' => false
}
],
'pricingPlan' => options[:pricing_plan] || 'PER_USE',
'replicationType' => options[:replication_type] || 'SYNCHRONOUS',
'activationPolicy' => options[:activation_policy] || 'ON_DEMAND',
'ipConfiguration' => {
'enabled' => false,
},
'locationPreference' => {
'kind' => 'sql#locationPreference',
}
},
'serverCaCert' => {
'kind' => 'sql#sslCert',
'instance' => name,
'sha1Fingerprint' => Fog::Mock.random_hex(40),
'commonName' => 'C=US,O=Google\\, Inc,CN=Google Cloud SQL Server CA',
'certSerialNumber' => '0',
'cert' => "-----BEGIN CERTIFICATE-----\nMIIDITCCAgmgAwIBAgIBADANBgkqhkiG9w0BAQUFADBIMSMwIQYDVQQDExpHb29n\nbGUgQ2xvdWQgU1FMIFNlcnZlciBDQTEUMBIGA1UEChMLR29vZ2xlLCBJbmMxCzAJ\nBgNVBAYTAlVTMB4XDTE0MDYwNDA1MjkxMVoXDTI0MDYwMTA1MjkxMVowSDEjMCEG\nA1UEAxMaR29vZ2xlIENsb3VkIFNRTCBTZXJ2ZXIgQ0ExFDASBgNVBAoTC0dvb2ds\nZSwgSW5jMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\nggEBALlRjq3zccH5ed6NMfCFcTYd9XxYXyvLurxxjDIA6A7/ymVM9qdQC0uckf7C\nsi4uMi2yfK+PHZ0jXC+g0uPx5RTm+nbKl4I++VOh2g6oZHeNdFt4rVJpr+jzGUMf\nr67SymUr70TQOTEVpx2Ud3rBB2szulxWUSXEy2AGA3uNUGe/IgENh7p56s00Sr97\nTRP1S5/JVMalncgNVLH2nNqBQJZTx9t9qvGatoUfmHUU0+M//J5sXLbgdzeEeeot\nHJUyoXjA2sRkH1+F/d6PpFrcr1I8dVmCBEbTAnm7HpKh5Mx2nRYi+t/y9D2Mblwx\n9dBRfr3WIJ1JDxzt3L8CtBGZbvUCAwEAAaMWMBQwEgYDVR0TAQH/BAgwBgEB/wIB\nADANBgkqhkiG9w0BAQUFAAOCAQEAmHuBecPc265sbd26B1HXUAD6FHdzoZLrAZVW\n+1eIK4E669P4y6LkLuoCkLd64/YwA4K2FioksqgHOahbYWJJYPymy4ae+IPXzXcY\nPv3gmBsKk++sHb64D9Cj/k5n8BEiVmmrsUCUiL75nJAzK+El3hvKKWWl76XX/qHP\nk8ZAxIrn8bCiVOaj6NR4+p1OmcZSPNWxz7j/EwQxoABRxgPgt+B/YRseevww7an2\n/rGs0sk7RE0QDjLfZblYGh+xVPBBLuLmf4L5JNJkFEoeGSWrxTzvXnS+2LZeHdM/\nJ9nsiKu5JKPhMUS0vOcTymOkh8tJ6Np8gwg6ca4g6dT3llE6uQ==\n-----END CERTIFICATE-----",
'createTime' => Time.now.iso8601,
'expirationTime' => Time.now.iso8601,
}
}
if options[:autorized_gae_applications]
data['settings']['authorizedGaeApplications'] = Array(options[:autorized_gae_applications])
end
if options[:backup_configuration]
data['settings']['backupConfiguration'] = options[:backup_configuration]
end
if options[:ip_configuration_authorized_networks]
data['settings']['ipConfiguration']['authorizedNetworks'] = Array(options[:ip_configuration_authorized_networks])
end
if options[:ip_configuration_enabled]
data['settings']['ipConfiguration']['enabled'] = options[:ip_configuration_enabled]
end
if options[:ip_configuration_require_ssl]
data['settings']['ipConfiguration']['requireSsl'] = options[:ip_configuration_require_ssl]
end
if options[:location_preference_zone_follow_gae_application]
data['settings']['locationPreference']['followGaeApplication'] = options[:location_preference_zone_follow_gae_application]
end
if options[:location_preference_zone]
data['settings']['locationPreference']['zone'] = options[:location_preference_zone]
end
self.data[:instances][name] = data
self.data[:ssl_certs][name] = {}
self.data[:backup_runs][name] = {}
operation = self.random_operation
self.data[:operations][name] ||= {}
self.data[:operations][name][operation] = {
'kind' => 'sql#instanceOperation',
'instance' => name,
'operation' => operation,
'operationType' => 'CREATE',
'state' => Fog::Google::SQL::Operation::DONE_STATE,
'userEmailAddress' => 'google_client_email@developer.gserviceaccount.com',
'enqueuedTime' => Time.now.iso8601,
'startTime' => Time.now.iso8601,
'endTime' => Time.now.iso8601,
}
body = {
'kind' => 'sql#instancesInsert',
'operation' => operation,
}
status = 200
build_excon_response(body, status)
end
end
end
end
end

View file

@ -0,0 +1,32 @@
module Fog
module Google
class SQL
##
# Lists instances under a given project in the alphabetical order of the instance name
#
# @see https://developers.google.com/cloud-sql/docs/admin-api/v1beta3/instances/list
class Real
def list_instances
api_method = @sql.instances.list
parameters = {
'project' => @project,
}
request(api_method, parameters)
end
end
class Mock
def list_instances
body = {
'kind' => 'sql#instancesList',
'items' => self.data[:instances].values,
}
build_excon_response(body)
end
end
end
end
end

View file

@ -0,0 +1,49 @@
module Fog
module Google
class SQL
##
# Deletes all client certificates and generates a new server SSL certificate for the instance.
# The changes will not take effect until the instance is restarted. Existing instances without
# a server certificate will need to call this once to set a server certificate
#
# @see https://developers.google.com/cloud-sql/docs/admin-api/v1beta3/instances/resetSslConfig
class Real
def reset_instance_ssl_config(instance_id)
api_method = @sql.instances.reset_ssl_config
parameters = {
'project' => @project,
'instance' => instance_id,
}
request(api_method, parameters)
end
end
class Mock
def reset_instance_ssl_config(instance_id)
operation = self.random_operation
self.data[:operations][instance_id] ||= {}
self.data[:operations][instance_id][operation] = {
'kind' => 'sql#instanceOperation',
'instance' => instance_id,
'operation' => operation,
'operationType' => 'UPDATE',
'state' => Fog::Google::SQL::Operation::DONE_STATE,
'userEmailAddress' => 'google_client_email@developer.gserviceaccount.com',
'enqueuedTime' => Time.now.iso8601,
'startTime' => Time.now.iso8601,
'endTime' => Time.now.iso8601,
}
body = {
'kind' => 'sql#instancesResetSslConfig',
'operation' => operation,
}
build_excon_response(body)
end
end
end
end
end

View file

@ -0,0 +1,47 @@
module Fog
module Google
class SQL
##
# Restarts a Cloud SQL instance
#
# @see https://developers.google.com/cloud-sql/docs/admin-api/v1beta3/instances/restart
class Real
def restart_instance(instance_id)
api_method = @sql.instances.restart
parameters = {
'project' => @project,
'instance' => instance_id,
}
request(api_method, parameters)
end
end
class Mock
def restart_instance(instance_id)
operation = self.random_operation
self.data[:operations][instance_id] ||= {}
self.data[:operations][instance_id][operation] = {
'kind' => 'sql#instanceOperation',
'instance' => instance_id,
'operation' => operation,
'operationType' => 'RESTART',
'state' => Fog::Google::SQL::Operation::DONE_STATE,
'userEmailAddress' => 'google_client_email@developer.gserviceaccount.com',
'enqueuedTime' => Time.now.iso8601,
'startTime' => Time.now.iso8601,
'endTime' => Time.now.iso8601,
}
body = {
'kind' => 'sql#instancesRestart',
'operation' => operation,
}
build_excon_response(body)
end
end
end
end
end

View file

@ -0,0 +1,30 @@
module Fog
module Google
class SQL
##
# Restores a backup of a Cloud SQL instance
#
# @see https://developers.google.com/cloud-sql/docs/admin-api/v1beta3/instances/restoreBackup
class Real
def restore_instance_backup(identity, backup_configuration, due_time)
api_method = @sql.instances.reset_ssl_config
parameters = {
'project' => @project,
'instance' => identity,
'backupConfiguration' => backup_configuration,
'dueTime' => due_time,
}
request(api_method, parameters)
end
end
class Mock
def restore_instance_backup(identity, backup_configuration, due_time)
Fog::Mock.not_implemented
end
end
end
end
end

View file

@ -0,0 +1,54 @@
module Fog
module Google
class SQL
##
# Sets the password for the root user
#
# @see https://developers.google.com/cloud-sql/docs/admin-api/v1beta3/instances/setRootPassword
class Real
def set_instance_root_password(instance_id, password)
api_method = @sql.instances.set_root_password
parameters = {
'project' => @project,
'instance' => instance_id,
}
body = {
'setRootPasswordContext' => {
'kind' => 'sql#setRootUserContext',
'password' => password,
}
}
request(api_method, parameters, body)
end
end
class Mock
def set_instance_root_password(instance_id, password)
operation = self.random_operation
self.data[:operations][instance_id] ||= {}
self.data[:operations][instance_id][operation] = {
'kind' => 'sql#instanceOperation',
'instance' => instance_id,
'operation' => operation,
'operationType' => 'INJECT_USER',
'state' => Fog::Google::SQL::Operation::DONE_STATE,
'userEmailAddress' => 'google_client_email@developer.gserviceaccount.com',
'enqueuedTime' => Time.now.iso8601,
'startTime' => Time.now.iso8601,
'endTime' => Time.now.iso8601,
}
body = {
'kind' => 'sql#instancesSetRootPassword',
'operation' => operation,
}
build_excon_response(body)
end
end
end
end
end

View file

@ -0,0 +1,132 @@
module Fog
module Google
class SQL
##
# Updates settings of a Cloud SQL instance
#
# @see https://developers.google.com/cloud-sql/docs/admin-api/v1beta3/instances/update
class Real
def update_instance(instance_id, settings_version, tier, options = {})
api_method = @sql.instances.update
parameters = {
'project' => @project,
'instance' => instance_id,
}
body = {
'project' => @project,
'instance' => instance_id,
'settings' => {
'settingsVersion' => settings_version,
'tier' => tier,
}
}
if options[:activation_policy]
body['settings']['activationPolicy'] = options[:activation_policy]
end
if options[:autorized_gae_applications]
body['settings']['authorizedGaeApplications'] = Array(options[:autorized_gae_applications])
end
if options[:backup_configuration]
body['settings']['backupConfiguration'] = options[:backup_configuration]
end
if options[:ip_configuration_authorized_networks]
body['settings']['ipConfiguration'] ||= {}
body['settings']['ipConfiguration']['authorizedNetworks'] = Array(options[:ip_configuration_authorized_networks])
end
if options[:ip_configuration_enabled]
body['settings']['ipConfiguration'] ||= {}
body['settings']['ipConfiguration']['enabled'] = options[:ip_configuration_enabled]
end
if options[:ip_configuration_require_ssl]
body['settings']['ipConfiguration'] ||= {}
body['settings']['ipConfiguration']['requireSsl'] = options[:ip_configuration_require_ssl]
end
if options[:location_preference_zone_follow_gae_application]
body['settings']['locationPreference'] ||= {}
body['settings']['locationPreference']['followGaeApplication'] = options[:location_preference_zone_follow_gae_application]
end
if options[:location_preference_zone]
body['settings']['locationPreference'] ||= {}
body['settings']['locationPreference']['zone'] = options[:location_preference_zone]
end
if options[:pricing_plan]
body['settings']['pricingPlan'] = options[:pricing_plan]
end
if options[:replication_type]
body['settings']['replicationType'] = options[:replication_type]
end
request(api_method, parameters, body)
end
end
class Mock
def update_instance(instance_id, settings_version, tier, options = {})
data = self.data[:instances][instance_id]
data['tier'] = tier
if options[:activation_policy]
data['settings']['activationPolicy'] = options[:activation_policy]
end
if options[:autorized_gae_applications]
data['settings']['authorizedGaeApplications'] = Array(options[:autorized_gae_applications])
end
if options[:backup_configuration]
data['settings']['backupConfiguration'] = options[:backup_configuration]
end
if options[:ip_configuration_authorized_networks]
data['settings']['ipConfiguration'] ||= {}
data['settings']['ipConfiguration']['authorizedNetworks'] = Array(options[:ip_configuration_authorized_networks])
end
if options[:ip_configuration_enabled]
data['settings']['ipConfiguration'] ||= {}
data['settings']['ipConfiguration']['enabled'] = options[:ip_configuration_enabled]
end
if options[:ip_configuration_require_ssl]
data['settings']['ipConfiguration'] ||= {}
data['settings']['ipConfiguration']['requireSsl'] = options[:ip_configuration_require_ssl]
end
if options[:location_preference_zone_follow_gae_application]
data['settings']['locationPreference'] ||= {}
data['settings']['locationPreference']['followGaeApplication'] = options[:location_preference_zone_follow_gae_application]
end
if options[:location_preference_zone]
data['settings']['locationPreference'] ||= {}
data['settings']['locationPreference']['zone'] = options[:location_preference_zone]
end
if options[:pricing_plan]
data['settings']['pricingPlan'] = options[:pricing_plan]
end
if options[:replication_type]
data['settings']['replicationType'] = options[:replication_type]
end
self.data[:instances][instance_id] = data
operation = self.random_operation
self.data[:operations][instance_id] ||= {}
self.data[:operations][instance_id][operation] = {
'kind' => 'sql#instanceOperation',
'instance' => instance_id,
'operation' => operation,
'operationType' => 'UPDATE',
'state' => Fog::Google::SQL::Operation::DONE_STATE,
'userEmailAddress' => 'google_client_email@developer.gserviceaccount.com',
'enqueuedTime' => Time.now.iso8601,
'startTime' => Time.now.iso8601,
'endTime' => Time.now.iso8601,
}
body = {
'kind' => 'sql#instancesUpdate',
'operation' => operation,
}
status = 200
build_excon_response(body, status)
end
end
end
end
end

View file

@ -20,6 +20,10 @@ module Fog
model :flag
collection :flags
# Instance
model :instance
collection :instances
# Operation
model :operation
collection :operations
@ -35,6 +39,20 @@ module Fog
# Flag
request :list_flags
# Instance
request :clone_instance
request :delete_instance
request :export_instance
request :get_instance
request :import_instance
request :insert_instance
request :list_instances
request :reset_instance_ssl_config
request :restart_instance
request :restore_instance_backup
request :set_instance_root_password
request :update_instance
# Operation
request :get_operation
request :list_operations

View file

@ -0,0 +1,56 @@
Shindo.tests('Fog::Google[:sql] | instance model', ['google']) do
@instances = Fog::Google[:sql].instances
tests('success') do
tests('#create').succeeds do
@instance = @instances.create(:instance => Fog::Mock.random_letters(16), :tier => 'D1')
@instance.wait_for { ready? }
end
tests('#update').succeeds do
@instance.activation_policy = 'ALWAYS'
@instance.update
@instance.wait_for { ready? }
end
tests('#clone').succeeds do
pending unless Fog.mocking? # Binary log must be activated
instance_cloned_id = Fog::Mock.random_letters(16)
@instance.clone(instance_cloned_id, :async => false)
@instances.get(instance_cloned_id).destroy
end
tests('#export').succeeds do
pending unless Fog.mocking? # We don't have access to a Google Cloud Storage bucket
@instance.export("gs://#{Fog::Mock.random_letters_and_numbers(16)}/mysql-export", :async => false)
end
tests('#import').succeeds do
pending unless Fog.mocking? # We don't have access to a Google Cloud Storage bucket
@instance.import("gs://#{Fog::Mock.random_letters_and_numbers(16)}/mysql-export", :async => false)
end
tests('#ready?').succeeds do
@instance.ready? == true
end
tests('#reset_ssl_config').succeeds do
@instance.reset_ssl_config(:async => false)
end
tests('#restart').succeeds do
@instance.restart(:async => false)
end
tests('#set_root_password').succeeds do
@instance.set_root_password(Fog::Mock.random_letters_and_numbers(8), :async => false)
end
tests('#destroy').succeeds do
@instance.destroy
end
end
end

View file

@ -0,0 +1,32 @@
Shindo.tests('Fog::Google[:sql] | instances model', ['google']) do
@instance = Fog::Google[:sql].instances.create(:instance => Fog::Mock.random_letters(16), :tier => 'D1')
@instance.wait_for { ready? }
@instances = Fog::Google[:sql].instances
tests('success') do
tests('#all').succeeds do
@instances.all
end
tests('#get').succeeds do
@instances.get(@instance.instance)
end
end
@instance.destroy(:async => false)
tests('failure') do
tests('#all').returns([]) do
@instances.all
end
tests('#get').returns(nil) do
@instances.get(Fog::Mock.random_letters_and_numbers(16))
end
end
end

View file

@ -0,0 +1,129 @@
Shindo.tests('Fog::Google[:sql] | instance requests', ['google']) do
@sql = Fog::Google[:sql]
@instance_id = Fog::Mock.random_letters(16)
@insert_instance_format = {
'kind' => String,
'operation' => String,
}
@get_instance_format = {
'instance' => String,
'currentDiskSize' => Fog::Nullable::String,
'databaseVersion' => String,
'etag' => String,
'ipAddresses' => Fog::Nullable::String,
'kind' => String,
'maxDiskSize' => String,
'project' => String,
'region' => String,
'serverCaCert' => Hash,
'settings' => Hash,
'state' => String,
}
@list_instances_format = {
'kind' => String,
'items' => [@get_instance_format],
}
@clone_instance_format = {
'kind' => String,
'operation' => String,
}
@export_instance_format = {
'kind' => String,
'operation' => String,
}
@import_instance_format = {
'kind' => String,
'operation' => String,
}
@reset_instance_ssl_config_format = {
'kind' => String,
'operation' => String,
}
@restart_instance_format = {
'kind' => String,
'operation' => String,
}
@set_instance_root_password_format = {
'kind' => String,
'operation' => String,
}
@update_instance_format = {
'kind' => String,
'operation' => String,
}
@delete_instance_format = {
'kind' => String,
'operation' => String,
}
tests('success') do
tests('#insert_instance').formats(@insert_instance_format) do
result = @sql.insert_instance(@instance_id, 'D1').body
@sql.instances.get(@instance_id).wait_for { ready? }
result
end
tests('#list_instances').formats(@list_instances_format) do
@sql.list_instances.body
end
tests('#get_instance').formats(@get_instance_format) do
@sql.get_instance(@instance_id).body
end
tests('#update_instance').formats(@update_instance_format) do
instance = @sql.instances.get(@instance_id)
@sql.update_instance(instance.instance, instance.settings_version, instance.tier, instance.attributes).body
end
tests('#clone_instance').formats(@clone_instance_format) do
pending unless Fog.mocking? # Binary log must be activated
instance_cloned_id = Fog::Mock.random_letters(16)
clone_instance_format = @sql.clone_instance(@instance_id, instance_cloned_id).body
@sql.delete_instance(instance_cloned_id)
clone_instance_format
end
tests('#export_instance').formats(@export_instance_format) do
pending unless Fog.mocking? # We don't have access to a Google Cloud Storage bucket
@sql.export_instance(@instance_id, "gs://#{Fog::Mock.random_letters_and_numbers(16)}/mysql-export").body
end
tests('#import_instance').formats(@import_instance_format) do
pending unless Fog.mocking? # We don't have access to a Google Cloud Storage bucket
@sql.import_instance(@instance_id, "gs://#{Fog::Mock.random_letters_and_numbers(16)}/mysql-export").body
end
tests('#reset_instance_ssl_config').formats(@reset_instance_ssl_config_format) do
@sql.reset_instance_ssl_config(@instance_id).body
end
tests('#set_instance_root_password').formats(@set_instance_root_password_format) do
@sql.set_instance_root_password(@instance_id, Fog::Mock.random_letters_and_numbers(8)).body
end
tests('#restart_instance').formats(@restart_instance_format) do
result = @sql.restart_instance(@instance_id).body
@sql.operations.get(@instance_id, result['operation']).wait_for { ready? }
result
end
tests('#delete_instance').formats(@delete_instance_format) do
@sql.delete_instance(@instance_id).body
end
end
end