All Files (63.39% covered at 10.03 hits/line)
47 files in total.
2931 relevant lines.
1858 lines covered and
1073 lines missed
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
# Add libraries/ to library search path
- 1
$LOAD_PATH.unshift ::File.expand_path(::File.dirname(__FILE__))
# Copyright 2017 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
- 1
require 'google/string_utils'
- 1
module Google
# Helper class to process and mutate hashes.
- 1
class HashUtils
# Converts all keys to symbols
- 1
def self.camelize_keys(source)
result = source.clone
# rubocop:disable Performance/HashEachMethods
result.keys.each do |k|
result[Google::StringUtils.camelize(k.to_s)] = result.delete(k)
end
# rubocop:enable Performance/HashEachMethods
result
end
- 1
def self.symbolize_keys(source)
result = source.clone
# rubocop:disable Performance/HashEachMethods
result.keys.each do |k|
result[Google::StringUtils.symbolize(k)] = result.delete(k)
end
# rubocop:enable Performance/HashEachMethods
result
end
# Allows fetching objects within a tree path.
- 1
def self.navigate(source, path, default = nil)
- 6
key = path.take(1)[0]
- 6
path = path.drop(1)
- 6
return default unless source.key?(key)
- 1
result = source.fetch(key)
- 1
return HashUtils.navigate(result, path, default) unless path.empty?
- 1
return result if path.empty?
end
# Converts a path in the form a/b/c/d into %w(a b c d)
- 1
def self.path2navigate(path)
"%w[#{path.split('/').join(' ')}]"
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
require 'net/http'
- 1
require 'net/https'
- 1
module Google
- 1
module Sql
- 1
module Network
# A handler for authenticated network request
- 1
class Base
- 1
def initialize(link, cred)
@link = link
@cred = cred
end
- 1
def builder
Net::HTTP.const_get(self.class.name.split('::').last)
end
- 1
def send
request = @cred.authorize(builder.new(@link))
request['User-Agent'] = generate_user_agent
response = transport(request).request(request)
unless ENV['GOOGLE_HTTP_VERBOSE'].nil?
puts ["network(#{request}: [#{response.code}]",
response.body.split("\n").map(&:strip).join(' ')].join(' ')
end
response
end
- 1
def transport(request)
uri = request.uri
puts "network(#{request}: #{uri})" \
unless ENV['GOOGLE_HTTP_VERBOSE'].nil?
transport = Net::HTTP.new(uri.host, uri.port)
transport.use_ssl = uri.is_a?(URI::HTTPS)
transport.verify_mode = OpenSSL::SSL::VERIFY_PEER
transport.set_debug_output $stderr \
unless ENV['GOOGLE_HTTP_DEBUG'].nil?
transport
end
- 1
private
- 1
def generate_user_agent
# TODO(alexstephen): Check how to get the original Chef user agent.
# TODO(alexstephen): Check how to fetch cookbook version.
version = '1.0.0'
[
"GoogleChefSql/#{version}"
].join(' ')
end
end
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
require 'google/sql/network/base'
- 1
module Google
- 1
module Sql
- 1
module Network
# A wrapper class for a Get Request
- 1
class Delete < Google::Sql::Network::Base
end
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
require 'google/sql/network/base'
- 1
module Google
- 1
module Sql
- 1
module Network
# A wrapper class for a Get Request
- 1
class Get < Google::Sql::Network::Base
end
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
require 'google/sql/network/base'
- 1
module Google
- 1
module Sql
- 1
module Network
# A wrapper class for a Post Request
- 1
class Post < Google::Sql::Network::Base
- 1
def initialize(link, cred, type, body)
super(link, cred)
@type = type
@body = body
end
- 1
def transport(request)
request.content_type = @type
request.body = @body
puts "network(#{request}: body(#{@body}))" \
unless ENV['GOOGLE_HTTP_VERBOSE'].nil?
super(request)
end
end
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
require 'google/sql/network/base'
- 1
module Google
- 1
module Sql
- 1
module Network
# A wrapper class for a PUT Request
- 1
class Put < Google::Sql::Network::Base
- 1
def initialize(link, cred, type, body)
super(link, cred)
@type = type
@body = body
end
- 1
def transport(request)
request.content_type = @type
request.body = @body
puts "network(#{request}: body(#{@body}))" \
unless ENV['GOOGLE_HTTP_VERBOSE'].nil?
super(request)
end
end
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
module Google
- 1
module Sql
- 1
module Property
# A class to handle serialization of Array items.
- 1
class Array
- 1
def self.coerce
->(x) { ::Google::Sql::Property::Array.catalog_parse(x) }
end
- 1
def self.api_parse(value)
value
end
- 1
def self.catalog_parse(value)
value
end
end
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
module Google
- 1
module Sql
- 1
module Property
# A class to handle serialization of Boolean items.
- 1
class Boolean
- 1
def self.coerce
->(x) { ::Google::Sql::Property::Boolean.catalog_parse(x) }
end
- 1
def self.api_parse(value)
- 5
value
end
- 1
def self.catalog_parse(value)
value
end
end
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
module Google
- 1
module Sql
- 1
module Property
# A class to handle serialization of Enumerated items.
- 1
class Enum
- 1
def self.coerce
->(x) { ::Google::Sql::Property::Enum.catalog_parse(x) }
end
- 1
def self.api_parse(value)
- 7
value
end
- 1
def self.catalog_parse(value)
- 3
value
end
end
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
require 'google/sql/property/array'
- 1
module Google
- 1
module Sql
- 1
module Data
# A class to manage data for AuthorizedNetworks for instance.
- 1
class InstanceAuthorizedNetworks
- 1
include Comparable
- 1
attr_reader :expiration_time
- 1
attr_reader :name
- 1
attr_reader :value
- 1
def to_json(_arg = nil)
{
'expirationTime' => expiration_time,
'name' => name,
'value' => value
}.reject { |_k, v| v.nil? }.to_json
end
- 1
def to_s
{
expiration_time: expiration_time.to_s,
name: name.to_s,
value: value.to_s
}.map { |k, v| "#{k}: #{v}" }.join(', ')
end
- 1
def ==(other)
return false unless other.is_a? InstanceAuthorizedNetworks
compare_fields(other).each do |compare|
next if compare[:self].nil? || compare[:other].nil?
return false if compare[:self] != compare[:other]
end
true
end
- 1
def <=>(other)
return false unless other.is_a? InstanceAuthorizedNetworks
compare_fields(other).each do |compare|
next if compare[:self].nil? || compare[:other].nil?
result = compare[:self] <=> compare[:other]
return result unless result.zero?
end
0
end
- 1
def inspect
to_json
end
- 1
private
- 1
def compare_fields(other)
[
{ self: expiration_time, other: other.expiration_time },
{ self: name, other: other.name },
{ self: value, other: other.value }
]
end
end
# Manages a InstanceAuthorizedNetworks nested object
# Data is coming from the GCP API
- 1
class InstanceAuthorizedNetworksApi < InstanceAuthorizedNetworks
- 1
def initialize(args)
- 3
@expiration_time = Google::Sql::Property::Time.api_parse(args['expirationTime'])
- 3
@name = Google::Sql::Property::String.api_parse(args['name'])
- 3
@value = Google::Sql::Property::String.api_parse(args['value'])
end
end
# Manages a InstanceAuthorizedNetworks nested object
# Data is coming from the Chef catalog
- 1
class InstanceAuthorizedNetworksCatalog < InstanceAuthorizedNetworks
- 1
def initialize(args)
@expiration_time = Google::Sql::Property::Time.catalog_parse(args[:expiration_time])
@name = Google::Sql::Property::String.catalog_parse(args[:name])
@value = Google::Sql::Property::String.catalog_parse(args[:value])
end
end
end
- 1
module Property
# A class to manage input to AuthorizedNetworks for instance.
- 1
class InstanceAuthorizedNetworks
- 1
def self.coerce
->(x) { ::Google::Sql::Property::InstanceAuthorizedNetworks.catalog_parse(x) }
end
# Used for parsing Chef catalog
- 1
def self.catalog_parse(value)
return if value.nil?
return value if value.is_a? Data::InstanceAuthorizedNetworks
Data::InstanceAuthorizedNetworksCatalog.new(value)
end
# Used for parsing GCP API responses
- 1
def self.api_parse(value)
- 3
return if value.nil?
- 3
return value if value.is_a? Data::InstanceAuthorizedNetworks
- 3
Data::InstanceAuthorizedNetworksApi.new(value)
end
end
# A Chef property that holds an integer
- 1
class InstanceAuthorizedNetworksArray < Google::Sql::Property::Array
- 1
def self.coerce
->(x) { ::Google::Sql::Property::InstanceAuthorizedNetworksArray.catalog_parse(x) }
end
# Used for parsing Chef catalog
- 1
def self.catalog_parse(value)
return if value.nil?
return InstanceAuthorizedNetworks.catalog_parse(value) \
unless value.is_a?(::Array)
value.map { |v| InstanceAuthorizedNetworks.catalog_parse(v) }
end
# Used for parsing GCP API responses
- 1
def self.api_parse(value)
- 1
return if value.nil?
return InstanceAuthorizedNetworks.api_parse(value) \
- 1
unless value.is_a?(::Array)
- 4
value.map { |v| InstanceAuthorizedNetworks.api_parse(v) }
end
end
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
module Google
- 1
module Sql
- 1
module Data
# A class to manage data for FailoverReplica for instance.
- 1
class InstanceFailoverReplica
- 1
include Comparable
- 1
attr_reader :available
- 1
attr_reader :name
- 1
def to_json(_arg = nil)
{
'available' => available,
'name' => name
}.reject { |_k, v| v.nil? }.to_json
end
- 1
def to_s
{
available: available.to_s,
name: name.to_s
}.map { |k, v| "#{k}: #{v}" }.join(', ')
end
- 1
def ==(other)
return false unless other.is_a? InstanceFailoverReplica
compare_fields(other).each do |compare|
next if compare[:self].nil? || compare[:other].nil?
return false if compare[:self] != compare[:other]
end
true
end
- 1
def <=>(other)
return false unless other.is_a? InstanceFailoverReplica
compare_fields(other).each do |compare|
next if compare[:self].nil? || compare[:other].nil?
result = compare[:self] <=> compare[:other]
return result unless result.zero?
end
0
end
- 1
def inspect
to_json
end
- 1
private
- 1
def compare_fields(other)
[
{ self: available, other: other.available },
{ self: name, other: other.name }
]
end
end
# Manages a InstanceFailoverReplica nested object
# Data is coming from the GCP API
- 1
class InstanceFailoverReplicaApi < InstanceFailoverReplica
- 1
def initialize(args)
- 1
@available = Google::Sql::Property::Boolean.api_parse(args['available'])
- 1
@name = Google::Sql::Property::String.api_parse(args['name'])
end
end
# Manages a InstanceFailoverReplica nested object
# Data is coming from the Chef catalog
- 1
class InstanceFailoverReplicaCatalog < InstanceFailoverReplica
- 1
def initialize(args)
@available = Google::Sql::Property::Boolean.catalog_parse(args[:available])
@name = Google::Sql::Property::String.catalog_parse(args[:name])
end
end
end
- 1
module Property
# A class to manage input to FailoverReplica for instance.
- 1
class InstanceFailoverReplica
- 1
def self.coerce
->(x) { ::Google::Sql::Property::InstanceFailoverReplica.catalog_parse(x) }
end
# Used for parsing Chef catalog
- 1
def self.catalog_parse(value)
- 1
return if value.nil?
- 1
return value if value.is_a? Data::InstanceFailoverReplica
Data::InstanceFailoverReplicaCatalog.new(value)
end
# Used for parsing GCP API responses
- 1
def self.api_parse(value)
- 1
return if value.nil?
- 1
return value if value.is_a? Data::InstanceFailoverReplica
- 1
Data::InstanceFailoverReplicaApi.new(value)
end
end
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
require 'google/sql/property/array'
- 1
module Google
- 1
module Sql
- 1
module Data
# A class to manage data for IpAddresses for instance.
- 1
class InstanceIpAddresses
- 1
include Comparable
- 1
attr_reader :ip_address
- 1
attr_reader :time_to_retire
- 1
attr_reader :type
- 1
def to_json(_arg = nil)
{
'ipAddress' => ip_address,
'timeToRetire' => time_to_retire,
'type' => type
}.reject { |_k, v| v.nil? }.to_json
end
- 1
def to_s
{
ip_address: ip_address.to_s,
time_to_retire: time_to_retire.to_s,
type: type.to_s
}.map { |k, v| "#{k}: #{v}" }.join(', ')
end
- 1
def ==(other)
return false unless other.is_a? InstanceIpAddresses
compare_fields(other).each do |compare|
next if compare[:self].nil? || compare[:other].nil?
return false if compare[:self] != compare[:other]
end
true
end
- 1
def <=>(other)
return false unless other.is_a? InstanceIpAddresses
compare_fields(other).each do |compare|
next if compare[:self].nil? || compare[:other].nil?
result = compare[:self] <=> compare[:other]
return result unless result.zero?
end
0
end
- 1
def inspect
to_json
end
- 1
private
- 1
def compare_fields(other)
[
{ self: ip_address, other: other.ip_address },
{ self: time_to_retire, other: other.time_to_retire },
{ self: type, other: other.type }
]
end
end
# Manages a InstanceIpAddresses nested object
# Data is coming from the GCP API
- 1
class InstanceIpAddressesApi < InstanceIpAddresses
- 1
def initialize(args)
- 4
@ip_address = Google::Sql::Property::String.api_parse(args['ipAddress'])
- 4
@time_to_retire = Google::Sql::Property::Time.api_parse(args['timeToRetire'])
- 4
@type = Google::Sql::Property::Enum.api_parse(args['type'])
end
end
# Manages a InstanceIpAddresses nested object
# Data is coming from the Chef catalog
- 1
class InstanceIpAddressesCatalog < InstanceIpAddresses
- 1
def initialize(args)
@ip_address = Google::Sql::Property::String.catalog_parse(args[:ip_address])
@time_to_retire = Google::Sql::Property::Time.catalog_parse(args[:time_to_retire])
@type = Google::Sql::Property::Enum.catalog_parse(args[:type])
end
end
end
- 1
module Property
# A class to manage input to IpAddresses for instance.
- 1
class InstanceIpAddresses
- 1
def self.coerce
->(x) { ::Google::Sql::Property::InstanceIpAddresses.catalog_parse(x) }
end
# Used for parsing Chef catalog
- 1
def self.catalog_parse(value)
- 4
return if value.nil?
- 4
return value if value.is_a? Data::InstanceIpAddresses
Data::InstanceIpAddressesCatalog.new(value)
end
# Used for parsing GCP API responses
- 1
def self.api_parse(value)
- 4
return if value.nil?
- 4
return value if value.is_a? Data::InstanceIpAddresses
- 4
Data::InstanceIpAddressesApi.new(value)
end
end
# A Chef property that holds an integer
- 1
class InstanceIpAddressesArray < Google::Sql::Property::Array
- 1
def self.coerce
->(x) { ::Google::Sql::Property::InstanceIpAddressesArray.catalog_parse(x) }
end
# Used for parsing Chef catalog
- 1
def self.catalog_parse(value)
- 1
return if value.nil?
return InstanceIpAddresses.catalog_parse(value) \
- 1
unless value.is_a?(::Array)
- 5
value.map { |v| InstanceIpAddresses.catalog_parse(v) }
end
# Used for parsing GCP API responses
- 1
def self.api_parse(value)
- 1
return if value.nil?
return InstanceIpAddresses.api_parse(value) \
- 1
unless value.is_a?(::Array)
- 5
value.map { |v| InstanceIpAddresses.api_parse(v) }
end
end
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
module Google
- 1
module Sql
- 1
module Data
# A class to manage data for IpConfiguration for instance.
- 1
class InstanceIpConfiguration
- 1
include Comparable
- 1
attr_reader :ipv4_enabled
- 1
attr_reader :authorized_networks
- 1
attr_reader :require_ssl
- 1
def to_json(_arg = nil)
{
'ipv4Enabled' => ipv4_enabled,
'authorizedNetworks' => authorized_networks,
'requireSsl' => require_ssl
}.reject { |_k, v| v.nil? }.to_json
end
- 1
def to_s
{
ipv4_enabled: ipv4_enabled.to_s,
authorized_networks: ['[',
authorized_networks.map(&:to_json).join(', '),
']'].join(' '),
require_ssl: require_ssl.to_s
}.map { |k, v| "#{k}: #{v}" }.join(', ')
end
- 1
def ==(other)
return false unless other.is_a? InstanceIpConfiguration
compare_fields(other).each do |compare|
next if compare[:self].nil? || compare[:other].nil?
return false if compare[:self] != compare[:other]
end
true
end
- 1
def <=>(other)
return false unless other.is_a? InstanceIpConfiguration
compare_fields(other).each do |compare|
next if compare[:self].nil? || compare[:other].nil?
result = compare[:self] <=> compare[:other]
return result unless result.zero?
end
0
end
- 1
def inspect
to_json
end
- 1
private
- 1
def compare_fields(other)
[
{ self: ipv4_enabled, other: other.ipv4_enabled },
{ self: authorized_networks, other: other.authorized_networks },
{ self: require_ssl, other: other.require_ssl }
]
end
end
# Manages a InstanceIpConfiguration nested object
# Data is coming from the GCP API
- 1
class InstanceIpConfigurationApi < InstanceIpConfiguration
- 1
def initialize(args)
- 1
@ipv4_enabled = Google::Sql::Property::Boolean.api_parse(args['ipv4Enabled'])
- 1
@authorized_networks = Google::Sql::Property::InstanceAuthorizedNetworksArray.api_parse(
args['authorizedNetworks']
)
- 1
@require_ssl = Google::Sql::Property::Boolean.api_parse(args['requireSsl'])
end
end
# Manages a InstanceIpConfiguration nested object
# Data is coming from the Chef catalog
- 1
class InstanceIpConfigurationCatalog < InstanceIpConfiguration
- 1
def initialize(args)
@ipv4_enabled = Google::Sql::Property::Boolean.catalog_parse(args[:ipv4_enabled])
@authorized_networks =
Google::Sql::Property::InstanceAuthorizedNetworksArray.catalog_parse(
args[:authorized_networks]
)
@require_ssl = Google::Sql::Property::Boolean.catalog_parse(args[:require_ssl])
end
end
end
- 1
module Property
# A class to manage input to IpConfiguration for instance.
- 1
class InstanceIpConfiguration
- 1
def self.coerce
->(x) { ::Google::Sql::Property::InstanceIpConfiguration.catalog_parse(x) }
end
# Used for parsing Chef catalog
- 1
def self.catalog_parse(value)
return if value.nil?
return value if value.is_a? Data::InstanceIpConfiguration
Data::InstanceIpConfigurationCatalog.new(value)
end
# Used for parsing GCP API responses
- 1
def self.api_parse(value)
- 1
return if value.nil?
- 1
return value if value.is_a? Data::InstanceIpConfiguration
- 1
Data::InstanceIpConfigurationApi.new(value)
end
end
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
module Google
- 1
module Sql
- 1
module Data
# A class to manage data for MysqlReplicaConfiguration for instance.
- 1
class InstanceMysqlReplicaConfiguration
- 1
include Comparable
- 1
attr_reader :ca_certificate
- 1
attr_reader :client_certificate
- 1
attr_reader :client_key
- 1
attr_reader :connect_retry_interval
- 1
attr_reader :dump_file_path
- 1
attr_reader :master_heartbeat_period
- 1
attr_reader :password
- 1
attr_reader :ssl_cipher
- 1
attr_reader :username
- 1
attr_reader :verify_server_certificate
- 1
def to_json(_arg = nil)
{
'caCertificate' => ca_certificate,
'clientCertificate' => client_certificate,
'clientKey' => client_key,
'connectRetryInterval' => connect_retry_interval,
'dumpFilePath' => dump_file_path,
'masterHeartbeatPeriod' => master_heartbeat_period,
'password' => password,
'sslCipher' => ssl_cipher,
'username' => username,
'verifyServerCertificate' => verify_server_certificate
}.reject { |_k, v| v.nil? }.to_json
end
- 1
def to_s
{
ca_certificate: ca_certificate.to_s,
client_certificate: client_certificate.to_s,
client_key: client_key.to_s,
connect_retry_interval: connect_retry_interval.to_s,
dump_file_path: dump_file_path.to_s,
master_heartbeat_period: master_heartbeat_period.to_s,
password: password.to_s,
ssl_cipher: ssl_cipher.to_s,
username: username.to_s,
verify_server_certificate: verify_server_certificate.to_s
}.map { |k, v| "#{k}: #{v}" }.join(', ')
end
- 1
def ==(other)
return false unless other.is_a? InstanceMysqlReplicaConfiguration
compare_fields(other).each do |compare|
next if compare[:self].nil? || compare[:other].nil?
return false if compare[:self] != compare[:other]
end
true
end
- 1
def <=>(other)
return false unless other.is_a? InstanceMysqlReplicaConfiguration
compare_fields(other).each do |compare|
next if compare[:self].nil? || compare[:other].nil?
result = compare[:self] <=> compare[:other]
return result unless result.zero?
end
0
end
- 1
def inspect
to_json
end
- 1
private
# rubocop:disable Metrics/MethodLength
- 1
def compare_fields(other)
[
{ self: ca_certificate, other: other.ca_certificate },
{ self: client_certificate, other: other.client_certificate },
{ self: client_key, other: other.client_key },
{ self: connect_retry_interval, other: other.connect_retry_interval },
{ self: dump_file_path, other: other.dump_file_path },
{ self: master_heartbeat_period, other: other.master_heartbeat_period },
{ self: password, other: other.password },
{ self: ssl_cipher, other: other.ssl_cipher },
{ self: username, other: other.username },
{ self: verify_server_certificate, other: other.verify_server_certificate }
]
end
# rubocop:enable Metrics/MethodLength
end
# Manages a InstanceMysqlReplicaConfiguration nested object
# Data is coming from the GCP API
- 1
class InstanceMysqlReplicaConfigurationApi < InstanceMysqlReplicaConfiguration
# rubocop:disable Metrics/MethodLength
- 1
def initialize(args)
- 1
@ca_certificate = Google::Sql::Property::String.api_parse(args['caCertificate'])
- 1
@client_certificate = Google::Sql::Property::String.api_parse(args['clientCertificate'])
- 1
@client_key = Google::Sql::Property::String.api_parse(args['clientKey'])
- 1
@connect_retry_interval =
Google::Sql::Property::Integer.api_parse(args['connectRetryInterval'])
- 1
@dump_file_path = Google::Sql::Property::String.api_parse(args['dumpFilePath'])
- 1
@master_heartbeat_period =
Google::Sql::Property::Integer.api_parse(args['masterHeartbeatPeriod'])
- 1
@password = Google::Sql::Property::String.api_parse(args['password'])
- 1
@ssl_cipher = Google::Sql::Property::String.api_parse(args['sslCipher'])
- 1
@username = Google::Sql::Property::String.api_parse(args['username'])
- 1
@verify_server_certificate =
Google::Sql::Property::Boolean.api_parse(args['verifyServerCertificate'])
end
# rubocop:enable Metrics/MethodLength
end
# Manages a InstanceMysqlReplicaConfiguration nested object
# Data is coming from the Chef catalog
- 1
class InstanceMysqlReplicaConfigurationCatalog < InstanceMysqlReplicaConfiguration
# rubocop:disable Metrics/MethodLength
- 1
def initialize(args)
@ca_certificate = Google::Sql::Property::String.catalog_parse(args[:ca_certificate])
@client_certificate =
Google::Sql::Property::String.catalog_parse(args[:client_certificate])
@client_key = Google::Sql::Property::String.catalog_parse(args[:client_key])
@connect_retry_interval =
Google::Sql::Property::Integer.catalog_parse(args[:connect_retry_interval])
@dump_file_path = Google::Sql::Property::String.catalog_parse(args[:dump_file_path])
@master_heartbeat_period =
Google::Sql::Property::Integer.catalog_parse(args[:master_heartbeat_period])
@password = Google::Sql::Property::String.catalog_parse(args[:password])
@ssl_cipher = Google::Sql::Property::String.catalog_parse(args[:ssl_cipher])
@username = Google::Sql::Property::String.catalog_parse(args[:username])
@verify_server_certificate =
Google::Sql::Property::Boolean.catalog_parse(args[:verify_server_certificate])
end
# rubocop:enable Metrics/MethodLength
end
end
- 1
module Property
# A class to manage input to MysqlReplicaConfiguration for instance.
- 1
class InstanceMysqlReplicaConfiguration
- 1
def self.coerce
->(x) { ::Google::Sql::Property::InstanceMysqlReplicaConfiguration.catalog_parse(x) }
end
# Used for parsing Chef catalog
- 1
def self.catalog_parse(value)
return if value.nil?
return value if value.is_a? Data::InstanceMysqlReplicaConfiguration
Data::InstanceMysqlReplicaConfigurationCatalog.new(value)
end
# Used for parsing GCP API responses
- 1
def self.api_parse(value)
- 1
return if value.nil?
- 1
return value if value.is_a? Data::InstanceMysqlReplicaConfiguration
- 1
Data::InstanceMysqlReplicaConfigurationApi.new(value)
end
end
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
module Google
- 1
module Sql
- 1
module Data
# Base class for ResourceRefs
# Imports name from instance
- 1
class InstanceNameRef
- 1
include Comparable
- 1
def ==(other)
return false unless other.is_a? InstanceNameRef
return false if resource != other.resource
true
end
- 1
def <=>(other)
resource <=> other.resource
end
# Overriding inspect method ensures that Chef logs only the
# fetched value to the console
- 1
def inspect
"'#{resource}'"
end
end
# A class to fetch the resource value from a referenced block
# Will return the value exported from a different Chef resource
- 1
class InstanceNameRefCatalog < InstanceNameRef
- 1
def initialize(title)
- 1
@title = title
end
# Chef requires the title for autorequiring
- 1
def autorequires
[@title]
end
- 1
def to_s
- 3
resource.to_s
end
- 1
def to_json(_arg = nil)
return if resource.nil?
resource.to_json
end
- 1
def resource
- 3
Chef.run_context.resource_collection.each do |entry|
- 6
return entry.exports[:name] if entry.name == @title
end
raise ArgumentError, "gsql_instance[#{@title}] required"
end
end
# A class to manage a JSON blob from GCP API
# Will immediately return value from JSON blob without changes
- 1
class InstanceNameRefApi < InstanceNameRef
- 1
attr_reader :resource
- 1
def initialize(resource)
@resource = resource
end
- 1
def to_s
@resource.to_s
end
- 1
def to_json(_arg = nil)
@resource.to_json
end
end
end
- 1
module Property
# A class to manage fetching name from a instance
- 1
class InstanceNameRef
- 1
def self.coerce
->(x) { ::Google::Sql::Property::InstanceNameRef.catalog_parse(x) }
end
- 1
def catalog_parse(value)
return if value.nil?
self.class.catalog_parse(value)
end
- 1
def self.catalog_parse(value)
- 1
return if value.nil?
- 1
return value if value.is_a? Data::InstanceNameRef
- 1
Data::InstanceNameRefCatalog.new(value)
end
# Used for fetched JSON values
- 1
def self.api_parse(value)
return if value.nil?
return value if value.is_a? Data::InstanceNameRef
Data::InstanceNameRefApi.new(value)
end
end
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
module Google
- 1
module Sql
- 1
module Data
# A class to manage data for ReplicaConfiguration for instance.
- 1
class InstanceReplicaConfiguration
- 1
include Comparable
- 1
attr_reader :failover_target
- 1
attr_reader :mysql_replica_configuration
- 1
attr_reader :replica_names
- 1
attr_reader :service_account_email_address
- 1
def to_json(_arg = nil)
{
'failoverTarget' => failover_target,
'mysqlReplicaConfiguration' => mysql_replica_configuration,
'replicaNames' => replica_names,
'serviceAccountEmailAddress' => service_account_email_address
}.reject { |_k, v| v.nil? }.to_json
end
- 1
def to_s
{
failover_target: failover_target.to_s,
mysql_replica_configuration: mysql_replica_configuration.to_s,
replica_names: replica_names.to_s,
service_account_email_address: service_account_email_address.to_s
}.map { |k, v| "#{k}: #{v}" }.join(', ')
end
- 1
def ==(other)
return false unless other.is_a? InstanceReplicaConfiguration
compare_fields(other).each do |compare|
next if compare[:self].nil? || compare[:other].nil?
return false if compare[:self] != compare[:other]
end
true
end
- 1
def <=>(other)
return false unless other.is_a? InstanceReplicaConfiguration
compare_fields(other).each do |compare|
next if compare[:self].nil? || compare[:other].nil?
result = compare[:self] <=> compare[:other]
return result unless result.zero?
end
0
end
- 1
def inspect
to_json
end
- 1
private
- 1
def compare_fields(other)
[
{ self: failover_target, other: other.failover_target },
{ self: mysql_replica_configuration, other: other.mysql_replica_configuration },
{ self: replica_names, other: other.replica_names },
{ self: service_account_email_address, other: other.service_account_email_address }
]
end
end
# Manages a InstanceReplicaConfiguration nested object
# Data is coming from the GCP API
- 1
class InstanceReplicaConfigurationApi < InstanceReplicaConfiguration
- 1
def initialize(args)
- 1
@failover_target = Google::Sql::Property::Boolean.api_parse(args['failoverTarget'])
- 1
@mysql_replica_configuration =
Google::Sql::Property::InstanceMysqlReplicaConfiguration.api_parse(
args['mysqlReplicaConfiguration']
)
- 1
@replica_names = Google::Sql::Property::StringArray.api_parse(args['replicaNames'])
- 1
@service_account_email_address =
Google::Sql::Property::String.api_parse(args['serviceAccountEmailAddress'])
end
end
# Manages a InstanceReplicaConfiguration nested object
# Data is coming from the Chef catalog
- 1
class InstanceReplicaConfigurationCatalog < InstanceReplicaConfiguration
- 1
def initialize(args)
@failover_target = Google::Sql::Property::Boolean.catalog_parse(args[:failover_target])
@mysql_replica_configuration =
Google::Sql::Property::InstanceMysqlReplicaConfiguration.catalog_parse(
args[:mysql_replica_configuration]
)
@replica_names = Google::Sql::Property::StringArray.catalog_parse(args[:replica_names])
@service_account_email_address =
Google::Sql::Property::String.catalog_parse(args[:service_account_email_address])
end
end
end
- 1
module Property
# A class to manage input to ReplicaConfiguration for instance.
- 1
class InstanceReplicaConfiguration
- 1
def self.coerce
->(x) { ::Google::Sql::Property::InstanceReplicaConfiguration.catalog_parse(x) }
end
# Used for parsing Chef catalog
- 1
def self.catalog_parse(value)
- 1
return if value.nil?
- 1
return value if value.is_a? Data::InstanceReplicaConfiguration
Data::InstanceReplicaConfigurationCatalog.new(value)
end
# Used for parsing GCP API responses
- 1
def self.api_parse(value)
- 1
return if value.nil?
- 1
return value if value.is_a? Data::InstanceReplicaConfiguration
- 1
Data::InstanceReplicaConfigurationApi.new(value)
end
end
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
module Google
- 1
module Sql
- 1
module Data
# A class to manage data for Settings for instance.
- 1
class InstanceSettings
- 1
include Comparable
- 1
attr_reader :ip_configuration
- 1
attr_reader :tier
- 1
attr_reader :settings_version
- 1
def to_json(_arg = nil)
{
'ipConfiguration' => ip_configuration,
'tier' => tier,
'settingsVersion' => settings_version
}.reject { |_k, v| v.nil? }.to_json
end
- 1
def to_s
{
ip_configuration: ip_configuration.to_s,
tier: tier.to_s,
settings_version: settings_version.to_s
}.map { |k, v| "#{k}: #{v}" }.join(', ')
end
- 1
def ==(other)
return false unless other.is_a? InstanceSettings
compare_fields(other).each do |compare|
next if compare[:self].nil? || compare[:other].nil?
return false if compare[:self] != compare[:other]
end
true
end
- 1
def <=>(other)
return false unless other.is_a? InstanceSettings
compare_fields(other).each do |compare|
next if compare[:self].nil? || compare[:other].nil?
result = compare[:self] <=> compare[:other]
return result unless result.zero?
end
0
end
- 1
def inspect
to_json
end
- 1
private
- 1
def compare_fields(other)
[
{ self: ip_configuration, other: other.ip_configuration },
{ self: tier, other: other.tier },
{ self: settings_version, other: other.settings_version }
]
end
end
# Manages a InstanceSettings nested object
# Data is coming from the GCP API
- 1
class InstanceSettingsApi < InstanceSettings
- 1
def initialize(args)
- 1
@ip_configuration =
Google::Sql::Property::InstanceIpConfiguration.api_parse(args['ipConfiguration'])
- 1
@tier = Google::Sql::Property::String.api_parse(args['tier'])
- 1
@settings_version = Google::Sql::Property::Integer.api_parse(args['settingsVersion'])
end
end
# Manages a InstanceSettings nested object
# Data is coming from the Chef catalog
- 1
class InstanceSettingsCatalog < InstanceSettings
- 1
def initialize(args)
@ip_configuration =
Google::Sql::Property::InstanceIpConfiguration.catalog_parse(args[:ip_configuration])
@tier = Google::Sql::Property::String.catalog_parse(args[:tier])
@settings_version = Google::Sql::Property::Integer.catalog_parse(args[:settings_version])
end
end
end
- 1
module Property
# A class to manage input to Settings for instance.
- 1
class InstanceSettings
- 1
def self.coerce
->(x) { ::Google::Sql::Property::InstanceSettings.catalog_parse(x) }
end
# Used for parsing Chef catalog
- 1
def self.catalog_parse(value)
- 1
return if value.nil?
- 1
return value if value.is_a? Data::InstanceSettings
Data::InstanceSettingsCatalog.new(value)
end
# Used for parsing GCP API responses
- 1
def self.api_parse(value)
- 1
return if value.nil?
- 1
return value if value.is_a? Data::InstanceSettings
- 1
Data::InstanceSettingsApi.new(value)
end
end
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
module Google
- 1
module Sql
- 1
module Property
# A class to handle serialization of Integer items.
- 1
class Integer
- 1
def self.coerce
->(x) { ::Google::Sql::Property::Integer.catalog_parse(x) }
end
- 1
def self.api_parse(value)
- 4
value.to_i
end
- 1
def self.catalog_parse(value)
- 1
value.to_i
end
end
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
module Google
- 1
module Sql
- 1
module Property
# A class to handle serialization of String items.
- 1
class String
- 1
def self.coerce
->(x) { ::Google::Sql::Property::String.catalog_parse(x) }
end
- 1
def self.api_parse(value)
- 25
value
end
- 1
def self.catalog_parse(value)
- 8
value
end
end
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
require 'google/sql/property/array'
- 1
module Google
- 1
module Sql
- 1
module Property
# A class to handle serialization of Array items.
- 1
class StringArray < Google::Sql::Property::Array
- 1
def self.coerce
->(x) { ::Google::Sql::Property::StringArray.catalog_parse(x) }
end
- 1
def self.api_parse(value)
- 1
value
end
- 1
def self.catalog_parse(value)
value
end
- 1
def self.validate(value)
return if value.nil? || value.is_a?(::String)
unless value.is_a? ::Array
raise "Expected string but found #{value.class} instead: #{value}"
end
value.each { |v| validate v }
end
end
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
require 'time'
- 1
module Google
- 1
module Sql
- 1
module Data
# A Time that always returns a ISO-8601 string
- 1
class Time < ::Time
- 1
def to_s
# All GCP APIs expect timestamps in the ISO-8601 / RFC3339 format
# Overriding the .to_s method ensures that Ruby will get a
# ISO-8601 timestamp at the last moment and ensures the timestamp
# format is abstracted away.
iso8601
end
end
end
- 1
module Property
# A class to handle serialization of Time items.
- 1
class Time
- 1
def self.coerce
->(x) { ::Google::Sql::Property::Time.catalog_parse(x) }
end
- 1
def self.api_parse(value)
- 7
return if value.nil?
- 7
return value if value.is_a? ::Time
- 7
Data::Time.parse(value)
end
- 1
def self.catalog_parse(value)
return if value.nil?
return value if value.is_a? ::Time
Data::Time.parse(value)
end
end
end
end
end
# Copyright 2017 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
- 1
module Google
# Helper class to process and mutate strings.
- 1
class StringUtils
# Converts string from underscore to camel case
- 1
def self.camelize(source, style = :lower)
camelized = source.gsub(/_(.)/, &:upcase).delete('_')
case style
when :lower
camelized[0] = camelized[0].downcase
when :upper
camelized[0] = camelized[0].upcase
else
raise "Unknown camel case style: #{style}"
end
camelized
end
# Converts string from camel case to underscore
- 1
def self.underscore(source)
source.gsub(/::/, '/')
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
.tr('-', '_')
.tr('.', '_')
.downcase
end
# Add spaces before every capitalized word except first.
- 1
def self.uncombine(source)
source.gsub(/(?=[A-Z])/, ' ').strip
end
# rubocop:disable Style/SafeNavigation # support Ruby < 2.3.0
- 1
def self.symbolize(key)
key.to_sym unless key.nil?
end
# rubocop:enable Style/SafeNavigation
# Returns all the characters up until the period (.) or returns text
# unchanged if there is no period.
- 1
def self.first_sentence(text)
period_pos = text.index(/[\.\?!]/)
return text if period_pos.nil?
text[0, period_pos + 1]
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
# Add our google/ lib
- 1
$LOAD_PATH.unshift ::File.expand_path('../libraries', ::File.dirname(__FILE__))
- 1
require 'chef/resource'
- 1
require 'google/hash_utils'
- 1
require 'google/sql/network/delete'
- 1
require 'google/sql/network/get'
- 1
require 'google/sql/network/post'
- 1
require 'google/sql/network/put'
- 1
require 'google/sql/property/instance_name'
- 1
require 'google/sql/property/string'
- 1
module Google
- 1
module GSQL
# A provider to manage Google Cloud SQL resources.
# rubocop:disable Metrics/ClassLength
- 1
class Database < Chef::Resource
- 1
resource_name :gsql_database
- 1
property :charset, String, coerce: ::Google::Sql::Property::String.coerce, desired_state: true
- 1
property :collation,
String, coerce: ::Google::Sql::Property::String.coerce, desired_state: true
- 1
property :d_label,
String,
coerce: ::Google::Sql::Property::String.coerce,
name_property: true, desired_state: true
- 1
property :instance,
[String, ::Google::Sql::Data::InstanceNameRef],
coerce: ::Google::Sql::Property::InstanceNameRef.coerce, desired_state: true
- 1
property :credential, String, desired_state: false, required: true
- 1
property :project, String, desired_state: false, required: true
- 1
action :create do
fetch = fetch_resource(@new_resource, self_link(@new_resource),
'sql#database')
if fetch.nil?
converge_by "Creating gsql_database[#{new_resource.name}]" do
# TODO(nelsonjr): Show a list of variables to create
# TODO(nelsonjr): Determine how to print green like update converge
puts # making a newline until we find a better way TODO: find!
compute_changes.each { |log| puts " - #{log.strip}\n" }
create_req = ::Google::Sql::Network::Post.new(
collection(@new_resource), fetch_auth(@new_resource),
'application/json', resource_to_request
)
wait_for_operation create_req.send, @new_resource
end
else
@current_resource = @new_resource.clone
@current_resource.charset = ::Google::Sql::Property::String.api_parse(fetch['charset'])
@current_resource.collation =
::Google::Sql::Property::String.api_parse(fetch['collation'])
@current_resource.d_label = ::Google::Sql::Property::String.api_parse(fetch['name'])
update
end
end
- 1
action :delete do
fetch = fetch_resource(@new_resource, self_link(@new_resource),
'sql#database')
unless fetch.nil?
converge_by "Deleting gsql_database[#{new_resource.name}]" do
delete_req = ::Google::Sql::Network::Delete.new(
self_link(@new_resource), fetch_auth(@new_resource)
)
wait_for_operation delete_req.send, @new_resource
end
end
end
# TODO(nelsonjr): Add actions :manage and :modify
- 1
private
- 1
action_class do
- 1
def resource_to_request
request = {
kind: 'sql#database',
charset: new_resource.charset,
collation: new_resource.collation,
name: new_resource.d_label
}.reject { |_, v| v.nil? }
request.to_json
end
- 1
def update
converge_if_changed do |_vars|
# TODO(nelsonjr): Determine how to print indented like upd converge
# TODO(nelsonjr): Check w/ Chef... can we print this in red?
puts # making a newline until we find a better way TODO: find!
compute_changes.each { |log| puts " - #{log.strip}\n" }
update_req =
::Google::Sql::Network::Put.new(self_link(@new_resource),
fetch_auth(@new_resource),
'application/json',
resource_to_request)
wait_for_operation update_req.send, @new_resource
end
end
- 1
def self.fetch_export(resource, type, id, property)
return if id.nil?
resource.resources("#{type}[#{id}]").exports[property]
end
- 1
def self.resource_to_hash(resource)
{
project: resource.project,
name: resource.d_label,
kind: 'sql#database',
charset: resource.charset,
collation: resource.collation,
instance: resource.instance
}.reject { |_, v| v.nil? }
end
# Copied from Chef > Provider > #converge_if_changed
- 1
def compute_changes
properties = @new_resource.class.state_properties.map(&:name)
properties = properties.map(&:to_sym)
if current_resource
compute_changes_for_existing_resource properties
else
compute_changes_for_new_resource properties
end
end
# Collect the list of modified properties
- 1
def compute_changes_for_existing_resource(properties)
specified_properties = properties.select do |property|
@new_resource.property_is_set?(property)
end
modified = specified_properties.reject do |p|
@new_resource.send(p) == current_resource.send(p)
end
generate_pretty_green_text(modified)
end
- 1
def generate_pretty_green_text(modified)
property_size = modified.map(&:size).max
modified.map! do |p|
properties_str = if @new_resource.sensitive
'(suppressed sensitive property)'
else
[
@new_resource.send(p).inspect,
"(was #{current_resource.send(p).inspect})"
].join(' ')
end
" set #{p.to_s.ljust(property_size)} to #{properties_str}"
end
end
# Write down any properties we are setting.
- 1
def compute_changes_for_new_resource(properties)
property_size = properties.map(&:size).max
properties.map do |property|
default = ' (default value)' \
unless @new_resource.property_is_set?(property)
next if @new_resource.send(property).nil?
properties_str = if @new_resource.sensitive
'(suppressed sensitive property)'
else
@new_resource.send(property).inspect
end
[" set #{property.to_s.ljust(property_size)}",
"to #{properties_str}#{default}"].join(' ')
end.compact
end
- 1
def fetch_auth(resource)
self.class.fetch_auth(resource)
end
- 1
def self.fetch_auth(resource)
resource.resources("gauth_credential[#{resource.credential}]")
.authorization
end
- 1
def fetch_resource(resource, self_link, kind)
self.class.fetch_resource(resource, self_link, kind)
end
- 1
def debug(message)
Chef::Log.debug(message)
end
- 1
def self.collection(data)
URI.join(
'https://www.googleapis.com/sql/v1beta4/',
expand_variables(
'projects/{{project}}/instances/{{instance}}/databases',
data
)
)
end
- 1
def collection(data)
self.class.collection(data)
end
- 1
def self.self_link(data)
URI.join(
'https://www.googleapis.com/sql/v1beta4/',
expand_variables(
'projects/{{project}}/instances/{{instance}}/databases/{{name}}',
data
)
)
end
- 1
def self_link(data)
self.class.self_link(data)
end
# rubocop:disable Metrics/CyclomaticComplexity
- 1
def self.return_if_object(response, kind)
raise "Bad response: #{response}" \
unless response.is_a?(Net::HTTPResponse)
return if response.is_a?(Net::HTTPNotFound)
return if response.is_a?(Net::HTTPNoContent)
# TODO(nelsonjr): Remove return of Net::HTTPForbidden from
# return_if_object once Cloud SQL bug http://b/62635365 is resolved.
# Currently the API returns 403 for objects that do not exist, even
# when the user has access to the project. This is being changed to
# return 404 as it is supposed to be.
# Once 404 is the correct response, the temporary workaround should
# be removed.
return if response.is_a?(Net::HTTPForbidden)
result = JSON.parse(response.body)
raise_if_errors result, %w[error errors], 'message'
raise "Bad response: #{response}" unless response.is_a?(Net::HTTPOK)
# TODO(nelsonjr): Revert this check back to standard once Cloud SQL
# bug http://b/62841551 is resolved.
# Currently the sql#operation#targetLink for create returns a
# sql#database while for a delete it returns a sql#instance.
# | raise "Incorrect result: #{result['kind']} (expecting #{kind})" \
# | unless result['kind'] == kind
raise "Incorrect result: #{result['kind']} (expecting #{kind})" \
unless [kind, 'sql#instance'].include?(result['kind'])
result
end
# rubocop:enable Metrics/CyclomaticComplexity
- 1
def return_if_object(response, kind)
self.class.return_if_object(response, kind)
end
- 1
def self.extract_variables(template)
- 518
template.scan(/{{[^}]*}}/).map { |v| v.gsub(/{{([^}]*)}}/, '\1') }
- 178
.map(&:to_sym)
end
- 1
def self.expand_variables(template, var_data, extra_data = {})
- 178
data = if var_data.class <= Hash
- 178
var_data.merge(extra_data)
else
resource_to_hash(var_data).merge(extra_data)
end
- 178
extract_variables(template).each do |v|
- 518
unless data.key?(v)
raise "Missing variable :#{v} in #{data} on #{caller.join("\n")}}"
end
- 518
template.gsub!(/{{#{v}}}/, CGI.escape(data[v].to_s))
end
- 178
template
end
- 1
def expand_variables(template, var_data, extra_data = {})
self.class.expand_variables(template, var_data, extra_data)
end
- 1
def fetch_resource(resource, self_link, kind)
self.class.fetch_resource(resource, self_link, kind)
end
- 1
def async_op_url(data, extra_data = {})
URI.join(
'https://www.googleapis.com/sql/v1beta4/',
expand_variables(
'projects/{{project}}/operations/{{op_id}}',
data, extra_data
)
)
end
- 1
def wait_for_operation(response, resource)
op_result = return_if_object(response, 'sql#operation')
return if op_result.nil?
status = ::Google::HashUtils.navigate(op_result, %w[status])
fetch_resource(
resource,
URI.parse(::Google::HashUtils.navigate(wait_for_completion(status,
op_result,
resource),
%w[targetLink])),
'sql#database'
)
end
- 1
def wait_for_completion(status, op_result, resource)
op_id = ::Google::HashUtils.navigate(op_result, %w[name])
op_uri = async_op_url(resource, op_id: op_id)
while status != 'DONE'
debug("Waiting for completion of operation #{op_id}")
raise_if_errors op_result, %w[error errors], 'message'
sleep 1.0
raise "Invalid result '#{status}' on gsql_database." \
unless %w[PENDING RUNNING DONE].include?(status)
op_result = fetch_resource(resource, op_uri, 'sql#operation')
status = ::Google::HashUtils.navigate(op_result, %w[status])
end
op_result
end
- 1
def raise_if_errors(response, err_path, msg_field)
self.class.raise_if_errors(response, err_path, msg_field)
end
- 1
def self.fetch_resource(resource, self_link, kind)
get_request = ::Google::Sql::Network::Get.new(
self_link, fetch_auth(resource)
)
return_if_object get_request.send, kind
end
- 1
def self.raise_if_errors(response, err_path, msg_field)
errors = ::Google::HashUtils.navigate(response, err_path)
raise_error(errors, msg_field) unless errors.nil?
end
- 1
def self.raise_error(errors, msg_field)
raise IOError, ['Operation failed:',
errors.map { |e| e[msg_field] }.join(', ')].join(' ')
end
end
end
# rubocop:enable Metrics/ClassLength
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
# Add our google/ lib
- 1
$LOAD_PATH.unshift ::File.expand_path('../libraries', ::File.dirname(__FILE__))
- 1
require 'chef/resource'
- 1
require 'google/hash_utils'
- 1
require 'google/sql/network/get'
- 1
require 'google/sql/property/boolean'
- 1
require 'google/sql/property/integer'
- 1
require 'google/sql/property/string'
- 1
require 'google/sql/property/string_array'
- 1
module Google
- 1
module GSQL
# A provider to manage Google Cloud SQL resources.
# rubocop:disable Metrics/ClassLength
- 1
class Flag < Chef::Resource
- 1
resource_name :gsql_flag
# allowed_string_values is Array of Google::Sql::Property::StringArray
- 1
property :allowed_string_values,
Array, coerce: ::Google::Sql::Property::StringArray.coerce, desired_state: true
# applies_to is Array of Google::Sql::Property::StringArray
- 1
property :applies_to,
Array, coerce: ::Google::Sql::Property::StringArray.coerce, desired_state: true
- 1
property :max_value,
Integer, coerce: ::Google::Sql::Property::Integer.coerce, desired_state: true
- 1
property :min_value,
Integer, coerce: ::Google::Sql::Property::Integer.coerce, desired_state: true
- 1
property :f_label,
String,
coerce: ::Google::Sql::Property::String.coerce,
name_property: true, desired_state: true
- 1
property :requires_restart,
kind_of: [TrueClass, FalseClass],
coerce: ::Google::Sql::Property::Boolean.coerce, desired_state: true
- 1
property :type, String, coerce: ::Google::Sql::Property::String.coerce, desired_state: true
- 1
property :credential, String, desired_state: false, required: true
- 1
property :project, String, desired_state: false, required: true
- 1
action :create do
Chef.deprecated(:generic,
["gsql_flag has been deprecated.",
"Please use the Flag Name instead."
].join(" "))
fetch = fetch_wrapped_resource(@new_resource, 'sql#flag',
'sql#flagsList',
'items')
if fetch.nil?
converge_by "Creating gsql_flag[#{new_resource.name}]" do
# TODO(nelsonjr): Show a list of variables to create
# TODO(nelsonjr): Determine how to print green like update converge
puts # making a newline until we find a better way TODO: find!
compute_changes.each { |log| puts " - #{log.strip}\n" }
create_req = ::Google::Sql::Network::Post.new(
collection(@new_resource), fetch_auth(@new_resource),
'application/json', resource_to_request
)
return_if_object create_req.send, 'sql#flag'
end
else
@current_resource = @new_resource.clone
@current_resource.allowed_string_values =
::Google::Sql::Property::StringArray.api_parse(fetch['allowedStringValues'])
@current_resource.applies_to =
::Google::Sql::Property::StringArray.api_parse(fetch['appliesTo'])
@current_resource.max_value =
::Google::Sql::Property::Integer.api_parse(fetch['maxValue'])
@current_resource.min_value =
::Google::Sql::Property::Integer.api_parse(fetch['minValue'])
@current_resource.f_label = ::Google::Sql::Property::String.api_parse(fetch['name'])
@current_resource.requires_restart =
::Google::Sql::Property::Boolean.api_parse(fetch['requiresRestart'])
@current_resource.type = ::Google::Sql::Property::String.api_parse(fetch['type'])
update
end
end
- 1
action :delete do
fetch = fetch_wrapped_resource(@new_resource, 'sql#flag',
'sql#flagsList',
'items')
unless fetch.nil?
converge_by "Deleting gsql_flag[#{new_resource.name}]" do
delete_req = ::Google::Sql::Network::Delete.new(
self_link(@new_resource), fetch_auth(@new_resource)
)
return_if_object delete_req.send, 'sql#flag'
end
end
end
# TODO(nelsonjr): Add actions :manage and :modify
- 1
private
- 1
action_class do
- 1
def resource_to_request
request = {
kind: 'sql#flag',
name: new_resource.f_label
}.reject { |_, v| v.nil? }
request.to_json
end
- 1
def unwrap_resource_filter(resource)
self.class.unwrap_resource_filter(resource)
end
- 1
def self.unwrap_resource_filter(resource)
{
name: resource.f_label
}
end
- 1
def update
converge_if_changed do |_vars|
# TODO(nelsonjr): Determine how to print indented like upd converge
# TODO(nelsonjr): Check w/ Chef... can we print this in red?
puts # making a newline until we find a better way TODO: find!
compute_changes.each { |log| puts " - #{log.strip}\n" }
raise('Cloud SQL flag does not match expectations.')
end
end
- 1
def self.resource_to_hash(resource)
{
project: resource.project,
name: resource.f_label,
kind: 'sql#flag',
allowed_string_values: resource.allowed_string_values,
applies_to: resource.applies_to,
max_value: resource.max_value,
min_value: resource.min_value,
requires_restart: resource.requires_restart,
type: resource.type
}.reject { |_, v| v.nil? }
end
# Copied from Chef > Provider > #converge_if_changed
- 1
def compute_changes
properties = @new_resource.class.state_properties.map(&:name)
properties = properties.map(&:to_sym)
if current_resource
compute_changes_for_existing_resource properties
else
compute_changes_for_new_resource properties
end
end
# Collect the list of modified properties
- 1
def compute_changes_for_existing_resource(properties)
specified_properties = properties.select do |property|
@new_resource.property_is_set?(property)
end
modified = specified_properties.reject do |p|
@new_resource.send(p) == current_resource.send(p)
end
generate_pretty_green_text(modified)
end
- 1
def generate_pretty_green_text(modified)
property_size = modified.map(&:size).max
modified.map! do |p|
properties_str = if @new_resource.sensitive
'(suppressed sensitive property)'
else
[
@new_resource.send(p).inspect,
"(was #{current_resource.send(p).inspect})"
].join(' ')
end
" set #{p.to_s.ljust(property_size)} to #{properties_str}"
end
end
# Write down any properties we are setting.
- 1
def compute_changes_for_new_resource(properties)
property_size = properties.map(&:size).max
properties.map do |property|
default = ' (default value)' \
unless @new_resource.property_is_set?(property)
next if @new_resource.send(property).nil?
properties_str = if @new_resource.sensitive
'(suppressed sensitive property)'
else
@new_resource.send(property).inspect
end
[" set #{property.to_s.ljust(property_size)}",
"to #{properties_str}#{default}"].join(' ')
end.compact
end
- 1
def resource_to_query_predicate(resource)
self.class.resource_to_query_predicate(resource)
end
- 1
def self.resource_to_query_predicate(resource)
{
name: resource.name
}
end
- 1
def fetch_auth(resource)
self.class.fetch_auth(resource)
end
- 1
def self.fetch_auth(resource)
resource.resources("gauth_credential[#{resource.credential}]")
.authorization
end
- 1
def fetch_resource(resource, self_link, kind)
self.class.fetch_resource(resource, self_link, kind)
end
- 1
def debug(message)
Chef::Log.debug(message)
end
- 1
def self.collection(data)
URI.join(
'https://www.googleapis.com/sql/v1beta4/',
expand_variables(
'flags',
data
)
)
end
- 1
def collection(data)
self.class.collection(data)
end
- 1
def self.self_link(data)
URI.join(
'https://www.googleapis.com/sql/v1beta4/',
expand_variables(
'flags',
data
)
)
end
- 1
def self_link(data)
self.class.self_link(data)
end
# rubocop:disable Metrics/CyclomaticComplexity
- 1
def self.return_if_object(response, kind)
raise "Bad response: #{response.body}" \
if response.is_a?(Net::HTTPBadRequest)
raise "Bad response: #{response}" \
unless response.is_a?(Net::HTTPResponse)
return if response.is_a?(Net::HTTPNotFound)
return if response.is_a?(Net::HTTPNoContent)
result = JSON.parse(response.body)
raise_if_errors result, %w[error errors], 'message'
raise "Bad response: #{response}" unless response.is_a?(Net::HTTPOK)
raise "Incorrect result: #{result['kind']} (expected '#{kind}')" \
unless result['kind'] == kind
result
end
# rubocop:enable Metrics/CyclomaticComplexity
- 1
def return_if_object(response, kind)
self.class.return_if_object(response, kind)
end
- 1
def self.extract_variables(template)
template.scan(/{{[^}]*}}/).map { |v| v.gsub(/{{([^}]*)}}/, '\1') }
.map(&:to_sym)
end
- 1
def self.expand_variables(template, var_data, extra_data = {})
data = if var_data.class <= Hash
var_data.merge(extra_data)
else
resource_to_hash(var_data).merge(extra_data)
end
extract_variables(template).each do |v|
unless data.key?(v)
raise "Missing variable :#{v} in #{data} on #{caller.join("\n")}}"
end
template.gsub!(/{{#{v}}}/, CGI.escape(data[v].to_s))
end
template
end
- 1
def self.fetch_resource(resource, self_link, kind)
get_request = ::Google::Sql::Network::Get.new(
self_link, fetch_auth(resource)
)
return_if_object get_request.send, kind
end
- 1
def fetch_wrapped_resource(resource, kind, wrap_kind, wrap_path)
self.class.fetch_wrapped_resource(resource, kind, wrap_kind, wrap_path)
end
- 1
def self.fetch_wrapped_resource(resource, kind, wrap_kind, wrap_path)
result = fetch_resource(resource, self_link(resource), wrap_kind)
return if result.nil? || !result.key?(wrap_path)
result = unwrap_resource(result[wrap_path], resource)
return if result.nil?
raise "Incorrect result: #{result['kind']} (expected #{kind})" \
unless result['kind'] == kind
result
end
- 1
def unwrap_resource(result, resource)
self.class.unwrap_resource(result, resource)
end
- 1
def self.unwrap_resource(result, resource)
query_predicate = unwrap_resource_filter(resource)
matches = result.select do |entry|
query_predicate.all? do |k, v|
entry[k.id2name] == v
end
end
raise "More than 1 result found: #{matches}" if matches.size > 1
return if matches.empty?
matches.first
end
- 1
def self.raise_if_errors(response, err_path, msg_field)
errors = ::Google::HashUtils.navigate(response, err_path)
raise_error(errors, msg_field) unless errors.nil?
end
- 1
def self.raise_error(errors, msg_field)
raise IOError, ['Operation failed:',
errors.map { |e| e[msg_field] }.join(', ')].join(' ')
end
end
end
# rubocop:enable Metrics/ClassLength
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
# Add our google/ lib
- 1
$LOAD_PATH.unshift ::File.expand_path('../libraries', ::File.dirname(__FILE__))
- 1
require 'chef/resource'
- 1
require 'google/hash_utils'
- 1
require 'google/sql/network/delete'
- 1
require 'google/sql/network/get'
- 1
require 'google/sql/network/post'
- 1
require 'google/sql/network/put'
- 1
require 'google/sql/property/boolean'
- 1
require 'google/sql/property/enum'
- 1
require 'google/sql/property/instance_authorized_networks'
- 1
require 'google/sql/property/instance_failover_replica'
- 1
require 'google/sql/property/instance_ip_addresses'
- 1
require 'google/sql/property/instance_ip_configuration'
- 1
require 'google/sql/property/instance_mysql_replica_configuration'
- 1
require 'google/sql/property/instance_replica_configuration'
- 1
require 'google/sql/property/instance_settings'
- 1
require 'google/sql/property/integer'
- 1
require 'google/sql/property/string'
- 1
require 'google/sql/property/string_array'
- 1
require 'google/sql/property/time'
- 1
module Google
- 1
module GSQL
# A provider to manage Google Cloud SQL resources.
# rubocop:disable Metrics/ClassLength
- 1
class Instance < Chef::Resource
- 1
resource_name :gsql_instance
- 1
property :backend_type,
equal_to: %w[FIRST_GEN SECOND_GEN EXTERNAL],
coerce: ::Google::Sql::Property::Enum.coerce, desired_state: true
- 1
property :connection_name,
String, coerce: ::Google::Sql::Property::String.coerce, desired_state: true
- 1
property :database_version,
equal_to: %w[MYSQL_5_5 MYSQL_5_6 MYSQL_5_7 POSTGRES_9_6],
coerce: ::Google::Sql::Property::Enum.coerce, desired_state: true
- 1
property :failover_replica,
[Hash, ::Google::Sql::Data::InstanceFailoverReplica],
coerce: ::Google::Sql::Property::InstanceFailoverReplica.coerce, desired_state: true
- 1
property :instance_type,
equal_to: %w[CLOUD_SQL_INSTANCE ON_PREMISES_INSTANCE READ_REPLICA_INSTANCE],
coerce: ::Google::Sql::Property::Enum.coerce, desired_state: true
# ip_addresses is Array of Google::Sql::Property::InstanceIpAddressesArray
- 1
property :ip_addresses,
Array,
coerce: ::Google::Sql::Property::InstanceIpAddressesArray.coerce, desired_state: true
- 1
property :ipv6_address,
String, coerce: ::Google::Sql::Property::String.coerce, desired_state: true
- 1
property :master_instance_name,
String, coerce: ::Google::Sql::Property::String.coerce, desired_state: true
- 1
property :max_disk_size,
Integer, coerce: ::Google::Sql::Property::Integer.coerce, desired_state: true
- 1
property :i_label,
String,
coerce: ::Google::Sql::Property::String.coerce,
name_property: true, desired_state: true
- 1
property :region, String, coerce: ::Google::Sql::Property::String.coerce, desired_state: true
- 1
property :replica_configuration,
[Hash, ::Google::Sql::Data::InstanceReplicaConfiguration],
coerce: ::Google::Sql::Property::InstanceReplicaConfiguration.coerce,
desired_state: true
- 1
property :settings,
[Hash, ::Google::Sql::Data::InstanceSettings],
coerce: ::Google::Sql::Property::InstanceSettings.coerce, desired_state: true
- 1
property :credential, String, desired_state: false, required: true
- 1
property :project, String, desired_state: false, required: true
- 1
action :create do
fetch = fetch_resource(@new_resource, self_link(@new_resource),
'sql#instance')
if fetch.nil?
converge_by "Creating gsql_instance[#{new_resource.name}]" do
# TODO(nelsonjr): Show a list of variables to create
# TODO(nelsonjr): Determine how to print green like update converge
puts # making a newline until we find a better way TODO: find!
compute_changes.each { |log| puts " - #{log.strip}\n" }
create_req = ::Google::Sql::Network::Post.new(
collection(@new_resource), fetch_auth(@new_resource),
'application/json', resource_to_request
)
wait_for_operation create_req.send, @new_resource
end
else
@current_resource = @new_resource.clone
@current_resource.backend_type =
::Google::Sql::Property::Enum.api_parse(fetch['backendType'])
@current_resource.connection_name =
::Google::Sql::Property::String.api_parse(fetch['connectionName'])
@current_resource.database_version =
::Google::Sql::Property::Enum.api_parse(fetch['databaseVersion'])
@current_resource.failover_replica =
::Google::Sql::Property::InstanceFailoverReplica.api_parse(fetch['failoverReplica'])
@current_resource.instance_type =
::Google::Sql::Property::Enum.api_parse(fetch['instanceType'])
@current_resource.ip_addresses =
::Google::Sql::Property::InstanceIpAddressesArray.api_parse(fetch['ipAddresses'])
@current_resource.ipv6_address =
::Google::Sql::Property::String.api_parse(fetch['ipv6Address'])
@current_resource.master_instance_name =
::Google::Sql::Property::String.api_parse(fetch['masterInstanceName'])
@current_resource.max_disk_size =
::Google::Sql::Property::Integer.api_parse(fetch['maxDiskSize'])
@current_resource.i_label = ::Google::Sql::Property::String.api_parse(fetch['name'])
@current_resource.region = ::Google::Sql::Property::String.api_parse(fetch['region'])
@current_resource.replica_configuration =
::Google::Sql::Property::InstanceReplicaConfiguration.api_parse(
fetch['replicaConfiguration']
)
@current_resource.settings =
::Google::Sql::Property::InstanceSettings.api_parse(fetch['settings'])
update
end
end
- 1
action :delete do
fetch = fetch_resource(@new_resource, self_link(@new_resource),
'sql#instance')
unless fetch.nil?
converge_by "Deleting gsql_instance[#{new_resource.name}]" do
delete_req = ::Google::Sql::Network::Delete.new(
self_link(@new_resource), fetch_auth(@new_resource)
)
wait_for_operation delete_req.send, @new_resource
end
end
end
# TODO(nelsonjr): Add actions :manage and :modify
- 1
def exports
{
name: i_label
}
end
- 1
private
- 1
action_class do
# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/MethodLength
- 1
def resource_to_request
request = {
kind: 'sql#instance',
backendType: new_resource.backend_type,
connectionName: new_resource.connection_name,
databaseVersion: new_resource.database_version,
failoverReplica: new_resource.failover_replica,
instanceType: new_resource.instance_type,
ipv6Address: new_resource.ipv6_address,
masterInstanceName: new_resource.master_instance_name,
maxDiskSize: new_resource.max_disk_size,
name: new_resource.i_label,
region: new_resource.region,
replicaConfiguration: new_resource.replica_configuration,
settings: new_resource.settings
}.reject { |_, v| v.nil? }
unless @current_resource.nil?
# Convert to pure JSON
request = JSON.parse(request.to_json)
request['settings']['settingsVersion'] =
@current_resource.settings.settings_version
end
request.to_json
end
# rubocop:enable Metrics/MethodLength
# rubocop:enable Metrics/AbcSize
- 1
def update
converge_if_changed do |_vars|
# TODO(nelsonjr): Determine how to print indented like upd converge
# TODO(nelsonjr): Check w/ Chef... can we print this in red?
puts # making a newline until we find a better way TODO: find!
compute_changes.each { |log| puts " - #{log.strip}\n" }
update_req =
::Google::Sql::Network::Put.new(self_link(@new_resource),
fetch_auth(@new_resource),
'application/json',
resource_to_request)
wait_for_operation update_req.send, @new_resource
end
end
# rubocop:disable Metrics/MethodLength
- 1
def self.resource_to_hash(resource)
{
project: resource.project,
name: resource.i_label,
kind: 'sql#instance',
backend_type: resource.backend_type,
connection_name: resource.connection_name,
database_version: resource.database_version,
failover_replica: resource.failover_replica,
instance_type: resource.instance_type,
ip_addresses: resource.ip_addresses,
ipv6_address: resource.ipv6_address,
master_instance_name: resource.master_instance_name,
max_disk_size: resource.max_disk_size,
region: resource.region,
replica_configuration: resource.replica_configuration,
settings: resource.settings
}.reject { |_, v| v.nil? }
end
# rubocop:enable Metrics/MethodLength
# Copied from Chef > Provider > #converge_if_changed
- 1
def compute_changes
properties = @new_resource.class.state_properties.map(&:name)
properties = properties.map(&:to_sym)
if current_resource
compute_changes_for_existing_resource properties
else
compute_changes_for_new_resource properties
end
end
# Collect the list of modified properties
- 1
def compute_changes_for_existing_resource(properties)
specified_properties = properties.select do |property|
@new_resource.property_is_set?(property)
end
modified = specified_properties.reject do |p|
@new_resource.send(p) == current_resource.send(p)
end
generate_pretty_green_text(modified)
end
- 1
def generate_pretty_green_text(modified)
property_size = modified.map(&:size).max
modified.map! do |p|
properties_str = if @new_resource.sensitive
'(suppressed sensitive property)'
else
[
@new_resource.send(p).inspect,
"(was #{current_resource.send(p).inspect})"
].join(' ')
end
" set #{p.to_s.ljust(property_size)} to #{properties_str}"
end
end
# Write down any properties we are setting.
- 1
def compute_changes_for_new_resource(properties)
property_size = properties.map(&:size).max
properties.map do |property|
default = ' (default value)' \
unless @new_resource.property_is_set?(property)
next if @new_resource.send(property).nil?
properties_str = if @new_resource.sensitive
'(suppressed sensitive property)'
else
@new_resource.send(property).inspect
end
[" set #{property.to_s.ljust(property_size)}",
"to #{properties_str}#{default}"].join(' ')
end.compact
end
- 1
def fetch_auth(resource)
self.class.fetch_auth(resource)
end
- 1
def self.fetch_auth(resource)
resource.resources("gauth_credential[#{resource.credential}]")
.authorization
end
- 1
def fetch_resource(resource, self_link, kind)
self.class.fetch_resource(resource, self_link, kind)
end
- 1
def debug(message)
Chef::Log.debug(message)
end
- 1
def self.collection(data)
URI.join(
'https://www.googleapis.com/sql/v1beta4/',
expand_variables(
'projects/{{project}}/instances',
data
)
)
end
- 1
def collection(data)
self.class.collection(data)
end
- 1
def self.self_link(data)
URI.join(
'https://www.googleapis.com/sql/v1beta4/',
expand_variables(
'projects/{{project}}/instances/{{name}}',
data
)
)
end
- 1
def self_link(data)
self.class.self_link(data)
end
# rubocop:disable Metrics/CyclomaticComplexity
- 1
def self.return_if_object(response, kind)
raise "Bad response: #{response}" \
unless response.is_a?(Net::HTTPResponse)
return if response.is_a?(Net::HTTPNotFound)
return if response.is_a?(Net::HTTPNoContent)
# TODO(nelsonjr): Remove return of Net::HTTPForbidden from
# return_if_object once Cloud SQL bug http://b/62635365 is resolved.
# Currently the API returns 403 for objects that do not exist, even
# when the user has access to the project. This is being changed to
# return 404 as it is supposed to be.
# Once 404 is the correct response, the temporary workaround should
# be removed.
return if response.is_a?(Net::HTTPForbidden)
result = JSON.parse(response.body)
raise_if_errors result, %w[error errors], 'message'
raise "Bad response: #{response}" unless response.is_a?(Net::HTTPOK)
raise "Incorrect result: #{result['kind']} (expecting #{kind})" \
unless result['kind'] == kind
result
end
# rubocop:enable Metrics/CyclomaticComplexity
- 1
def return_if_object(response, kind)
self.class.return_if_object(response, kind)
end
- 1
def self.extract_variables(template)
- 1172
template.scan(/{{[^}]*}}/).map { |v| v.gsub(/{{([^}]*)}}/, '\1') }
- 606
.map(&:to_sym)
end
- 1
def self.expand_variables(template, var_data, extra_data = {})
- 606
data = if var_data.class <= Hash
- 606
var_data.merge(extra_data)
else
resource_to_hash(var_data).merge(extra_data)
end
- 606
extract_variables(template).each do |v|
- 1172
unless data.key?(v)
raise "Missing variable :#{v} in #{data} on #{caller.join("\n")}}"
end
- 1172
template.gsub!(/{{#{v}}}/, CGI.escape(data[v].to_s))
end
- 606
template
end
- 1
def expand_variables(template, var_data, extra_data = {})
self.class.expand_variables(template, var_data, extra_data)
end
- 1
def fetch_resource(resource, self_link, kind)
self.class.fetch_resource(resource, self_link, kind)
end
- 1
def async_op_url(data, extra_data = {})
URI.join(
'https://www.googleapis.com/sql/v1beta4/',
expand_variables(
'projects/{{project}}/operations/{{op_id}}',
data, extra_data
)
)
end
- 1
def wait_for_operation(response, resource)
op_result = return_if_object(response, 'sql#operation')
return if op_result.nil?
status = ::Google::HashUtils.navigate(op_result, %w[status])
fetch_resource(
resource,
URI.parse(::Google::HashUtils.navigate(wait_for_completion(status,
op_result,
resource),
%w[targetLink])),
'sql#instance'
)
end
- 1
def wait_for_completion(status, op_result, resource)
op_id = ::Google::HashUtils.navigate(op_result, %w[name])
op_uri = async_op_url(resource, op_id: op_id)
while status != 'DONE'
debug("Waiting for completion of operation #{op_id}")
raise_if_errors op_result, %w[error errors], 'message'
sleep 1.0
raise "Invalid result '#{status}' on gsql_instance." \
unless %w[PENDING RUNNING DONE].include?(status)
op_result = fetch_resource(resource, op_uri, 'sql#operation')
status = ::Google::HashUtils.navigate(op_result, %w[status])
end
op_result
end
- 1
def raise_if_errors(response, err_path, msg_field)
self.class.raise_if_errors(response, err_path, msg_field)
end
- 1
def self.fetch_resource(resource, self_link, kind)
get_request = ::Google::Sql::Network::Get.new(
self_link, fetch_auth(resource)
)
return_if_object get_request.send, kind
end
- 1
def self.raise_if_errors(response, err_path, msg_field)
errors = ::Google::HashUtils.navigate(response, err_path)
raise_error(errors, msg_field) unless errors.nil?
end
- 1
def self.raise_error(errors, msg_field)
raise IOError, ['Operation failed:',
errors.map { |e| e[msg_field] }.join(', ')].join(' ')
end
end
end
# rubocop:enable Metrics/ClassLength
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
# Add our google/ lib
- 1
$LOAD_PATH.unshift ::File.expand_path('../libraries', ::File.dirname(__FILE__))
- 1
require 'chef/resource'
- 1
require 'google/hash_utils'
- 1
require 'google/sql/network/get'
- 1
require 'google/sql/property/instance_name'
- 1
require 'google/sql/property/string'
- 1
require 'google/sql/property/time'
- 1
module Google
- 1
module GSQL
# A provider to manage Google Cloud SQL resources.
# rubocop:disable Metrics/ClassLength
- 1
class SslCert < Chef::Resource
- 1
resource_name :gsql_ssl_cert
- 1
property :cert, String, coerce: ::Google::Sql::Property::String.coerce, desired_state: true
- 1
property :cert_serial_number,
String, coerce: ::Google::Sql::Property::String.coerce, desired_state: true
- 1
property :common_name,
String, coerce: ::Google::Sql::Property::String.coerce, desired_state: true
- 1
property :create_time, Time, coerce: ::Google::Sql::Property::Time.coerce, desired_state: true
- 1
property :expiration_time,
Time, coerce: ::Google::Sql::Property::Time.coerce, desired_state: true
- 1
property :instance,
[String, ::Google::Sql::Data::InstanceNameRef],
coerce: ::Google::Sql::Property::InstanceNameRef.coerce, desired_state: true
- 1
property :sha1_fingerprint,
String, coerce: ::Google::Sql::Property::String.coerce, desired_state: true
- 1
property :credential, String, desired_state: false, required: true
- 1
property :project, String, desired_state: false, required: true
- 1
action :create do
Chef.deprecated(:generic,
["gsql_ssl_cert has been deprecated.",
"Please use the SslCert Name instead."
].join(" "))
fetch = fetch_resource(@new_resource, self_link(@new_resource),
'sql#sslCert')
if fetch.nil?
converge_by "Creating gsql_ssl_cert[#{new_resource.name}]" do
# TODO(nelsonjr): Show a list of variables to create
# TODO(nelsonjr): Determine how to print green like update converge
puts # making a newline until we find a better way TODO: find!
compute_changes.each { |log| puts " - #{log.strip}\n" }
create_req = ::Google::Sql::Network::Post.new(
collection(@new_resource), fetch_auth(@new_resource),
'application/json', resource_to_request
)
return_if_object create_req.send, 'sql#sslCert'
end
else
@current_resource = @new_resource.clone
@current_resource.cert = ::Google::Sql::Property::String.api_parse(fetch['cert'])
@current_resource.cert_serial_number =
::Google::Sql::Property::String.api_parse(fetch['certSerialNumber'])
@current_resource.common_name =
::Google::Sql::Property::String.api_parse(fetch['commonName'])
@current_resource.create_time =
::Google::Sql::Property::Time.api_parse(fetch['createTime'])
@current_resource.expiration_time =
::Google::Sql::Property::Time.api_parse(fetch['expirationTime'])
update
end
end
- 1
action :delete do
fetch = fetch_resource(@new_resource, self_link(@new_resource),
'sql#sslCert')
unless fetch.nil?
converge_by "Deleting gsql_ssl_cert[#{new_resource.name}]" do
delete_req = ::Google::Sql::Network::Delete.new(
self_link(@new_resource), fetch_auth(@new_resource)
)
return_if_object delete_req.send, 'sql#sslCert'
end
end
end
# TODO(nelsonjr): Add actions :manage and :modify
- 1
private
- 1
action_class do
- 1
def resource_to_request
request = {
kind: 'sql#sslCert',
cert: new_resource.cert,
certSerialNumber: new_resource.cert_serial_number,
commonName: new_resource.common_name,
createTime: new_resource.create_time,
expirationTime: new_resource.expiration_time
}.reject { |_, v| v.nil? }
request.to_json
end
- 1
def update
converge_if_changed do |_vars|
# TODO(nelsonjr): Determine how to print indented like upd converge
# TODO(nelsonjr): Check w/ Chef... can we print this in red?
puts # making a newline until we find a better way TODO: find!
compute_changes.each { |log| puts " - #{log.strip}\n" }
raise('Cloud SQL SSL certificate mismatch.')
end
end
- 1
def self.fetch_export(resource, type, id, property)
return if id.nil?
resource.resources("#{type}[#{id}]").exports[property]
end
- 1
def self.resource_to_hash(resource)
{
project: resource.project,
name: resource.name,
kind: 'sql#sslCert',
cert: resource.cert,
cert_serial_number: resource.cert_serial_number,
common_name: resource.common_name,
create_time: resource.create_time,
expiration_time: resource.expiration_time,
instance: resource.instance,
sha1_fingerprint: resource.sha1_fingerprint
}.reject { |_, v| v.nil? }
end
# Copied from Chef > Provider > #converge_if_changed
- 1
def compute_changes
properties = @new_resource.class.state_properties.map(&:name)
properties = properties.map(&:to_sym)
if current_resource
compute_changes_for_existing_resource properties
else
compute_changes_for_new_resource properties
end
end
# Collect the list of modified properties
- 1
def compute_changes_for_existing_resource(properties)
specified_properties = properties.select do |property|
@new_resource.property_is_set?(property)
end
modified = specified_properties.reject do |p|
@new_resource.send(p) == current_resource.send(p)
end
generate_pretty_green_text(modified)
end
- 1
def generate_pretty_green_text(modified)
property_size = modified.map(&:size).max
modified.map! do |p|
properties_str = if @new_resource.sensitive
'(suppressed sensitive property)'
else
[
@new_resource.send(p).inspect,
"(was #{current_resource.send(p).inspect})"
].join(' ')
end
" set #{p.to_s.ljust(property_size)} to #{properties_str}"
end
end
# Write down any properties we are setting.
- 1
def compute_changes_for_new_resource(properties)
property_size = properties.map(&:size).max
properties.map do |property|
default = ' (default value)' \
unless @new_resource.property_is_set?(property)
next if @new_resource.send(property).nil?
properties_str = if @new_resource.sensitive
'(suppressed sensitive property)'
else
@new_resource.send(property).inspect
end
[" set #{property.to_s.ljust(property_size)}",
"to #{properties_str}#{default}"].join(' ')
end.compact
end
- 1
def fetch_auth(resource)
self.class.fetch_auth(resource)
end
- 1
def self.fetch_auth(resource)
resource.resources("gauth_credential[#{resource.credential}]")
.authorization
end
- 1
def fetch_resource(resource, self_link, kind)
self.class.fetch_resource(resource, self_link, kind)
end
- 1
def debug(message)
Chef::Log.debug(message)
end
- 1
def self.collection(data)
URI.join(
'https://www.googleapis.com/sql/v1beta4/',
expand_variables(
'projects/{{project}}/instances/{{instance}}/sslCerts',
data
)
)
end
- 1
def collection(data)
self.class.collection(data)
end
- 1
def self.self_link(data)
URI.join(
'https://www.googleapis.com/sql/v1beta4/',
expand_variables(
[
'projects/{{project}}/instances/{{instance}}/sslCerts/',
'{{sha1_fingerprint}}'
].join,
data
)
)
end
- 1
def self_link(data)
self.class.self_link(data)
end
# rubocop:disable Metrics/CyclomaticComplexity
- 1
def self.return_if_object(response, kind)
raise "Bad response: #{response.body}" \
if response.is_a?(Net::HTTPBadRequest)
raise "Bad response: #{response}" \
unless response.is_a?(Net::HTTPResponse)
return if response.is_a?(Net::HTTPNotFound)
return if response.is_a?(Net::HTTPNoContent)
result = JSON.parse(response.body)
raise_if_errors result, %w[error errors], 'message'
raise "Bad response: #{response}" unless response.is_a?(Net::HTTPOK)
raise "Incorrect result: #{result['kind']} (expected '#{kind}')" \
unless result['kind'] == kind
result
end
# rubocop:enable Metrics/CyclomaticComplexity
- 1
def return_if_object(response, kind)
self.class.return_if_object(response, kind)
end
- 1
def self.extract_variables(template)
template.scan(/{{[^}]*}}/).map { |v| v.gsub(/{{([^}]*)}}/, '\1') }
.map(&:to_sym)
end
- 1
def self.expand_variables(template, var_data, extra_data = {})
data = if var_data.class <= Hash
var_data.merge(extra_data)
else
resource_to_hash(var_data).merge(extra_data)
end
extract_variables(template).each do |v|
unless data.key?(v)
raise "Missing variable :#{v} in #{data} on #{caller.join("\n")}}"
end
template.gsub!(/{{#{v}}}/, CGI.escape(data[v].to_s))
end
template
end
- 1
def self.fetch_resource(resource, self_link, kind)
get_request = ::Google::Sql::Network::Get.new(
self_link, fetch_auth(resource)
)
return_if_object get_request.send, kind
end
- 1
def self.raise_if_errors(response, err_path, msg_field)
errors = ::Google::HashUtils.navigate(response, err_path)
raise_error(errors, msg_field) unless errors.nil?
end
- 1
def self.raise_error(errors, msg_field)
raise IOError, ['Operation failed:',
errors.map { |e| e[msg_field] }.join(', ')].join(' ')
end
end
end
# rubocop:enable Metrics/ClassLength
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
# Add our google/ lib
- 1
$LOAD_PATH.unshift ::File.expand_path('../libraries', ::File.dirname(__FILE__))
- 1
require 'chef/resource'
- 1
require 'google/hash_utils'
- 1
require 'google/sql/network/get'
- 1
require 'google/sql/property/integer'
- 1
require 'google/sql/property/string'
- 1
require 'google/sql/property/string_array'
- 1
module Google
- 1
module GSQL
# A provider to manage Google Cloud SQL resources.
# rubocop:disable Metrics/ClassLength
- 1
class Tier < Chef::Resource
- 1
resource_name :gsql_tier
- 1
property :disk_quota,
Integer, coerce: ::Google::Sql::Property::Integer.coerce, desired_state: true
- 1
property :ram, Integer, coerce: ::Google::Sql::Property::Integer.coerce, desired_state: true
# region is Array of Google::Sql::Property::StringArray
- 1
property :region,
Array, coerce: ::Google::Sql::Property::StringArray.coerce, desired_state: true
- 1
property :tier, String, coerce: ::Google::Sql::Property::String.coerce, desired_state: true
- 1
property :credential, String, desired_state: false, required: true
- 1
property :project, String, desired_state: false, required: true
- 1
action :create do
Chef.deprecated(:generic,
["gsql_tier has been deprecated.",
"Please use the Tier Name instead."
].join(" "))
fetch = fetch_wrapped_resource(@new_resource, 'sql#tier',
'sql#tiersList',
'items')
if fetch.nil?
converge_by "Creating gsql_tier[#{new_resource.name}]" do
# TODO(nelsonjr): Show a list of variables to create
# TODO(nelsonjr): Determine how to print green like update converge
puts # making a newline until we find a better way TODO: find!
compute_changes.each { |log| puts " - #{log.strip}\n" }
create_req = ::Google::Sql::Network::Post.new(
collection(@new_resource), fetch_auth(@new_resource),
'application/json', resource_to_request
)
return_if_object create_req.send, 'sql#tier'
end
else
@current_resource = @new_resource.clone
@current_resource.disk_quota =
::Google::Sql::Property::Integer.api_parse(fetch['DiskQuota'])
@current_resource.ram = ::Google::Sql::Property::Integer.api_parse(fetch['RAM'])
@current_resource.region =
::Google::Sql::Property::StringArray.api_parse(fetch['region'])
update
end
end
- 1
action :delete do
fetch = fetch_wrapped_resource(@new_resource, 'sql#tier',
'sql#tiersList',
'items')
unless fetch.nil?
converge_by "Deleting gsql_tier[#{new_resource.name}]" do
delete_req = ::Google::Sql::Network::Delete.new(
self_link(@new_resource), fetch_auth(@new_resource)
)
return_if_object delete_req.send, 'sql#tier'
end
end
end
# TODO(nelsonjr): Add actions :manage and :modify
- 1
private
- 1
action_class do
- 1
def resource_to_request
request = {
kind: 'sql#tier'
}.reject { |_, v| v.nil? }
request.to_json
end
- 1
def unwrap_resource_filter(resource)
self.class.unwrap_resource_filter(resource)
end
- 1
def self.unwrap_resource_filter(resource)
{
tier: resource.tier
}
end
- 1
def update
converge_if_changed do |_vars|
# TODO(nelsonjr): Determine how to print indented like upd converge
# TODO(nelsonjr): Check w/ Chef... can we print this in red?
puts # making a newline until we find a better way TODO: find!
compute_changes.each { |log| puts " - #{log.strip}\n" }
raise('Cloud SQL tier does not match expectations.')
end
end
- 1
def self.resource_to_hash(resource)
{
project: resource.project,
name: resource.name,
kind: 'sql#tier',
disk_quota: resource.disk_quota,
ram: resource.ram,
region: resource.region,
tier: resource.tier
}.reject { |_, v| v.nil? }
end
# Copied from Chef > Provider > #converge_if_changed
- 1
def compute_changes
properties = @new_resource.class.state_properties.map(&:name)
properties = properties.map(&:to_sym)
if current_resource
compute_changes_for_existing_resource properties
else
compute_changes_for_new_resource properties
end
end
# Collect the list of modified properties
- 1
def compute_changes_for_existing_resource(properties)
specified_properties = properties.select do |property|
@new_resource.property_is_set?(property)
end
modified = specified_properties.reject do |p|
@new_resource.send(p) == current_resource.send(p)
end
generate_pretty_green_text(modified)
end
- 1
def generate_pretty_green_text(modified)
property_size = modified.map(&:size).max
modified.map! do |p|
properties_str = if @new_resource.sensitive
'(suppressed sensitive property)'
else
[
@new_resource.send(p).inspect,
"(was #{current_resource.send(p).inspect})"
].join(' ')
end
" set #{p.to_s.ljust(property_size)} to #{properties_str}"
end
end
# Write down any properties we are setting.
- 1
def compute_changes_for_new_resource(properties)
property_size = properties.map(&:size).max
properties.map do |property|
default = ' (default value)' \
unless @new_resource.property_is_set?(property)
next if @new_resource.send(property).nil?
properties_str = if @new_resource.sensitive
'(suppressed sensitive property)'
else
@new_resource.send(property).inspect
end
[" set #{property.to_s.ljust(property_size)}",
"to #{properties_str}#{default}"].join(' ')
end.compact
end
- 1
def resource_to_query_predicate(resource)
self.class.resource_to_query_predicate(resource)
end
- 1
def self.resource_to_query_predicate(resource)
{
tier: resource.tier
}
end
- 1
def fetch_auth(resource)
self.class.fetch_auth(resource)
end
- 1
def self.fetch_auth(resource)
resource.resources("gauth_credential[#{resource.credential}]")
.authorization
end
- 1
def fetch_resource(resource, self_link, kind)
self.class.fetch_resource(resource, self_link, kind)
end
- 1
def debug(message)
Chef::Log.debug(message)
end
- 1
def self.collection(data)
URI.join(
'https://www.googleapis.com/sql/v1beta4/',
expand_variables(
'projects/{{project}}/tiers',
data
)
)
end
- 1
def collection(data)
self.class.collection(data)
end
- 1
def self.self_link(data)
URI.join(
'https://www.googleapis.com/sql/v1beta4/',
expand_variables(
'projects/{{project}}/tiers',
data
)
)
end
- 1
def self_link(data)
self.class.self_link(data)
end
# rubocop:disable Metrics/CyclomaticComplexity
- 1
def self.return_if_object(response, kind)
raise "Bad response: #{response.body}" \
if response.is_a?(Net::HTTPBadRequest)
raise "Bad response: #{response}" \
unless response.is_a?(Net::HTTPResponse)
return if response.is_a?(Net::HTTPNotFound)
return if response.is_a?(Net::HTTPNoContent)
result = JSON.parse(response.body)
raise_if_errors result, %w[error errors], 'message'
raise "Bad response: #{response}" unless response.is_a?(Net::HTTPOK)
raise "Incorrect result: #{result['kind']} (expected '#{kind}')" \
unless result['kind'] == kind
result
end
# rubocop:enable Metrics/CyclomaticComplexity
- 1
def return_if_object(response, kind)
self.class.return_if_object(response, kind)
end
- 1
def self.extract_variables(template)
template.scan(/{{[^}]*}}/).map { |v| v.gsub(/{{([^}]*)}}/, '\1') }
.map(&:to_sym)
end
- 1
def self.expand_variables(template, var_data, extra_data = {})
data = if var_data.class <= Hash
var_data.merge(extra_data)
else
resource_to_hash(var_data).merge(extra_data)
end
extract_variables(template).each do |v|
unless data.key?(v)
raise "Missing variable :#{v} in #{data} on #{caller.join("\n")}}"
end
template.gsub!(/{{#{v}}}/, CGI.escape(data[v].to_s))
end
template
end
- 1
def self.fetch_resource(resource, self_link, kind)
get_request = ::Google::Sql::Network::Get.new(
self_link, fetch_auth(resource)
)
return_if_object get_request.send, kind
end
- 1
def fetch_wrapped_resource(resource, kind, wrap_kind, wrap_path)
self.class.fetch_wrapped_resource(resource, kind, wrap_kind, wrap_path)
end
- 1
def self.fetch_wrapped_resource(resource, kind, wrap_kind, wrap_path)
result = fetch_resource(resource, self_link(resource), wrap_kind)
return if result.nil? || !result.key?(wrap_path)
result = unwrap_resource(result[wrap_path], resource)
return if result.nil?
raise "Incorrect result: #{result['kind']} (expected #{kind})" \
unless result['kind'] == kind
result
end
- 1
def unwrap_resource(result, resource)
self.class.unwrap_resource(result, resource)
end
- 1
def self.unwrap_resource(result, resource)
query_predicate = unwrap_resource_filter(resource)
matches = result.select do |entry|
query_predicate.all? do |k, v|
entry[k.id2name] == v
end
end
raise "More than 1 result found: #{matches}" if matches.size > 1
return if matches.empty?
matches.first
end
- 1
def self.raise_if_errors(response, err_path, msg_field)
errors = ::Google::HashUtils.navigate(response, err_path)
raise_error(errors, msg_field) unless errors.nil?
end
- 1
def self.raise_error(errors, msg_field)
raise IOError, ['Operation failed:',
errors.map { |e| e[msg_field] }.join(', ')].join(' ')
end
end
end
# rubocop:enable Metrics/ClassLength
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
# Add our google/ lib
- 1
$LOAD_PATH.unshift ::File.expand_path('../libraries', ::File.dirname(__FILE__))
- 1
require 'chef/resource'
- 1
require 'google/hash_utils'
- 1
require 'google/sql/network/delete'
- 1
require 'google/sql/network/get'
- 1
require 'google/sql/network/post'
- 1
require 'google/sql/network/put'
- 1
require 'google/sql/property/instance_name'
- 1
require 'google/sql/property/string'
- 1
module Google
- 1
module GSQL
# A provider to manage Google Cloud SQL resources.
# rubocop:disable Metrics/ClassLength
- 1
class User < Chef::Resource
- 1
resource_name :gsql_user
- 1
property :host, String, coerce: ::Google::Sql::Property::String.coerce, desired_state: true
- 1
property :u_label,
String,
coerce: ::Google::Sql::Property::String.coerce,
name_property: true, desired_state: true
- 1
property :instance,
[String, ::Google::Sql::Data::InstanceNameRef],
coerce: ::Google::Sql::Property::InstanceNameRef.coerce, desired_state: true
- 1
property :password,
String, coerce: ::Google::Sql::Property::String.coerce, desired_state: true
- 1
property :credential, String, desired_state: false, required: true
- 1
property :project, String, desired_state: false, required: true
- 1
action :create do
fetch = fetch_wrapped_resource(@new_resource, 'sql#user',
'sql#usersList',
'items')
if fetch.nil?
converge_by "Creating gsql_user[#{new_resource.name}]" do
# TODO(nelsonjr): Show a list of variables to create
# TODO(nelsonjr): Determine how to print green like update converge
puts # making a newline until we find a better way TODO: find!
compute_changes.each { |log| puts " - #{log.strip}\n" }
create_req = ::Google::Sql::Network::Post.new(
collection(@new_resource), fetch_auth(@new_resource),
'application/json', resource_to_request
)
wait_for_operation create_req.send, @new_resource
end
else
@current_resource = @new_resource.clone
@current_resource.host = ::Google::Sql::Property::String.api_parse(fetch['host'])
@current_resource.u_label = ::Google::Sql::Property::String.api_parse(fetch['name'])
update
end
end
- 1
action :delete do
fetch = fetch_wrapped_resource(@new_resource, 'sql#user',
'sql#usersList',
'items')
unless fetch.nil?
converge_by "Deleting gsql_user[#{new_resource.name}]" do
delete_req = ::Google::Sql::Network::Delete.new(
self_link(@new_resource), fetch_auth(@new_resource)
)
wait_for_operation delete_req.send, @new_resource
end
end
end
# TODO(nelsonjr): Add actions :manage and :modify
- 1
private
- 1
action_class do
- 1
def resource_to_request
request = {
kind: 'sql#user',
host: new_resource.host,
name: new_resource.u_label,
password: new_resource.password
}.reject { |_, v| v.nil? }
request.to_json
end
- 1
def unwrap_resource_filter(resource)
self.class.unwrap_resource_filter(resource)
end
- 1
def self.unwrap_resource_filter(resource)
{
host: resource.host,
name: resource.u_label
}
end
- 1
def update
converge_if_changed do |_vars|
# TODO(nelsonjr): Determine how to print indented like upd converge
# TODO(nelsonjr): Check w/ Chef... can we print this in red?
puts # making a newline until we find a better way TODO: find!
compute_changes.each { |log| puts " - #{log.strip}\n" }
update_req =
::Google::Sql::Network::Put.new(self_link(@new_resource),
fetch_auth(@new_resource),
'application/json',
resource_to_request)
wait_for_operation update_req.send, @new_resource
end
end
- 1
def self.fetch_export(resource, type, id, property)
return if id.nil?
resource.resources("#{type}[#{id}]").exports[property]
end
- 1
def self.resource_to_hash(resource)
{
project: resource.project,
name: resource.u_label,
kind: 'sql#user',
host: resource.host,
instance: resource.instance,
password: resource.password
}.reject { |_, v| v.nil? }
end
# Copied from Chef > Provider > #converge_if_changed
- 1
def compute_changes
properties = @new_resource.class.state_properties.map(&:name)
properties = properties.map(&:to_sym)
if current_resource
compute_changes_for_existing_resource properties
else
compute_changes_for_new_resource properties
end
end
# Collect the list of modified properties
- 1
def compute_changes_for_existing_resource(properties)
specified_properties = properties.select do |property|
@new_resource.property_is_set?(property)
end
modified = specified_properties.reject do |p|
@new_resource.send(p) == current_resource.send(p)
end
generate_pretty_green_text(modified)
end
- 1
def generate_pretty_green_text(modified)
property_size = modified.map(&:size).max
modified.map! do |p|
properties_str = if @new_resource.sensitive
'(suppressed sensitive property)'
else
[
@new_resource.send(p).inspect,
"(was #{current_resource.send(p).inspect})"
].join(' ')
end
" set #{p.to_s.ljust(property_size)} to #{properties_str}"
end
end
# Write down any properties we are setting.
- 1
def compute_changes_for_new_resource(properties)
property_size = properties.map(&:size).max
properties.map do |property|
default = ' (default value)' \
unless @new_resource.property_is_set?(property)
next if @new_resource.send(property).nil?
properties_str = if @new_resource.sensitive
'(suppressed sensitive property)'
else
@new_resource.send(property).inspect
end
[" set #{property.to_s.ljust(property_size)}",
"to #{properties_str}#{default}"].join(' ')
end.compact
end
- 1
def resource_to_query_predicate(resource)
self.class.resource_to_query_predicate(resource)
end
- 1
def self.resource_to_query_predicate(resource)
{
host: resource.host,
name: resource.name
}
end
- 1
def fetch_auth(resource)
self.class.fetch_auth(resource)
end
- 1
def self.fetch_auth(resource)
resource.resources("gauth_credential[#{resource.credential}]")
.authorization
end
- 1
def fetch_resource(resource, self_link, kind)
self.class.fetch_resource(resource, self_link, kind)
end
- 1
def debug(message)
Chef::Log.debug(message)
end
- 1
def self.collection(data)
URI.join(
'https://www.googleapis.com/sql/v1beta4/',
expand_variables(
'projects/{{project}}/instances/{{instance}}/users',
data
)
)
end
- 1
def collection(data)
self.class.collection(data)
end
- 1
def self.self_link(data)
URI.join(
'https://www.googleapis.com/sql/v1beta4/',
expand_variables(
[
'projects/{{project}}/instances/{{instance}}/users',
'?name={{name}}&host={{host}}'
].join,
data
)
)
end
- 1
def self_link(data)
self.class.self_link(data)
end
# rubocop:disable Metrics/CyclomaticComplexity
- 1
def self.return_if_object(response, kind)
raise "Bad response: #{response.body}" \
if response.is_a?(Net::HTTPBadRequest)
raise "Bad response: #{response}" \
unless response.is_a?(Net::HTTPResponse)
return if response.is_a?(Net::HTTPNotFound)
return if response.is_a?(Net::HTTPNoContent)
result = JSON.parse(response.body)
raise_if_errors result, %w[error errors], 'message'
raise "Bad response: #{response}" unless response.is_a?(Net::HTTPOK)
raise "Incorrect result: #{result['kind']} (expected '#{kind}')" \
unless result['kind'] == kind
result
end
# rubocop:enable Metrics/CyclomaticComplexity
- 1
def return_if_object(response, kind)
self.class.return_if_object(response, kind)
end
- 1
def self.extract_variables(template)
- 680
template.scan(/{{[^}]*}}/).map { |v| v.gsub(/{{([^}]*)}}/, '\1') }
- 178
.map(&:to_sym)
end
- 1
def self.expand_variables(template, var_data, extra_data = {})
- 178
data = if var_data.class <= Hash
- 178
var_data.merge(extra_data)
else
resource_to_hash(var_data).merge(extra_data)
end
- 178
extract_variables(template).each do |v|
- 680
unless data.key?(v)
raise "Missing variable :#{v} in #{data} on #{caller.join("\n")}}"
end
- 680
template.gsub!(/{{#{v}}}/, CGI.escape(data[v].to_s))
end
- 178
template
end
- 1
def expand_variables(template, var_data, extra_data = {})
self.class.expand_variables(template, var_data, extra_data)
end
- 1
def fetch_resource(resource, self_link, kind)
self.class.fetch_resource(resource, self_link, kind)
end
- 1
def async_op_url(data, extra_data = {})
URI.join(
'https://www.googleapis.com/sql/v1beta4/',
expand_variables(
'projects/{{project}}/operations/{{op_id}}',
data, extra_data
)
)
end
- 1
def wait_for_operation(response, resource)
op_result = return_if_object(response, 'sql#operation')
return if op_result.nil?
status = ::Google::HashUtils.navigate(op_result, %w[status])
wait_for_completion status, op_result, resource
fetch_wrapped_resource(resource, 'sql#user', 'sql#usersList', 'items')
end
- 1
def wait_for_completion(status, op_result, resource)
op_id = ::Google::HashUtils.navigate(op_result, %w[name])
op_uri = async_op_url(resource, op_id: op_id)
while status != 'DONE'
debug("Waiting for completion of operation #{op_id}")
raise_if_errors op_result, %w[error errors], 'message'
sleep 1.0
raise "Invalid result '#{status}' on gsql_user." \
unless %w[PENDING RUNNING DONE].include?(status)
op_result = fetch_resource(resource, op_uri, 'sql#operation')
status = ::Google::HashUtils.navigate(op_result, %w[status])
end
op_result
end
- 1
def raise_if_errors(response, err_path, msg_field)
self.class.raise_if_errors(response, err_path, msg_field)
end
- 1
def self.fetch_resource(resource, self_link, kind)
get_request = ::Google::Sql::Network::Get.new(
self_link, fetch_auth(resource)
)
return_if_object get_request.send, kind
end
- 1
def fetch_wrapped_resource(resource, kind, wrap_kind, wrap_path)
self.class.fetch_wrapped_resource(resource, kind, wrap_kind, wrap_path)
end
- 1
def self.fetch_wrapped_resource(resource, kind, wrap_kind, wrap_path)
result = fetch_resource(resource, self_link(resource), wrap_kind)
return if result.nil? || !result.key?(wrap_path)
result = unwrap_resource(result[wrap_path], resource)
return if result.nil?
raise "Incorrect result: #{result['kind']} (expected #{kind})" \
unless result['kind'] == kind
result
end
- 1
def unwrap_resource(result, resource)
self.class.unwrap_resource(result, resource)
end
- 1
def self.unwrap_resource(result, resource)
query_predicate = unwrap_resource_filter(resource)
matches = result.select do |entry|
query_predicate.all? do |k, v|
entry[k.id2name] == v
end
end
raise "More than 1 result found: #{matches}" if matches.size > 1
return if matches.empty?
matches.first
end
- 1
def self.raise_if_errors(response, err_path, msg_field)
errors = ::Google::HashUtils.navigate(response, err_path)
raise_error(errors, msg_field) unless errors.nil?
end
- 1
def self.raise_error(errors, msg_field)
raise IOError, ['Operation failed:',
errors.map { |e| e[msg_field] }.join(', ')].join(' ')
end
end
end
# rubocop:enable Metrics/ClassLength
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
require 'open3'
- 1
class Bundle
- 1
def self.run(args)
- 2
Open3.popen2e(*%w[bundle exec].concat(args)) do |_, stdout_err, wait_thr|
- 2
return -2 if wait_thr.nil?
- 2
exit_code = wait_thr.value.to_i
- 2
puts stdout_err.readlines unless exit_code.zero?
- 2
return exit_code
end
-1
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
module Google
# A dummy authorization handler that responds to the same authorize interface
# as a gauth_credential. Useful for testing code without the need to take a
# dependency on the real resource provider.
- 1
class FakeAuthorization
- 1
def authorize(request)
request
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
require 'chef/resource'
- 1
module Google
- 1
class CredentialResourceMock < Chef::Resource
- 1
resource_name :gauth_credential
- 1
property :name, String, identity: true, desired_state: false
- 1
property :path, String, desired_state: false
- 1
property :scopes, Array, desired_state: false
- 1
default_action :nothing
- 1
action :nothing do
end
- 1
action :serviceaccount do
end
- 1
def authorization
- 524
Google::FakeAuthorization.new
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
require 'spec_helper'
# TODO(alexstephen): Reformat tests to use nested describe blocks
# TODO(alexstephen): Add title == name tests
# Test Matrix:
#
# +--------------------------------------------------------+
# | Action | Exists | Changes | Success | Result |
# +--------------------------------------------------------+
# | create | Y | Y | Y | Edit |
# | create | Y | Y | N | Fail |
# | create | Y | N | Y | Fetch (no-op) |
# | create | Y | N | N | Fail |
# | create | N | Y | Y | Create |
# | create | N | Y | N | Fail |
# +--------------------------------------------------------+
# | delete | Y | Y | Y | Delete |
# | delete | Y | Y | N | Fail |
# | delete | N | Y | Y | Fail (no delete)|
# | delete | N | Y | N | Fail |
# +--------------------------------------------------------+
# TODO(alexstephen): Add tests for manage
# TODO(alexstephen): Add tests for modify
- 1
context 'gsql_flag' do
- 1
context 'resource exists' do
# Ensure ignore: resource exists, no change
- 1
context 'no changes == no action' do
# Ensure ignore: resource exists, no change, no name, pass
- 1
context 'title == name (pass)' do
# TODO(alexstephen): Implement new test format.
end
# Ensure ignore: resource exists, no change, has name, pass
- 1
context 'title != name (pass)' do
# TODO(alexstephen): Implement new test format.
end
end
# Ensure ignore: resource exists, changes
- 1
context 'changes == action' do
# Ensure ignore: resource exists, changes, no name, fail
- 1
context 'title == name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
# Ensure ignore: resource exists, changes, has name, fail
- 1
context 'title != name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
end
end
- 1
context 'resource missing' do
# Ensure ignore: resource missing, ignore, no name, fail
- 1
context 'title == name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
# Ensure ignore: resource missing, ignore, has name, fail
- 1
context 'title != name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
end
- 1
def expand_variables(template, data, extra_data = {})
Google::GSQL::Flag
.action_class.expand_variables(template, data, extra_data)
end
- 1
def expect_network_get_success(id, data = {})
id_data = data.fetch(:name, '').include?('title') ? 'title' : 'name'
body = load_network_result("success#{id}~#{id_data}.yaml").to_json
request = double('request')
allow(request).to receive(:send).and_return(http_success(body))
debug_network "!! GET #{self_link(uri_data(id).merge(data))}"
expect(Google::Sql::Network::Get).to receive(:new)
.with(self_link(uri_data(id).merge(data)),
instance_of(Google::FakeAuthorization)) do |args|
debug_network ">> GET #{args}"
request
end
end
- 1
def http_success(body)
response = Net::HTTPOK.new(1.0, 200, 'OK')
response.body = body
response.instance_variable_set(:@read, true)
response
end
- 1
def expect_network_get_failed(id, data = {})
request = double('request')
allow(request).to receive(:send).and_return(http_failed_object_missing)
debug_network "!! #{self_link(uri_data(id).merge(data))}"
expect(Google::Sql::Network::Get).to receive(:new)
.with(self_link(uri_data(id).merge(data)),
instance_of(Google::FakeAuthorization)) do |args|
debug_network ">> GET [failed] #{args}"
request
end
end
- 1
def http_failed_object_missing
Net::HTTPNotFound.new(1.0, 404, 'Not Found')
end
- 1
def load_network_result(file)
results = File.join(File.dirname(__FILE__), 'data', 'network',
'gsql_flag', file)
debug("Loading result file: #{results}")
raise "Network result data file #{results}" unless File.exist?(results)
data = YAML.safe_load(File.read(results))
raise "Invalid network results #{results}" unless data.class <= Hash
data
end
- 1
def debug(message)
puts(message) if ENV['RSPEC_DEBUG']
end
- 1
def debug_network(message)
puts("Network #{message}") \
if ENV['RSPEC_DEBUG'] || ENV['RSPEC_HTTP_VERBOSE']
end
- 1
def collection(data)
URI.join(
'https://www.googleapis.com/sql/v1beta4/',
expand_variables(
'flags',
data
)
)
end
- 1
def self_link(data)
URI.join(
'https://www.googleapis.com/sql/v1beta4/',
expand_variables(
'flags',
data
)
)
end
# Creates variable test data to comply with self_link URI parameters
- 1
def uri_data(_id)
{}
end
- 1
def build_cred
<<-CRED
gauth_credential 'mycred' do
action :serviceaccount
path '/home'
scopes [
'test_path'
]
end
CRED
end
# Creates a test recipe file and runs a block before destroying the file
- 1
def apply_recipe(recipe)
# Creates a random string name
recipe_name = "recipe~test~#{(0...8).map { (65 + rand(26)).chr }.join}"
recipe_loc = File.join(File.dirname(__FILE__), '..', 'recipes',
"#{recipe_name}.rb")
File.open(recipe_loc, 'w') do |file|
file.write([build_cred, recipe].join("\n"))
end
recipe_path = "google-gsql::#{recipe_name}"
begin
yield recipe_path
ensure
File.delete(recipe_loc)
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
require 'spec_helper'
- 1
context 'check examples with foodcritic' do
- 1
let(:recipes) do
- 1
Dir[File.join(File.dirname(__FILE__), '../', 'recipes', '*.rb')]
end
- 2
let(:command) { ['foodcritic'].concat(recipes) }
- 2
subject { Bundle.run(command) }
- 2
it { is_expected.to be_zero }
end
- 1
context 'ensure foodcritic recognizes bad recipes' do
- 1
let(:poor_recipe) do
- 1
File.join(File.dirname(__FILE__), 'data', 'poor_recipe.rb')
end
- 2
let(:command) { ['foodcritic', poor_recipe] }
- 2
subject { Bundle.run(command) }
- 2
it { is_expected.not_to be_zero }
end
# Copyright 2017 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
- 1
require 'spec_helper'
- 1
describe Google::HashUtils do
- 1
context '#camelize_keys' do
- 1
subject do
- 1
described_class.camelize_keys(a_a_a: 'aaa',
bb_bb_bb: 'bbb',
abc_def_ghi: 'abcdefghi')
end
- 1
it do
- 1
is_expected.to eq('aAA' => 'aaa',
'bbBbBb' => 'bbb',
'abcDefGhi' => 'abcdefghi')
end
end
- 1
context '#navigate' do
- 5
let(:source) { { a: { b: { c: %i[d e] } } } }
- 2
let(:default) { Object.new }
- 1
context 'find item middle' do
- 2
subject { described_class.navigate(source, %i[a b]) }
- 2
it { is_expected.to eq(c: %i[d e]) }
end
- 1
context 'find item leaf' do
- 2
subject { described_class.navigate(source, %i[a b c]) }
- 2
it { is_expected.to eq(%i[d e]) }
end
- 1
context 'item does not exist' do
- 2
subject { described_class.navigate(source, %i[d]) }
- 2
it { is_expected.to be nil }
end
- 1
context 'returns default' do
- 2
subject { described_class.navigate(source, %i[d], default) }
- 2
it { is_expected.to eq default }
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
require 'spec_helper'
# TODO(alexstephen): Reformat tests to use nested describe blocks
# TODO(alexstephen): Add title == name tests
# Test Matrix:
#
# +--------------------------------------------------------+
# | Action | Exists | Changes | Success | Result |
# +--------------------------------------------------------+
# | create | Y | Y | Y | Edit |
# | create | Y | Y | N | Fail |
# | create | Y | N | Y | Fetch (no-op) |
# | create | Y | N | N | Fail |
# | create | N | Y | Y | Create |
# | create | N | Y | N | Fail |
# +--------------------------------------------------------+
# | delete | Y | Y | Y | Delete |
# | delete | Y | Y | N | Fail |
# | delete | N | Y | Y | Fail (no delete)|
# | delete | N | Y | N | Fail |
# +--------------------------------------------------------+
# TODO(alexstephen): Add tests for manage
# TODO(alexstephen): Add tests for modify
- 1
context 'gsql_instance' do
- 1
context 'ensure == present' do
- 1
context 'resource exists' do
# Ensure present: resource exists, no change
- 1
context 'no changes == no action' do
# Ensure present: resource exists, no change, no name
- 1
context 'title == name' do
# Ensure present: resource exists, no change, no name, pass
- 1
context 'title == name (pass)' do
- 1
before do
- 27
allow(Time).to receive(:now).and_return(
Time.new(2017, 1, 2, 3, 4, 5)
)
- 27
expect_network_get_success 1, name: 'title0'
- 27
expect_network_get_success 2, name: 'title1'
- 27
expect_network_get_success 3, name: 'title2'
end
- 1
let(:runner) do
# This path ensures that the current cookbook is
# loaded for testing.
# This path will load all other cookbooks in the
# parent directory.
# Under most circumstances, this will include the
# real google-gauth cookbook.
- 27
parent_dir = File.join(File.dirname(__FILE__), '..', '..')
- 27
cookbook_paths = [parent_dir]
# If there's no real version of the google-gauth ,
# add in the mocked version so that the tests do not fail.
# Since cookbooks can have any name, we assume that
# any directory with the word auth is the google-gauth cookbook.
- 27
cookbook_paths << File.join(File.dirname(__FILE__), 'cookbooks')
- 27
ChefSpec::SoloRunner.new(
step_into: 'gsql_instance',
cookbook_path: cookbook_paths,
platform: 'ubuntu',
version: '16.04'
)
end
- 1
let(:chef_run) do
apply_recipe(
<<-MANIFEST
gsql_instance 'title0' do
action :create
backend_type 'FIRST_GEN'
connection_name 'test connection_name#0 data'
database_version 'MYSQL_5_5'
failover_replica({
available: true,
name: 'test name#0 data'
})
instance_type 'CLOUD_SQL_INSTANCE'
ipv6_address 'test ipv6_address#0 data'
master_instance_name 'test master_instance_name#0 data'
max_disk_size 399168897
region 'test region#0 data'
replica_configuration({
failover_target: true,
mysql_replica_configuration: {
ca_certificate: 'test ca_certificate#0 data',
client_certificate: 'test client_certificate#0 data',
client_key: 'test client_key#0 data',
connect_retry_interval: 586223489,
dump_file_path: 'test dump_file_path#0 data',
master_heartbeat_period: 2641537687,
password: 'test password#0 data',
ssl_cipher: 'test ssl_cipher#0 data',
username: 'test username#0 data',
verify_server_certificate: true
},
replica_names: ['ee', 'ff', 'gg', 'hh'],
service_account_email_address: 'test service_account_email_address#0 data'
})
settings({
ip_configuration: {
authorized_networks: [
{
expiration_time: '2018-07-08T02:10:16+00:00',
name: 'test name#0 data',
value: 'test value#0 data'
},
{
expiration_time: '2067-01-12T04:20:32+00:00',
name: 'test name#1 data',
value: 'test value#1 data'
},
{
expiration_time: '2115-07-20T06:30:48+00:00',
name: 'test name#2 data',
value: 'test value#2 data'
}
],
ipv4_enabled: true,
require_ssl: true
},
settings_version: 1508110470,
tier: 'test tier#0 data'
})
project 'test project#0 data'
credential 'mycred'
end
gsql_instance 'title1' do
action :create
backend_type 'SECOND_GEN'
connection_name 'test connection_name#1 data'
database_version 'MYSQL_5_6'
failover_replica({
available: false,
name: 'test name#1 data'
})
instance_type 'ON_PREMISES_INSTANCE'
ipv6_address 'test ipv6_address#1 data'
master_instance_name 'test master_instance_name#1 data'
max_disk_size 798337795
region 'test region#1 data'
replica_configuration({
failover_target: false,
mysql_replica_configuration: {
ca_certificate: 'test ca_certificate#1 data',
client_certificate: 'test client_certificate#1 data',
client_key: 'test client_key#1 data',
connect_retry_interval: 1172446978,
dump_file_path: 'test dump_file_path#1 data',
master_heartbeat_period: 5283075375,
password: 'test password#1 data',
ssl_cipher: 'test ssl_cipher#1 data',
username: 'test username#1 data',
verify_server_certificate: false
},
replica_names: ['kk', 'll'],
service_account_email_address: 'test service_account_email_address#1 data'
})
settings({
ip_configuration: {
authorized_networks: [
{
expiration_time: '2067-01-12T04:20:32+00:00',
name: 'test name#1 data',
value: 'test value#1 data'
},
{
expiration_time: '2115-07-20T06:30:48+00:00',
name: 'test name#2 data',
value: 'test value#2 data'
},
{
expiration_time: '2164-01-24T08:41:04+00:00',
name: 'test name#3 data',
value: 'test value#3 data'
},
{
expiration_time: '2212-07-31T10:51:20+00:00',
name: 'test name#4 data',
value: 'test value#4 data'
},
{
expiration_time: '2261-02-04T13:01:36+00:00',
name: 'test name#5 data',
value: 'test value#5 data'
}
],
ipv4_enabled: false,
require_ssl: false
},
settings_version: 3016220941,
tier: 'test tier#1 data'
})
project 'test project#1 data'
credential 'mycred'
end
gsql_instance 'title2' do
action :create
backend_type 'EXTERNAL'
connection_name 'test connection_name#2 data'
database_version 'MYSQL_5_7'
failover_replica({
available: true,
name: 'test name#2 data'
})
instance_type 'READ_REPLICA_INSTANCE'
ipv6_address 'test ipv6_address#2 data'
master_instance_name 'test master_instance_name#2 data'
max_disk_size 1197506692
region 'test region#2 data'
replica_configuration({
failover_target: true,
mysql_replica_configuration: {
ca_certificate: 'test ca_certificate#2 data',
client_certificate: 'test client_certificate#2 data',
client_key: 'test client_key#2 data',
connect_retry_interval: 1758670468,
dump_file_path: 'test dump_file_path#2 data',
master_heartbeat_period: 7924613063,
password: 'test password#2 data',
ssl_cipher: 'test ssl_cipher#2 data',
username: 'test username#2 data',
verify_server_certificate: true
},
replica_names: ['qq', 'rr', 'ss', 'tt'],
service_account_email_address: 'test service_account_email_address#2 data'
})
settings({
ip_configuration: {
authorized_networks: [
{
expiration_time: '2115-07-20T06:30:48+00:00',
name: 'test name#2 data',
value: 'test value#2 data'
},
{
expiration_time: '2164-01-24T08:41:04+00:00',
name: 'test name#3 data',
value: 'test value#3 data'
}
],
ipv4_enabled: true,
require_ssl: true
},
settings_version: 4524331411,
tier: 'test tier#2 data'
})
project 'test project#2 data'
credential 'mycred'
end
MANIFEST
- 27
) do |recipe_name|
- 27
runner.converge(recipe_name) do
- 27
cred = Google::CredentialResourceMock.new('mycred',
runner.run_context)
- 27
runner.resource_collection.insert(cred)
end
end
end
- 1
context 'gsql_instance[title0]' do
- 1
subject do
- 9
chef_run.find_resource(:gsql_instance, 'title0')
end
- 2
it { is_expected.to have_attributes(backend_type: 'FIRST_GEN') }
- 2
it { is_expected.to have_attributes(connection_name: 'test connection_name#0 data') }
- 2
it { is_expected.to have_attributes(database_version: 'MYSQL_5_5') }
# TODO(nelsonjr): Implement complex nested property object test.
# it 'failoverReplica' do
# # Add test code here
# end
- 2
it { is_expected.to have_attributes(instance_type: 'CLOUD_SQL_INSTANCE') }
- 2
it { is_expected.to have_attributes(ipv6_address: 'test ipv6_address#0 data') }
- 1
it do
- 1
is_expected
.to have_attributes(master_instance_name: 'test master_instance_name#0 data')
end
- 2
it { is_expected.to have_attributes(max_disk_size: 399_168_897) }
- 2
it { is_expected.to have_attributes(i_label: 'title0') }
- 2
it { is_expected.to have_attributes(region: 'test region#0 data') }
# TODO(nelsonjr): Implement complex nested property object test.
# it 'replicaConfiguration' do
# # Add test code here
# end
# TODO(nelsonjr): Implement complex nested property object test.
# it 'settings' do
# # Add test code here
# end
end
- 1
context 'gsql_instance[title1]' do
- 1
subject do
- 9
chef_run.find_resource(:gsql_instance, 'title1')
end
- 2
it { is_expected.to have_attributes(backend_type: 'SECOND_GEN') }
- 2
it { is_expected.to have_attributes(connection_name: 'test connection_name#1 data') }
- 2
it { is_expected.to have_attributes(database_version: 'MYSQL_5_6') }
# TODO(nelsonjr): Implement complex nested property object test.
# it 'failoverReplica' do
# # Add test code here
# end
- 2
it { is_expected.to have_attributes(instance_type: 'ON_PREMISES_INSTANCE') }
- 2
it { is_expected.to have_attributes(ipv6_address: 'test ipv6_address#1 data') }
- 1
it do
- 1
is_expected
.to have_attributes(master_instance_name: 'test master_instance_name#1 data')
end
- 2
it { is_expected.to have_attributes(max_disk_size: 798_337_795) }
- 2
it { is_expected.to have_attributes(i_label: 'title1') }
- 2
it { is_expected.to have_attributes(region: 'test region#1 data') }
# TODO(nelsonjr): Implement complex nested property object test.
# it 'replicaConfiguration' do
# # Add test code here
# end
# TODO(nelsonjr): Implement complex nested property object test.
# it 'settings' do
# # Add test code here
# end
end
- 1
context 'gsql_instance[title2]' do
- 1
subject do
- 9
chef_run.find_resource(:gsql_instance, 'title2')
end
- 2
it { is_expected.to have_attributes(backend_type: 'EXTERNAL') }
- 2
it { is_expected.to have_attributes(connection_name: 'test connection_name#2 data') }
- 2
it { is_expected.to have_attributes(database_version: 'MYSQL_5_7') }
# TODO(nelsonjr): Implement complex nested property object test.
# it 'failoverReplica' do
# # Add test code here
# end
- 2
it { is_expected.to have_attributes(instance_type: 'READ_REPLICA_INSTANCE') }
- 2
it { is_expected.to have_attributes(ipv6_address: 'test ipv6_address#2 data') }
- 1
it do
- 1
is_expected
.to have_attributes(master_instance_name: 'test master_instance_name#2 data')
end
- 2
it { is_expected.to have_attributes(max_disk_size: 1_197_506_692) }
- 2
it { is_expected.to have_attributes(i_label: 'title2') }
- 2
it { is_expected.to have_attributes(region: 'test region#2 data') }
# TODO(nelsonjr): Implement complex nested property object test.
# it 'replicaConfiguration' do
# # Add test code here
# end
# TODO(nelsonjr): Implement complex nested property object test.
# it 'settings' do
# # Add test code here
# end
end
end
# Ensure present: resource exists, no change, no name, fail
- 1
context 'title == name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
end
# Ensure present: resource exists, no change, has name
- 1
context 'title != name' do
# Ensure present: resource exists, no change, has name, pass
- 1
context 'title != name (pass)' do
- 1
before do
- 27
allow(Time).to receive(:now).and_return(
Time.new(2017, 1, 2, 3, 4, 5)
)
- 27
expect_network_get_success 1
- 27
expect_network_get_success 2
- 27
expect_network_get_success 3
end
- 1
let(:runner) do
# This path ensures that the current cookbook is
# loaded for testing.
# This path will load all other cookbooks in the
# parent directory.
# Under most circumstances, this will include the
# real google-gauth cookbook.
- 27
parent_dir = File.join(File.dirname(__FILE__), '..', '..')
- 27
cookbook_paths = [parent_dir]
# If there's no real version of the google-gauth ,
# add in the mocked version so that the tests do not fail.
# Since cookbooks can have any name, we assume that
# any directory with the word auth is the google-gauth cookbook.
- 27
cookbook_paths << File.join(File.dirname(__FILE__), 'cookbooks')
- 27
ChefSpec::SoloRunner.new(
step_into: 'gsql_instance',
cookbook_path: cookbook_paths,
platform: 'ubuntu',
version: '16.04'
)
end
- 1
let(:chef_run) do
apply_recipe(
<<-MANIFEST
gsql_instance 'title0' do
action :create
backend_type 'FIRST_GEN'
connection_name 'test connection_name#0 data'
database_version 'MYSQL_5_5'
failover_replica({
available: true,
name: 'test name#0 data'
})
i_label 'test name#0 data'
instance_type 'CLOUD_SQL_INSTANCE'
ipv6_address 'test ipv6_address#0 data'
master_instance_name 'test master_instance_name#0 data'
max_disk_size 399168897
region 'test region#0 data'
replica_configuration({
failover_target: true,
mysql_replica_configuration: {
ca_certificate: 'test ca_certificate#0 data',
client_certificate: 'test client_certificate#0 data',
client_key: 'test client_key#0 data',
connect_retry_interval: 586223489,
dump_file_path: 'test dump_file_path#0 data',
master_heartbeat_period: 2641537687,
password: 'test password#0 data',
ssl_cipher: 'test ssl_cipher#0 data',
username: 'test username#0 data',
verify_server_certificate: true
},
replica_names: ['ee', 'ff', 'gg', 'hh'],
service_account_email_address: 'test service_account_email_address#0 data'
})
settings({
ip_configuration: {
authorized_networks: [
{
expiration_time: '2018-07-08T02:10:16+00:00',
name: 'test name#0 data',
value: 'test value#0 data'
},
{
expiration_time: '2067-01-12T04:20:32+00:00',
name: 'test name#1 data',
value: 'test value#1 data'
},
{
expiration_time: '2115-07-20T06:30:48+00:00',
name: 'test name#2 data',
value: 'test value#2 data'
}
],
ipv4_enabled: true,
require_ssl: true
},
settings_version: 1508110470,
tier: 'test tier#0 data'
})
project 'test project#0 data'
credential 'mycred'
end
gsql_instance 'title1' do
action :create
backend_type 'SECOND_GEN'
connection_name 'test connection_name#1 data'
database_version 'MYSQL_5_6'
failover_replica({
available: false,
name: 'test name#1 data'
})
i_label 'test name#1 data'
instance_type 'ON_PREMISES_INSTANCE'
ipv6_address 'test ipv6_address#1 data'
master_instance_name 'test master_instance_name#1 data'
max_disk_size 798337795
region 'test region#1 data'
replica_configuration({
failover_target: false,
mysql_replica_configuration: {
ca_certificate: 'test ca_certificate#1 data',
client_certificate: 'test client_certificate#1 data',
client_key: 'test client_key#1 data',
connect_retry_interval: 1172446978,
dump_file_path: 'test dump_file_path#1 data',
master_heartbeat_period: 5283075375,
password: 'test password#1 data',
ssl_cipher: 'test ssl_cipher#1 data',
username: 'test username#1 data',
verify_server_certificate: false
},
replica_names: ['kk', 'll'],
service_account_email_address: 'test service_account_email_address#1 data'
})
settings({
ip_configuration: {
authorized_networks: [
{
expiration_time: '2067-01-12T04:20:32+00:00',
name: 'test name#1 data',
value: 'test value#1 data'
},
{
expiration_time: '2115-07-20T06:30:48+00:00',
name: 'test name#2 data',
value: 'test value#2 data'
},
{
expiration_time: '2164-01-24T08:41:04+00:00',
name: 'test name#3 data',
value: 'test value#3 data'
},
{
expiration_time: '2212-07-31T10:51:20+00:00',
name: 'test name#4 data',
value: 'test value#4 data'
},
{
expiration_time: '2261-02-04T13:01:36+00:00',
name: 'test name#5 data',
value: 'test value#5 data'
}
],
ipv4_enabled: false,
require_ssl: false
},
settings_version: 3016220941,
tier: 'test tier#1 data'
})
project 'test project#1 data'
credential 'mycred'
end
gsql_instance 'title2' do
action :create
backend_type 'EXTERNAL'
connection_name 'test connection_name#2 data'
database_version 'MYSQL_5_7'
failover_replica({
available: true,
name: 'test name#2 data'
})
i_label 'test name#2 data'
instance_type 'READ_REPLICA_INSTANCE'
ipv6_address 'test ipv6_address#2 data'
master_instance_name 'test master_instance_name#2 data'
max_disk_size 1197506692
region 'test region#2 data'
replica_configuration({
failover_target: true,
mysql_replica_configuration: {
ca_certificate: 'test ca_certificate#2 data',
client_certificate: 'test client_certificate#2 data',
client_key: 'test client_key#2 data',
connect_retry_interval: 1758670468,
dump_file_path: 'test dump_file_path#2 data',
master_heartbeat_period: 7924613063,
password: 'test password#2 data',
ssl_cipher: 'test ssl_cipher#2 data',
username: 'test username#2 data',
verify_server_certificate: true
},
replica_names: ['qq', 'rr', 'ss', 'tt'],
service_account_email_address: 'test service_account_email_address#2 data'
})
settings({
ip_configuration: {
authorized_networks: [
{
expiration_time: '2115-07-20T06:30:48+00:00',
name: 'test name#2 data',
value: 'test value#2 data'
},
{
expiration_time: '2164-01-24T08:41:04+00:00',
name: 'test name#3 data',
value: 'test value#3 data'
}
],
ipv4_enabled: true,
require_ssl: true
},
settings_version: 4524331411,
tier: 'test tier#2 data'
})
project 'test project#2 data'
credential 'mycred'
end
MANIFEST
- 27
) do |recipe_name|
- 27
runner.converge(recipe_name) do
- 27
cred = Google::CredentialResourceMock.new('mycred',
runner.run_context)
- 27
runner.resource_collection.insert(cred)
end
end
end
- 1
context 'gsql_instance[title0]' do
- 1
subject do
- 9
chef_run.find_resource(:gsql_instance, 'title0')
end
- 2
it { is_expected.to have_attributes(backend_type: 'FIRST_GEN') }
- 2
it { is_expected.to have_attributes(connection_name: 'test connection_name#0 data') }
- 2
it { is_expected.to have_attributes(database_version: 'MYSQL_5_5') }
# TODO(nelsonjr): Implement complex nested property object test.
# it 'failoverReplica' do
# # Add test code here
# end
- 2
it { is_expected.to have_attributes(instance_type: 'CLOUD_SQL_INSTANCE') }
- 2
it { is_expected.to have_attributes(ipv6_address: 'test ipv6_address#0 data') }
- 1
it do
- 1
is_expected
.to have_attributes(master_instance_name: 'test master_instance_name#0 data')
end
- 2
it { is_expected.to have_attributes(max_disk_size: 399_168_897) }
- 2
it { is_expected.to have_attributes(i_label: 'test name#0 data') }
- 2
it { is_expected.to have_attributes(region: 'test region#0 data') }
# TODO(nelsonjr): Implement complex nested property object test.
# it 'replicaConfiguration' do
# # Add test code here
# end
# TODO(nelsonjr): Implement complex nested property object test.
# it 'settings' do
# # Add test code here
# end
end
- 1
context 'gsql_instance[title1]' do
- 1
subject do
- 9
chef_run.find_resource(:gsql_instance, 'title1')
end
- 2
it { is_expected.to have_attributes(backend_type: 'SECOND_GEN') }
- 2
it { is_expected.to have_attributes(connection_name: 'test connection_name#1 data') }
- 2
it { is_expected.to have_attributes(database_version: 'MYSQL_5_6') }
# TODO(nelsonjr): Implement complex nested property object test.
# it 'failoverReplica' do
# # Add test code here
# end
- 2
it { is_expected.to have_attributes(instance_type: 'ON_PREMISES_INSTANCE') }
- 2
it { is_expected.to have_attributes(ipv6_address: 'test ipv6_address#1 data') }
- 1
it do
- 1
is_expected
.to have_attributes(master_instance_name: 'test master_instance_name#1 data')
end
- 2
it { is_expected.to have_attributes(max_disk_size: 798_337_795) }
- 2
it { is_expected.to have_attributes(i_label: 'test name#1 data') }
- 2
it { is_expected.to have_attributes(region: 'test region#1 data') }
# TODO(nelsonjr): Implement complex nested property object test.
# it 'replicaConfiguration' do
# # Add test code here
# end
# TODO(nelsonjr): Implement complex nested property object test.
# it 'settings' do
# # Add test code here
# end
end
- 1
context 'gsql_instance[title2]' do
- 1
subject do
- 9
chef_run.find_resource(:gsql_instance, 'title2')
end
- 2
it { is_expected.to have_attributes(backend_type: 'EXTERNAL') }
- 2
it { is_expected.to have_attributes(connection_name: 'test connection_name#2 data') }
- 2
it { is_expected.to have_attributes(database_version: 'MYSQL_5_7') }
# TODO(nelsonjr): Implement complex nested property object test.
# it 'failoverReplica' do
# # Add test code here
# end
- 2
it { is_expected.to have_attributes(instance_type: 'READ_REPLICA_INSTANCE') }
- 2
it { is_expected.to have_attributes(ipv6_address: 'test ipv6_address#2 data') }
- 1
it do
- 1
is_expected
.to have_attributes(master_instance_name: 'test master_instance_name#2 data')
end
- 2
it { is_expected.to have_attributes(max_disk_size: 1_197_506_692) }
- 2
it { is_expected.to have_attributes(i_label: 'test name#2 data') }
- 2
it { is_expected.to have_attributes(region: 'test region#2 data') }
# TODO(nelsonjr): Implement complex nested property object test.
# it 'replicaConfiguration' do
# # Add test code here
# end
# TODO(nelsonjr): Implement complex nested property object test.
# it 'settings' do
# # Add test code here
# end
end
end
# Ensure present: resource exists, no change, has name, fail
- 1
context 'title != name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
end
end
# Ensure present: resource exists, changes
- 1
context 'changes == action' do
# Ensure present: resource exists, changes, no name
- 1
context 'title == name' do
# Ensure present: resource exists, changes, no name, pass
- 1
context 'title == name (pass)' do
# TODO(alexstephen): Implement new test format.
end
# Ensure present: resource exists, changes, no name, fail
- 1
context 'title == name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
end
# Ensure present: resource exists, changes, has name
- 1
context 'title != name' do
# Ensure present: resource exists, changes, has name, pass
- 1
context 'title != name (pass)' do
# TODO(alexstephen): Implement new test format
end
# Ensure present: resource exists, changes, has name, fail
- 1
context 'title != name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
end
end
end
- 1
context 'resource missing' do
# Ensure present: resource missing, ignore, no name
- 1
context 'title == name' do
# Ensure present: resource missing, ignore, no name, pass
- 1
context 'title == name (pass)' do
- 1
before do
# rubocop:disable Metrics/LineLength
- 10
expect_network_get_failed 1, name: 'title0'
expect_network_create \
- 10
1,
{
'kind' => 'sql#instance',
'backendType' => 'FIRST_GEN',
'connectionName' => 'test connection_name#0 data',
'databaseVersion' => 'MYSQL_5_5',
'failoverReplica' => {
'available' => true,
'name' => 'test name#0 data'
},
'instanceType' => 'CLOUD_SQL_INSTANCE',
'ipv6Address' => 'test ipv6_address#0 data',
'masterInstanceName' => 'test master_instance_name#0 data',
'maxDiskSize' => 399_168_897,
'name' => 'title0',
'region' => 'test region#0 data',
'replicaConfiguration' => {
'failoverTarget' => true,
'mysqlReplicaConfiguration' => {
'caCertificate' => 'test ca_certificate#0 data',
'clientCertificate' => 'test client_certificate#0 data',
'clientKey' => 'test client_key#0 data',
'connectRetryInterval' => 586_223_489,
'dumpFilePath' => 'test dump_file_path#0 data',
'masterHeartbeatPeriod' => 2_641_537_687,
'password' => 'test password#0 data',
'sslCipher' => 'test ssl_cipher#0 data',
'username' => 'test username#0 data',
'verifyServerCertificate' => true
},
'replicaNames' => %w[ee ff gg hh],
'serviceAccountEmailAddress' => 'test service_account_email_address#0 data'
},
'settings' => {
'ipConfiguration' => {
'ipv4Enabled' => true,
'authorizedNetworks' => [
{
'expirationTime' => '2018-07-08T02:10:16+00:00',
'name' => 'test name#0 data',
'value' => 'test value#0 data'
},
{
'expirationTime' => '2067-01-12T04:20:32+00:00',
'name' => 'test name#1 data',
'value' => 'test value#1 data'
},
{
'expirationTime' => '2115-07-20T06:30:48+00:00',
'name' => 'test name#2 data',
'value' => 'test value#2 data'
}
],
'requireSsl' => true
},
'tier' => 'test tier#0 data',
'settingsVersion' => 1_508_110_470
}
},
name: 'title0'
- 10
expect_network_get_async 1, name: 'title0'
# rubocop:enable Metrics/LineLength
end
- 1
let(:runner) do
# This path ensures that the current cookbook is
# loaded for testing.
# This path will load all other cookbooks in the
# parent directory.
# Under most circumstances, this will include the
# real google-gauth cookbook.
- 10
parent_dir = File.join(File.dirname(__FILE__), '..', '..')
- 10
cookbook_paths = [parent_dir]
# If there's no real version of the google-gauth ,
# add in the mocked version so that the tests do not fail.
# Since cookbooks can have any name, we assume that
# any directory with the word auth is the google-gauth cookbook.
- 10
cookbook_paths << File.join(File.dirname(__FILE__), 'cookbooks')
- 10
ChefSpec::SoloRunner.new(
step_into: 'gsql_instance',
cookbook_path: cookbook_paths,
platform: 'ubuntu',
version: '16.04'
)
end
- 1
let(:chef_run) do
apply_recipe(
<<-MANIFEST
gsql_instance 'title0' do
action :create
backend_type 'FIRST_GEN'
connection_name 'test connection_name#0 data'
database_version 'MYSQL_5_5'
failover_replica({
available: true,
name: 'test name#0 data'
})
instance_type 'CLOUD_SQL_INSTANCE'
ipv6_address 'test ipv6_address#0 data'
master_instance_name 'test master_instance_name#0 data'
max_disk_size 399168897
region 'test region#0 data'
replica_configuration({
failover_target: true,
mysql_replica_configuration: {
ca_certificate: 'test ca_certificate#0 data',
client_certificate: 'test client_certificate#0 data',
client_key: 'test client_key#0 data',
connect_retry_interval: 586223489,
dump_file_path: 'test dump_file_path#0 data',
master_heartbeat_period: 2641537687,
password: 'test password#0 data',
ssl_cipher: 'test ssl_cipher#0 data',
username: 'test username#0 data',
verify_server_certificate: true
},
replica_names: ['ee', 'ff', 'gg', 'hh'],
service_account_email_address: 'test service_account_email_address#0 data'
})
settings({
ip_configuration: {
authorized_networks: [
{
expiration_time: '2018-07-08T02:10:16+00:00',
name: 'test name#0 data',
value: 'test value#0 data'
},
{
expiration_time: '2067-01-12T04:20:32+00:00',
name: 'test name#1 data',
value: 'test value#1 data'
},
{
expiration_time: '2115-07-20T06:30:48+00:00',
name: 'test name#2 data',
value: 'test value#2 data'
}
],
ipv4_enabled: true,
require_ssl: true
},
settings_version: 1508110470,
tier: 'test tier#0 data'
})
project 'test project#0 data'
credential 'mycred'
end
MANIFEST
- 10
) do |recipe_name|
- 10
runner.converge(recipe_name) do
- 10
cred = Google::CredentialResourceMock.new('mycred',
runner.run_context)
- 10
runner.resource_collection.insert(cred)
end
end
end
- 1
subject do
- 9
chef_run.find_resource(:gsql_instance, 'title0')
end
- 1
it 'should run test correctly' do
- 1
expect(chef_run).to create(:gsql_instance,
'title0')
end
- 2
it { is_expected.to have_attributes(backend_type: 'FIRST_GEN') }
- 2
it { is_expected.to have_attributes(connection_name: 'test connection_name#0 data') }
- 2
it { is_expected.to have_attributes(database_version: 'MYSQL_5_5') }
# TODO(nelsonjr): Implement complex nested property object test.
# it 'failoverReplica' do
# # Add test code here
# end
- 2
it { is_expected.to have_attributes(instance_type: 'CLOUD_SQL_INSTANCE') }
- 2
it { is_expected.to have_attributes(ipv6_address: 'test ipv6_address#0 data') }
- 1
it do
- 1
is_expected.to have_attributes(master_instance_name: 'test master_instance_name#0 data')
end
- 2
it { is_expected.to have_attributes(max_disk_size: 399_168_897) }
- 2
it { is_expected.to have_attributes(i_label: 'title0') }
- 2
it { is_expected.to have_attributes(region: 'test region#0 data') }
# TODO(nelsonjr): Implement complex nested property object test.
# it 'replicaConfiguration' do
# # Add test code here
# end
# TODO(nelsonjr): Implement complex nested property object test.
# it 'settings' do
# # Add test code here
# end
end
# Ensure present: resource missing, ignore, no name, fail
- 1
context 'title == name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
end
# Ensure present: resource missing, ignore, has name
- 1
context 'title != name' do
# Ensure present: resource missing, ignore, has name, pass
- 1
context 'title != name (pass)' do
- 1
before do
# rubocop:disable Metrics/LineLength
- 10
expect_network_get_failed 1
expect_network_create \
- 10
1,
'kind' => 'sql#instance',
'backendType' => 'FIRST_GEN',
'connectionName' => 'test connection_name#0 data',
'databaseVersion' => 'MYSQL_5_5',
'failoverReplica' => {
'available' => true,
'name' => 'test name#0 data'
},
'instanceType' => 'CLOUD_SQL_INSTANCE',
'ipv6Address' => 'test ipv6_address#0 data',
'masterInstanceName' => 'test master_instance_name#0 data',
'maxDiskSize' => 399_168_897,
'name' => 'test name#0 data',
'region' => 'test region#0 data',
'replicaConfiguration' => {
'failoverTarget' => true,
'mysqlReplicaConfiguration' => {
'caCertificate' => 'test ca_certificate#0 data',
'clientCertificate' => 'test client_certificate#0 data',
'clientKey' => 'test client_key#0 data',
'connectRetryInterval' => 586_223_489,
'dumpFilePath' => 'test dump_file_path#0 data',
'masterHeartbeatPeriod' => 2_641_537_687,
'password' => 'test password#0 data',
'sslCipher' => 'test ssl_cipher#0 data',
'username' => 'test username#0 data',
'verifyServerCertificate' => true
},
'replicaNames' => %w[ee ff gg hh],
'serviceAccountEmailAddress' => 'test service_account_email_address#0 data'
},
'settings' => {
'ipConfiguration' => {
'ipv4Enabled' => true,
'authorizedNetworks' => [
{
'expirationTime' => '2018-07-08T02:10:16+00:00',
'name' => 'test name#0 data',
'value' => 'test value#0 data'
},
{
'expirationTime' => '2067-01-12T04:20:32+00:00',
'name' => 'test name#1 data',
'value' => 'test value#1 data'
},
{
'expirationTime' => '2115-07-20T06:30:48+00:00',
'name' => 'test name#2 data',
'value' => 'test value#2 data'
}
],
'requireSsl' => true
},
'tier' => 'test tier#0 data',
'settingsVersion' => 1_508_110_470
}
- 10
expect_network_get_async 1
# rubocop:enable Metrics/LineLength
end
- 1
let(:runner) do
# This path ensures that the current cookbook is
# loaded for testing.
# This path will load all other cookbooks in the
# parent directory.
# Under most circumstances, this will include the
# real google-gauth cookbook.
- 10
parent_dir = File.join(File.dirname(__FILE__), '..', '..')
- 10
cookbook_paths = [parent_dir]
# If there's no real version of the google-gauth ,
# add in the mocked version so that the tests do not fail.
# Since cookbooks can have any name, we assume that
# any directory with the word auth is the google-gauth cookbook.
- 10
cookbook_paths << File.join(File.dirname(__FILE__), 'cookbooks')
- 10
ChefSpec::SoloRunner.new(
step_into: 'gsql_instance',
cookbook_path: cookbook_paths,
platform: 'ubuntu',
version: '16.04'
)
end
- 1
let(:chef_run) do
apply_recipe(
<<-MANIFEST
gsql_instance 'title0' do
action :create
backend_type 'FIRST_GEN'
connection_name 'test connection_name#0 data'
database_version 'MYSQL_5_5'
failover_replica({
available: true,
name: 'test name#0 data'
})
i_label 'test name#0 data'
instance_type 'CLOUD_SQL_INSTANCE'
ipv6_address 'test ipv6_address#0 data'
master_instance_name 'test master_instance_name#0 data'
max_disk_size 399168897
region 'test region#0 data'
replica_configuration({
failover_target: true,
mysql_replica_configuration: {
ca_certificate: 'test ca_certificate#0 data',
client_certificate: 'test client_certificate#0 data',
client_key: 'test client_key#0 data',
connect_retry_interval: 586223489,
dump_file_path: 'test dump_file_path#0 data',
master_heartbeat_period: 2641537687,
password: 'test password#0 data',
ssl_cipher: 'test ssl_cipher#0 data',
username: 'test username#0 data',
verify_server_certificate: true
},
replica_names: ['ee', 'ff', 'gg', 'hh'],
service_account_email_address: 'test service_account_email_address#0 data'
})
settings({
ip_configuration: {
authorized_networks: [
{
expiration_time: '2018-07-08T02:10:16+00:00',
name: 'test name#0 data',
value: 'test value#0 data'
},
{
expiration_time: '2067-01-12T04:20:32+00:00',
name: 'test name#1 data',
value: 'test value#1 data'
},
{
expiration_time: '2115-07-20T06:30:48+00:00',
name: 'test name#2 data',
value: 'test value#2 data'
}
],
ipv4_enabled: true,
require_ssl: true
},
settings_version: 1508110470,
tier: 'test tier#0 data'
})
project 'test project#0 data'
credential 'mycred'
end
MANIFEST
- 10
) do |recipe_name|
- 10
runner.converge(recipe_name) do
- 10
cred = Google::CredentialResourceMock.new('mycred',
runner.run_context)
- 10
runner.resource_collection.insert(cred)
end
end
end
- 1
subject do
- 9
chef_run.find_resource(:gsql_instance, 'title0')
end
- 1
it 'should run test correctly' do
- 1
expect(chef_run).to create(:gsql_instance,
'title0')
end
- 2
it { is_expected.to have_attributes(backend_type: 'FIRST_GEN') }
- 2
it { is_expected.to have_attributes(connection_name: 'test connection_name#0 data') }
- 2
it { is_expected.to have_attributes(database_version: 'MYSQL_5_5') }
# TODO(nelsonjr): Implement complex nested property object test.
# it 'failoverReplica' do
# # Add test code here
# end
- 2
it { is_expected.to have_attributes(instance_type: 'CLOUD_SQL_INSTANCE') }
- 2
it { is_expected.to have_attributes(ipv6_address: 'test ipv6_address#0 data') }
- 1
it do
- 1
is_expected.to have_attributes(master_instance_name: 'test master_instance_name#0 data')
end
- 2
it { is_expected.to have_attributes(max_disk_size: 399_168_897) }
- 2
it { is_expected.to have_attributes(i_label: 'test name#0 data') }
- 2
it { is_expected.to have_attributes(region: 'test region#0 data') }
# TODO(nelsonjr): Implement complex nested property object test.
# it 'replicaConfiguration' do
# # Add test code here
# end
# TODO(nelsonjr): Implement complex nested property object test.
# it 'settings' do
# # Add test code here
# end
end
# Ensure present: resource missing, ignore, has name, fail
- 1
context 'title != name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
end
end
end
- 1
context 'ensure == absent' do
- 1
context 'resource missing' do
# Ensure absent: resource missing, ignore, no name
- 1
context 'title == name' do
# Ensure absent: resource missing, ignore, no name, pass
- 1
context 'title == name (pass)' do
- 1
before do
expect_network_get_failed 1, name: 'title0'
end
- 1
let(:runner) do
# This path ensures that the current cookbook is
# loaded for testing.
# This path will load all other cookbooks in the
# parent directory.
# Under most circumstances, this will include the
# real google-gauth cookbook.
parent_dir = File.join(File.dirname(__FILE__), '..', '..')
cookbook_paths = [parent_dir]
# If there's no real version of the google-gauth ,
# add in the mocked version so that the tests do not fail.
# Since cookbooks can have any name, we assume that
# any directory with the word auth is the google-gauth cookbook.
cookbook_paths << File.join(File.dirname(__FILE__), 'cookbooks')
ChefSpec::SoloRunner.new(
step_into: 'gsql_instance',
cookbook_path: cookbook_paths,
platform: 'ubuntu',
version: '16.04'
)
end
- 1
let(:chef_run) do
apply_recipe(
<<-MANIFEST
gsql_instance 'title0' do
action :delete
project 'test project#0 data'
credential 'mycred'
end
MANIFEST
) do |recipe_name|
runner.converge(recipe_name) do
cred = Google::CredentialResourceMock.new('mycred',
runner.run_context)
runner.resource_collection.insert(cred)
end
end
end
- 1
subject do
chef_run.find_resource(:gsql_instance, 'title0')
end
end
# Ensure absent: resource missing, ignore, no name, fail
- 1
context 'title == name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
end
# Ensure absent: resource missing, ignore, has name
- 1
context 'title != name' do
# Ensure absent: resource missing, ignore, has name, pass
- 1
context 'title != name (pass)' do
- 1
before do
expect_network_get_failed 1
end
- 1
let(:runner) do
# This path ensures that the current cookbook is
# loaded for testing.
# This path will load all other cookbooks in the
# parent directory.
# Under most circumstances, this will include the
# real google-gauth cookbook.
parent_dir = File.join(File.dirname(__FILE__), '..', '..')
cookbook_paths = [parent_dir]
# If there's no real version of the google-gauth ,
# add in the mocked version so that the tests do not fail.
# Since cookbooks can have any name, we assume that
# any directory with the word auth is the google-gauth cookbook.
cookbook_paths << File.join(File.dirname(__FILE__), 'cookbooks')
ChefSpec::SoloRunner.new(
step_into: 'gsql_instance',
cookbook_path: cookbook_paths,
platform: 'ubuntu',
version: '16.04'
)
end
- 1
let(:chef_run) do
apply_recipe(
<<-MANIFEST
gsql_instance 'title0' do
action :delete
i_label 'test name#0 data'
project 'test project#0 data'
credential 'mycred'
end
MANIFEST
) do |recipe_name|
runner.converge(recipe_name) do
cred = Google::CredentialResourceMock.new('mycred',
runner.run_context)
runner.resource_collection.insert(cred)
end
end
end
- 1
subject do
chef_run.find_resource(:gsql_instance, 'title0')
end
end
# Ensure absent: resource missing, ignore, has name, fail
- 1
context 'title != name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
end
end
- 1
context 'resource exists' do
# Ensure absent: resource exists, ignore, no name
- 1
context 'title == name' do
# Ensure absent: resource exists, ignore, no name, pass
- 1
context 'title == name (pass)' do
- 1
before do
- 1
expect_network_get_success 1, name: 'title0'
- 1
expect_network_delete 1, 'title0'
- 1
expect_network_get_async 1, name: 'title0'
end
- 1
let(:runner) do
# This path ensures that the current cookbook is
# loaded for testing.
# This path will load all other cookbooks in the
# parent directory.
# Under most circumstances, this will include the
# real google-gauth cookbook.
- 1
parent_dir = File.join(File.dirname(__FILE__), '..', '..')
- 1
cookbook_paths = [parent_dir]
# If there's no real version of the google-gauth ,
# add in the mocked version so that the tests do not fail.
# Since cookbooks can have any name, we assume that
# any directory with the word auth is the google-gauth cookbook.
- 1
cookbook_paths << File.join(File.dirname(__FILE__), 'cookbooks')
- 1
ChefSpec::SoloRunner.new(
step_into: 'gsql_instance',
cookbook_path: cookbook_paths,
platform: 'ubuntu',
version: '16.04'
)
end
- 1
let(:chef_run) do
apply_recipe(
<<-MANIFEST
gsql_instance 'title0' do
action :delete
project 'test project#0 data'
credential 'mycred'
end
MANIFEST
- 1
) do |recipe_name|
- 1
runner.converge(recipe_name) do
- 1
cred = Google::CredentialResourceMock.new('mycred',
runner.run_context)
- 1
runner.resource_collection.insert(cred)
end
end
end
- 1
subject do
chef_run.find_resource(:gsql_instance, 'title0')
end
- 1
it 'should run test correctly' do
- 1
expect(chef_run).to delete(:gsql_instance,
'title0')
end
end
# Ensure absent: resource exists, ignore, no name, fail
- 1
context 'title == name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
end
# Ensure absent: resource exists, ignore, has name
- 1
context 'title != name' do
# Ensure absent: resource exists, ignore, has name, pass
- 1
context 'title != name (pass)' do
- 1
before do
- 1
expect_network_get_success 1
- 1
expect_network_delete 1
- 1
expect_network_get_async 1
end
- 1
let(:runner) do
# This path ensures that the current cookbook is
# loaded for testing.
# This path will load all other cookbooks in the
# parent directory.
# Under most circumstances, this will include the
# real google-gauth cookbook.
- 1
parent_dir = File.join(File.dirname(__FILE__), '..', '..')
- 1
cookbook_paths = [parent_dir]
# If there's no real version of the google-gauth ,
# add in the mocked version so that the tests do not fail.
# Since cookbooks can have any name, we assume that
# any directory with the word auth is the google-gauth cookbook.
- 1
cookbook_paths << File.join(File.dirname(__FILE__), 'cookbooks')
- 1
ChefSpec::SoloRunner.new(
step_into: 'gsql_instance',
cookbook_path: cookbook_paths,
platform: 'ubuntu',
version: '16.04'
)
end
- 1
let(:chef_run) do
apply_recipe(
<<-MANIFEST
gsql_instance 'title0' do
action :delete
i_label 'test name#0 data'
project 'test project#0 data'
credential 'mycred'
end
MANIFEST
- 1
) do |recipe_name|
- 1
runner.converge(recipe_name) do
- 1
cred = Google::CredentialResourceMock.new('mycred',
runner.run_context)
- 1
runner.resource_collection.insert(cred)
end
end
end
- 1
subject do
chef_run.find_resource(:gsql_instance, 'title0')
end
- 1
it 'should run test correctly' do
- 1
expect(chef_run).to delete(:gsql_instance,
'title0')
end
end
# Ensure absent: resource exists, ignore, has name, fail
- 1
context 'title != name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
end
end
end
- 1
def expand_variables(template, data, extra_data = {})
Google::GSQL::Instance
- 478
.action_class.expand_variables(template, data, extra_data)
end
- 1
def expect_network_get_success(id, data = {})
- 164
id_data = data.fetch(:name, '').include?('title') ? 'title' : 'name'
- 164
body = load_network_result("success#{id}~#{id_data}.yaml").to_json
- 164
request = double('request')
- 164
allow(request).to receive(:send).and_return(http_success(body))
- 164
debug_network "!! GET #{self_link(uri_data(id).merge(data))}"
- 164
expect(Google::Sql::Network::Get).to receive(:new)
.with(self_link(uri_data(id).merge(data)),
instance_of(Google::FakeAuthorization)) do |args|
- 164
debug_network ">> GET #{args}"
- 164
request
end
end
- 1
def http_success(body)
- 208
response = Net::HTTPOK.new(1.0, 200, 'OK')
- 208
response.body = body
- 208
response.instance_variable_set(:@read, true)
- 208
response
end
- 1
def expect_network_get_async(id, data = {})
- 22
body = { kind: 'sql#instance' }.to_json
- 22
request = double('request')
- 22
allow(request).to receive(:send).and_return(http_success(body))
- 22
debug_network "!! #{self_link(uri_data(id).merge(data))}"
- 22
expect(Google::Sql::Network::Get).to receive(:new)
.with(self_link(uri_data(id).merge(data)),
instance_of(Google::FakeAuthorization)) do |args|
- 22
debug_network ">> GET <async> #{args}"
- 22
request
end
end
- 1
def expect_network_get_failed(id, data = {})
- 20
request = double('request')
- 20
allow(request).to receive(:send).and_return(http_failed_object_missing)
- 20
debug_network "!! #{self_link(uri_data(id).merge(data))}"
- 20
expect(Google::Sql::Network::Get).to receive(:new)
.with(self_link(uri_data(id).merge(data)),
instance_of(Google::FakeAuthorization)) do |args|
- 20
debug_network ">> GET [failed] #{args}"
- 20
request
end
end
- 1
def http_failed_object_missing
- 20
Net::HTTPNotFound.new(1.0, 404, 'Not Found')
end
- 1
def expect_network_create(id, expected_body, data = {})
- 20
merged_uri = uri_data(id).merge(data)
- 20
body = { kind: 'sql#operation',
status: 'DONE', targetLink: self_link(merged_uri) }.to_json
- 20
request = double('request')
- 20
allow(request).to receive(:send).and_return(http_success(body))
- 20
debug_network "!! POST #{collection(merged_uri)}"
- 20
expect(Google::Sql::Network::Post).to receive(:new)
.with(collection(merged_uri), instance_of(Google::FakeAuthorization),
'application/json', expected_body.to_json) do |args|
- 20
debug_network ">> POST #{args} = body(#{body})"
- 20
request
end
end
- 1
def expect_network_delete(id, name = nil, data = {})
- 2
delete_data = uri_data(id).merge(data)
- 2
delete_data[:name] = name unless name.nil?
- 2
body = { kind: 'sql#operation',
status: 'DONE',
targetLink: self_link(delete_data) }.to_json
- 2
request = double('request')
- 2
allow(request).to receive(:send).and_return(http_success(body))
- 2
debug_network "!! DELETE #{self_link(delete_data)}"
- 2
expect(Google::Sql::Network::Delete).to receive(:new)
.with(self_link(delete_data),
instance_of(Google::FakeAuthorization)) do |args|
- 2
debug_network ">> DELETE #{args}"
- 2
request
end
end
- 1
def load_network_result(file)
- 164
results = File.join(File.dirname(__FILE__), 'data', 'network',
'gsql_instance', file)
- 164
debug("Loading result file: #{results}")
- 164
raise "Network result data file #{results}" unless File.exist?(results)
- 164
data = YAML.safe_load(File.read(results))
- 164
raise "Invalid network results #{results}" unless data.class <= Hash
- 164
data
end
- 1
def debug(message)
- 164
puts(message) if ENV['RSPEC_DEBUG']
end
- 1
def debug_network(message)
puts("Network #{message}") \
- 456
if ENV['RSPEC_DEBUG'] || ENV['RSPEC_HTTP_VERBOSE']
end
- 1
def collection(data)
- 40
URI.join(
'https://www.googleapis.com/sql/v1beta4/',
expand_variables(
'projects/{{project}}/instances',
data
)
)
end
- 1
def self_link(data)
- 438
URI.join(
'https://www.googleapis.com/sql/v1beta4/',
expand_variables(
'projects/{{project}}/instances/{{name}}',
data
)
)
end
# Creates variable test data to comply with self_link URI parameters
- 1
def uri_data(id)
- 434
{
- 434
project: GoogleTests::Constants::I_PROJECT_DATA[(id - 1) \
% GoogleTests::Constants::I_PROJECT_DATA.size],
- 434
name: GoogleTests::Constants::I_NAME_DATA[(id - 1) \
% GoogleTests::Constants::I_NAME_DATA.size]
}
end
- 1
def build_cred
- 76
<<-CRED
gauth_credential 'mycred' do
action :serviceaccount
path '/home'
scopes [
'test_path'
]
end
CRED
end
# Creates a test recipe file and runs a block before destroying the file
- 1
def apply_recipe(recipe)
# Creates a random string name
- 684
recipe_name = "recipe~test~#{(0...8).map { (65 + rand(26)).chr }.join}"
- 76
recipe_loc = File.join(File.dirname(__FILE__), '..', 'recipes',
"#{recipe_name}.rb")
- 76
File.open(recipe_loc, 'w') do |file|
- 76
file.write([build_cred, recipe].join("\n"))
end
- 76
recipe_path = "google-gsql::#{recipe_name}"
- 76
begin
- 76
yield recipe_path
ensure
- 76
File.delete(recipe_loc)
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
require 'net/http'
- 1
require 'singleton'
- 1
module Google
- 1
module Sql
# A helper class to block access to the network during tests, while
# providing a whitelist escape for the
# Google::Sql::Network::* classes to test themselves, also
# without accessing the network.
- 1
class NetworkBlocker
- 1
include Singleton
- 1
ALLOWED_TEST_URI = URI.parse('https://www.unreachable-test-host.com/blah')
- 1
attr_reader :allowed_test_hosts
- 1
attr_reader :allowed_request
- 1
attr_reader :canned_response
- 1
def initialize
- 1
@allowed_test_hosts = [
{ host: ALLOWED_TEST_URI.host, port: ALLOWED_TEST_URI.port }
]
end
- 1
def allow_get(uri, code, type, body)
- 8
@allowed_request = { uri: uri }
- 8
@canned_response = response(uri, code, type, body)
end
- 1
def allow_delete(uri)
- 3
@allowed_request = { uri: uri }
- 3
@canned_response = Net::HTTPNoContent.new(1.0, 204, 'No Content')
end
- 1
def allow_post(args)
- 14
@allowed_request = {
uri: args[:uri_in],
type: args[:type_in],
body: args[:body_in]
}
- 14
@canned_response = response(args[:uri_out], args[:code],
args[:type_out], args[:body_out])
end
- 1
def allow_put(args)
- 5
allow_post(args) # PUT uses same interface as POST
end
- 1
def deny(uri, code = 404)
- 8
case code
when 404
- 8
@allowed_request = { uri: uri }
- 8
@canned_response = Net::HTTPNotFound.new(1.0, 404, 'Not Found')
else
raise ArgumentError, "Unknown error code #{code}"
end
end
- 1
private
- 1
def response(uri, code, type, body)
- 22
response = Net::HTTPOK.new(1.0, code, 'OK')
- 22
response.uri = uri
- 22
response.content_type = type
- 22
response.body = body
- 22
response.instance_variable_set(:@read, true)
- 22
response
end
end
end
end
# Monkey patching of core Net::HTTP components to trap and block all network
# access, except to return canned responses when using the magic
# ALLOWED_TEST_URI URL.
- 1
module Net
- 1
class HTTP
- 1
define_method(:initialize) do |*args|
- 41
blocker = Google::Sql::NetworkBlocker.instance
- 156
unless blocker.allowed_test_hosts.map { |h| h[:host] }.include?(args[0])
- 8
message = [self, __method__, ':',
'Network traffic is blocked during tests', ':',
args[0]].join(' ')
- 8
if ENV['RSPEC_DEBUG']
module_dir = File.expand_path('..', File.dirname(__FILE__))
puts [message, caller.select { |c| c.include?(module_dir) }
.join("\n").gsub(/^/, ' ')].join("\n")
end
- 8
raise IOError, message
end
end
- 1
instance_methods.each do |m|
unless %i[get copy delete finish get get2 head head2 lock mkcol move
options patch post post2 propfind proppatch put put2 request
request_get request_head request_post request_put send
- 151
send_request start trace unlock].include?(m)
- 123
next
end
# rubocop:disable Metrics/MethodLength
- 28
define_method(m) do |*args|
- 32
request_allowed = true
- 32
blocker = Google::Sql::NetworkBlocker.instance
- 32
if !args.empty? && args[0].is_a?(Net::HTTPGenericRequest)
- 26
allow_terms = blocker.allowed_request
- 26
allow_terms.each_key do |key|
- 46
case key
when :uri
- 26
request_allowed &&= args[0].uri == allow_terms[:uri]
when :type
- 10
request_allowed &&= args[0].content_type == allow_terms[:type]
when :body
- 10
request_allowed &&= args[0].body == allow_terms[:body]
end
end
end
# rubocop:enable Metrics/MethodLength
- 32
return blocker.canned_response if request_allowed
raise IOError, [self, __method__, ':',
'Network traffic is blocked during tests', ':',
args[0]].join(' ')
end
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
require 'spec_helper'
- 1
TEST_URI = URI.parse('https://google.com')
- 1
describe Google::Sql::NetworkBlocker do
- 7
let(:uri) { described_class::ALLOWED_TEST_URI }
- 1
context '#allow_get' do
- 1
before(:each) do
- 1
described_class.instance.allow_get(uri, 200, 'text/html', 'hello')
end
- 2
subject { Net::HTTP.get(uri) }
- 2
it { is_expected.to eq 'hello' }
end
- 1
context '#allow_post' do
- 1
before(:each) do
- 4
described_class.instance.allow_post(
uri_in: uri, type_in: 'text/plain', body_in: 'my input',
code: 200, uri_out: uri, type_out: 'text/html', body_out: '<html/>'
)
end
- 5
subject { Net::HTTP.post_form(uri, q: 'query') }
- 2
it { is_expected.to be_a Net::HTTPOK }
- 2
it { is_expected.to have_attributes content_type: 'text/html' }
- 2
it { is_expected.to have_attributes code: 200 }
- 2
it { is_expected.to have_attributes body: '<html/>' }
end
- 1
context '#allow_delete' do
- 1
before(:each) do
- 1
described_class.instance.allow_delete(uri)
end
- 1
subject do
- 1
Net::HTTP.new(uri.host, uri.port).request(Net::HTTP::Delete.new(uri))
end
- 2
it { is_expected.to be_a Net::HTTPNoContent }
end
- 1
context '#allowed_test_hosts' do
- 3
let(:uri) { URI.parse('http://some-other-site.com') }
- 1
before(:each) do
- 2
described_class.instance.allow_get(uri, 200, 'text/html', 'hello')
end
- 1
context 'failed without #allowed_test_hosts update' do
- 3
subject { -> { Net::HTTP.get(uri) } }
- 2
it { is_expected.to raise_error(IOError) }
end
- 1
context '#allowed_test_hosts' do
- 1
before(:each) do
- 1
described_class.instance.allowed_test_hosts << \
{ host: uri.host, port: uri.port }
end
- 3
subject { -> { Net::HTTP.get(uri) } }
- 2
it { is_expected.not_to raise_error }
end
end
end
- 1
describe Net::HTTP do
- 1
context '#new' do
- 3
subject { -> { described_class.new(TEST_URI) } }
- 2
it { is_expected.to raise_error(IOError, /traffic.*blocked/) }
end
# Shortcut form for Net::HTTP::Get
- 1
context '#get' do
- 3
subject { -> { described_class.get(TEST_URI) } }
- 2
it { is_expected.to raise_error(IOError, /traffic.*blocked/) }
end
# Shortcut form for Net::HTTP::Get
- 1
context '#get_response' do
- 3
subject { -> { described_class.get_response(TEST_URI) } }
- 2
it { is_expected.to raise_error(IOError, /traffic.*blocked/) }
end
# Shortcut form for Net::HTTP::Post
- 1
context '#post_form' do
- 1
subject do
- 1
lambda do
- 1
described_class.post_form(TEST_URI, q: 'My query', per_page: 50)
end
end
- 2
it { is_expected.to raise_error(IOError, /traffic.*blocked/) }
end
end
- 1
context Net::HTTP::Get do
- 1
subject do
- 1
lambda do
- 1
http = Net::HTTP.new(TEST_URI.host, TEST_URI.port)
http.request(Net::HTTP::Get.new(TEST_URI.request_uri))
end
end
- 2
it { is_expected.to raise_error(IOError, /traffic.*blocked/) }
end
- 1
context Net::HTTP::Post do
- 1
subject do
- 1
lambda do
- 1
http = Net::HTTP.new(TEST_URI.host, TEST_URI.port)
request = Net::HTTP::Post.new(TEST_URI.request_uri)
request.set_form_data(q: 'My query', per_page: 50)
http.request(request)
end
end
- 2
it { is_expected.to raise_error(IOError, /traffic.*blocked/) }
end
- 1
context Net::HTTP::Delete do
- 1
subject do
- 1
lambda do
- 1
http = Net::HTTP.new(TEST_URI.host, TEST_URI.port)
http.request(Net::HTTP::Delete.new(TEST_URI.request_uri))
end
end
- 2
it { is_expected.to raise_error(IOError, /traffic.*blocked/) }
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
require 'spec_helper'
- 1
class TestCred
- 1
def authorize(request)
request
end
end
- 1
describe Google::Sql::Network::Delete do
- 5
let(:credential) { TestCred.new }
- 5
let(:uri) { Google::Sql::NetworkBlocker::ALLOWED_TEST_URI }
- 1
context 'verify proper request' do
- 3
before(:each) { Google::Sql::NetworkBlocker.instance.allow_delete(uri) }
- 3
subject { described_class.new(uri, credential).send }
- 2
it { is_expected.to be_a_kind_of(Net::HTTPNoContent) }
- 2
it { is_expected.to have_attributes(code: 204) }
end
- 1
context 'failed request' do
- 3
before(:each) { Google::Sql::NetworkBlocker.instance.deny(uri) }
- 3
subject { described_class.new(uri, credential).send }
- 2
it { is_expected.to be_a_kind_of(Net::HTTPNotFound) }
- 2
it { is_expected.to have_attributes(code: 404) }
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
require 'spec_helper'
- 1
require 'uri'
- 1
class TestCred
- 1
def authorize(request)
request
end
end
- 1
describe Google::Sql::Network::Get do
- 8
let(:credential) { TestCred.new }
- 8
let(:uri) { Google::Sql::NetworkBlocker::ALLOWED_TEST_URI }
- 1
context 'successful request' do
- 1
before(:each) do
- 5
Google::Sql::NetworkBlocker.instance.allow_get(
uri, 200, 'application/myfooapp', { field1: 'FOOBAR' }.to_json
)
end
- 6
subject { described_class.new(uri, credential).send }
- 2
it { is_expected.to be_a_kind_of(Net::HTTPResponse) }
- 2
it { is_expected.to have_attributes(body: { field1: 'FOOBAR' }.to_json) }
- 2
it { is_expected.to have_attributes(code: 200) }
- 2
it { is_expected.to have_attributes(content_type: 'application/myfooapp') }
- 2
it { is_expected.to have_attributes(uri: uri) }
end
- 1
context 'failed request' do
- 3
before(:each) { Google::Sql::NetworkBlocker.instance.deny(uri) }
- 3
subject { described_class.new(uri, credential).send }
- 2
it { is_expected.to be_a_kind_of(Net::HTTPNotFound) }
- 2
it { is_expected.to have_attributes(code: 404) }
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
require 'spec_helper'
- 1
require 'uri'
- 1
class TestCred
- 1
def authorize(request)
request
end
end
- 1
describe Google::Sql::Network::Post do
- 8
let(:credential) { TestCred.new }
- 8
let(:uri_in) { Google::Sql::NetworkBlocker::ALLOWED_TEST_URI }
- 6
let(:uri_out) { URI.parse('https://somewhere.else.com/some/path') }
- 8
let(:type_in) { 'application/myapp-request' }
- 6
let(:type_out) { 'application/myapp-response' }
- 8
let(:body_in) { { 'test1' => 'test' }.to_json }
- 6
let(:body_out) { { field1: 'WORKS' }.to_json }
- 1
context 'successful request' do
- 1
before(:each) do
- 5
Google::Sql::NetworkBlocker.instance.allow_post(
uri_in: uri_in, type_in: type_in, body_in: body_in,
code: 200, uri_out: uri_out, type_out: type_out, body_out: body_out
)
end
- 6
subject { described_class.new(uri_in, credential, type_in, body_in).send }
- 2
it { is_expected.to be_a_kind_of(Net::HTTPOK) }
- 2
it { is_expected.to have_attributes(code: 200) }
- 2
it { is_expected.to have_attributes(uri: uri_out) }
- 2
it { is_expected.to have_attributes(content_type: type_out) }
- 2
it { is_expected.to have_attributes(body: body_out) }
end
- 1
context 'failed request' do
- 3
before(:each) { Google::Sql::NetworkBlocker.instance.deny(uri_in) }
- 3
subject { described_class.new(uri_in, credential, type_in, body_in).send }
- 2
it { is_expected.to be_a_kind_of(Net::HTTPNotFound) }
- 2
it { is_expected.to have_attributes(code: 404) }
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
require 'spec_helper'
- 1
require 'uri'
- 1
class TestCred
- 1
def authorize(request)
- 25
request
end
end
- 1
describe Google::Sql::Network::Put do
- 8
let(:credential) { TestCred.new }
- 8
let(:uri_in) { Google::Sql::NetworkBlocker::ALLOWED_TEST_URI }
- 6
let(:uri_out) { URI.parse('https://somewhere.else.com/some/path') }
- 8
let(:type_in) { 'application/myapp-request' }
- 6
let(:type_out) { 'application/myapp-response' }
- 8
let(:body_in) { { 'test1' => 'test' }.to_json }
- 6
let(:body_out) { { field1: 'WORKS' }.to_json }
- 1
context 'successful request' do
- 1
before(:each) do
- 5
Google::Sql::NetworkBlocker.instance.allow_put(
uri_in: uri_in, type_in: type_in, body_in: body_in,
code: 200, uri_out: uri_out, type_out: type_out, body_out: body_out
)
end
- 6
subject { described_class.new(uri_in, credential, type_in, body_in).send }
- 2
it { is_expected.to be_a_kind_of(Net::HTTPOK) }
- 2
it { is_expected.to have_attributes(code: 200) }
- 2
it { is_expected.to have_attributes(uri: uri_out) }
- 2
it { is_expected.to have_attributes(content_type: type_out) }
- 2
it { is_expected.to have_attributes(body: body_out) }
end
- 1
context 'failed request' do
- 3
before(:each) { Google::Sql::NetworkBlocker.instance.deny(uri_in) }
- 3
subject { described_class.new(uri_in, credential, type_in, body_in).send }
- 2
it { is_expected.to be_a_kind_of(Net::HTTPNotFound) }
- 2
it { is_expected.to have_attributes(code: 404) }
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
require 'spec_helper'
# TODO(alexstephen): Reformat tests to use nested describe blocks
# TODO(alexstephen): Add title == name tests
# Test Matrix:
#
# +--------------------------------------------------------+
# | Action | Exists | Changes | Success | Result |
# +--------------------------------------------------------+
# | create | Y | Y | Y | Edit |
# | create | Y | Y | N | Fail |
# | create | Y | N | Y | Fetch (no-op) |
# | create | Y | N | N | Fail |
# | create | N | Y | Y | Create |
# | create | N | Y | N | Fail |
# +--------------------------------------------------------+
# | delete | Y | Y | Y | Delete |
# | delete | Y | Y | N | Fail |
# | delete | N | Y | Y | Fail (no delete)|
# | delete | N | Y | N | Fail |
# +--------------------------------------------------------+
# TODO(alexstephen): Add tests for manage
# TODO(alexstephen): Add tests for modify
- 1
context 'gsql_ssl_cert' do
- 1
context 'resource exists' do
# Ensure ignore: resource exists, no change
- 1
context 'no changes == no action' do
# Ensure ignore: resource exists, no change, no name, pass
- 1
context 'title == name (pass)' do
# TODO(alexstephen): Implement new test format.
end
# Ensure ignore: resource exists, no change, has name, pass
- 1
context 'title != name (pass)' do
# TODO(alexstephen): Implement new test format.
end
end
# Ensure ignore: resource exists, changes
- 1
context 'changes == action' do
# Ensure ignore: resource exists, changes, no name, fail
- 1
context 'title == name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
# Ensure ignore: resource exists, changes, has name, fail
- 1
context 'title != name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
end
end
- 1
context 'resource missing' do
# Ensure ignore: resource missing, ignore, no name, fail
- 1
context 'title == name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
# Ensure ignore: resource missing, ignore, has name, fail
- 1
context 'title != name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
end
- 1
def expand_variables(template, data, extra_data = {})
Google::GSQL::SslCert
.action_class.expand_variables(template, data, extra_data)
end
- 1
def expect_network_get_success(id, data = {})
id_data = data.fetch(:name, '').include?('title') ? 'title' : 'name'
body = load_network_result("success#{id}~#{id_data}.yaml").to_json
request = double('request')
allow(request).to receive(:send).and_return(http_success(body))
debug_network "!! GET #{self_link(uri_data(id).merge(data))}"
expect(Google::Sql::Network::Get).to receive(:new)
.with(self_link(uri_data(id).merge(data)),
instance_of(Google::FakeAuthorization)) do |args|
debug_network ">> GET #{args}"
request
end
end
- 1
def http_success(body)
response = Net::HTTPOK.new(1.0, 200, 'OK')
response.body = body
response.instance_variable_set(:@read, true)
response
end
- 1
def expect_network_get_failed(id, data = {})
request = double('request')
allow(request).to receive(:send).and_return(http_failed_object_missing)
debug_network "!! #{self_link(uri_data(id).merge(data))}"
expect(Google::Sql::Network::Get).to receive(:new)
.with(self_link(uri_data(id).merge(data)),
instance_of(Google::FakeAuthorization)) do |args|
debug_network ">> GET [failed] #{args}"
request
end
end
- 1
def http_failed_object_missing
Net::HTTPNotFound.new(1.0, 404, 'Not Found')
end
- 1
def load_network_result(file)
results = File.join(File.dirname(__FILE__), 'data', 'network',
'gsql_ssl_cert', file)
debug("Loading result file: #{results}")
raise "Network result data file #{results}" unless File.exist?(results)
data = YAML.safe_load(File.read(results))
raise "Invalid network results #{results}" unless data.class <= Hash
data
end
- 1
def expect_network_get_success_instance(id, data = {})
id_data = data.fetch(:name, '').include?('title') ? 'title' : 'name'
body = load_network_result_instance("success#{id}~" \
"#{id_data}.yaml")
.to_json
uri = uri_data_instance(id).merge(data)
request = double('request')
allow(request).to receive(:send).and_return(http_success(body))
debug_network "!! GET #{uri}"
expect(Google::Sql::Network::Get).to receive(:new)
.with(self_link_instance(uri),
instance_of(Google::FakeAuthorization)) do |args|
debug_network ">> GET #{args}"
request
end
end
- 1
def load_network_result_instance(file)
results = File.join(File.dirname(__FILE__), 'data', 'network',
'gsql_instance', file)
raise "Network result data file #{results}" unless File.exist?(results)
data = YAML.safe_load(File.read(results))
raise "Invalid network results #{results}" unless data.class <= Hash
data
end
# Creates variable test data to comply with self_link URI parameters
# Only used for gsql_instance objects
- 1
def uri_data_instance(id)
{
project: GoogleTests::Constants::I_PROJECT_DATA[(id - 1) \
% GoogleTests::Constants::I_PROJECT_DATA.size],
name: GoogleTests::Constants::I_NAME_DATA[(id - 1) \
% GoogleTests::Constants::I_NAME_DATA.size]
}
end
- 1
def self_link_instance(data)
URI.join(
'https://www.googleapis.com/sql/v1beta4/',
expand_variables_instance(
'projects/{{project}}/instances/{{name}}',
data
)
)
end
- 1
def debug(message)
puts(message) if ENV['RSPEC_DEBUG']
end
- 1
def debug_network(message)
puts("Network #{message}") \
if ENV['RSPEC_DEBUG'] || ENV['RSPEC_HTTP_VERBOSE']
end
- 1
def expand_variables_instance(template, data, ext_dat = {})
Google::GSQL::Instance
.action_class.expand_variables(template, data, ext_dat)
end
- 1
def collection(data)
URI.join(
'https://www.googleapis.com/sql/v1beta4/',
expand_variables(
'projects/{{project}}/instances/{{instance}}/sslCerts',
data
)
)
end
- 1
def self_link(data)
URI.join(
'https://www.googleapis.com/sql/v1beta4/',
expand_variables(
[
'projects/{{project}}/instances/{{instance}}/sslCerts/',
'{{sha1_fingerprint}}'
].join,
data
)
)
end
# Creates variable test data to comply with self_link URI parameters
- 1
def uri_data(id)
{
project: GoogleTests::Constants::SC_PROJECT_DATA[(id - 1) \
% GoogleTests::Constants::SC_PROJECT_DATA.size],
instance: GoogleTests::Constants::SC_INSTANCE_DATA[(id - 1) \
% GoogleTests::Constants::SC_INSTANCE_DATA.size],
sha1_fingerprint: GoogleTests::Constants::SC_SHA1_FINGERPRINT_DATA[(id - 1) \
% GoogleTests::Constants::SC_SHA1_FINGERPRINT_DATA.size]
}
end
- 1
def build_cred
<<-CRED
gauth_credential 'mycred' do
action :serviceaccount
path '/home'
scopes [
'test_path'
]
end
CRED
end
# Creates a test recipe file and runs a block before destroying the file
- 1
def apply_recipe(recipe)
# Creates a random string name
recipe_name = "recipe~test~#{(0...8).map { (65 + rand(26)).chr }.join}"
recipe_loc = File.join(File.dirname(__FILE__), '..', 'recipes',
"#{recipe_name}.rb")
File.open(recipe_loc, 'w') do |file|
file.write([build_cred, recipe].join("\n"))
end
recipe_path = "google-gsql::#{recipe_name}"
begin
yield recipe_path
ensure
File.delete(recipe_loc)
end
end
end
# Copyright 2017 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
- 1
require 'spec_helper'
- 1
describe Google::StringUtils do
- 1
context '#camelize' do
- 2
subject { described_class.camelize('some_string_with_underscores') }
- 2
it { is_expected.to eq 'someStringWithUnderscores' }
end
- 1
context '#underscore' do
- 2
subject { described_class.underscore('aStringInCamelCase') }
- 2
it { is_expected.to eq 'a_string_in_camel_case' }
end
- 1
context '#first_sentence' do
- 1
context 'sentence end with period' do
- 1
subject do
- 1
described_class.first_sentence('Lorem ipsum. Dolor sit amet. Elit')
end
- 2
it { is_expected.to eq 'Lorem ipsum.' }
end
- 1
context 'sentence end with question mark' do
- 1
subject do
- 1
described_class.first_sentence('Lorem ipsum? Dolor sit amet. Elit')
end
- 2
it { is_expected.to eq 'Lorem ipsum?' }
end
- 1
context 'sentence end with exclamation mark' do
- 1
subject do
- 1
described_class.first_sentence('Lorem ipsum! Dolor sit amet. Elit')
end
- 2
it { is_expected.to eq 'Lorem ipsum!' }
end
- 1
context 'no period returns full string' do
- 2
subject { described_class.first_sentence('Lorem ipsum dolor') }
- 2
it { is_expected.to eq 'Lorem ipsum dolor' }
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
module GoogleTests
- 1
module Constants
# Constants for: Instance.project
- 1
I_PROJECT_DATA = [
'test project#0 data',
'test project#1 data',
'test project#2 data',
'test project#3 data',
'test project#4 data'
].freeze
# Constants for: Instance.name
- 1
I_NAME_DATA = [
'test name#0 data',
'test name#1 data',
'test name#2 data',
'test name#3 data',
'test name#4 data'
].freeze
# Constants for: Database.project
- 1
D_PROJECT_DATA = [
'test project#0 data',
'test project#1 data',
'test project#2 data',
'test project#3 data',
'test project#4 data'
].freeze
# Constants for: Database.instance
- 1
D_INSTANCE_DATA = [
'test name#0 data',
'test name#1 data',
'test name#2 data',
'test name#3 data',
'test name#4 data'
].freeze
# Constants for: Database.name
- 1
D_NAME_DATA = [
'test name#0 data',
'test name#1 data',
'test name#2 data',
'test name#3 data',
'test name#4 data'
].freeze
# Constants for: User.project
- 1
U_PROJECT_DATA = [
'test project#0 data',
'test project#1 data',
'test project#2 data',
'test project#3 data',
'test project#4 data'
].freeze
# Constants for: User.instance
- 1
U_INSTANCE_DATA = [
'test name#0 data',
'test name#1 data',
'test name#2 data',
'test name#3 data',
'test name#4 data'
].freeze
# Constants for: User.name
- 1
U_NAME_DATA = [
'test name#0 data',
'test name#1 data',
'test name#2 data',
'test name#3 data',
'test name#4 data'
].freeze
# Constants for: User.host
- 1
U_HOST_DATA = [
'test host#0 data',
'test host#1 data',
'test host#2 data',
'test host#3 data',
'test host#4 data'
].freeze
# Constants for: SslCert.project
- 1
SC_PROJECT_DATA = [
'test project#0 data',
'test project#1 data',
'test project#2 data',
'test project#3 data',
'test project#4 data'
].freeze
# Constants for: SslCert.instance
- 1
SC_INSTANCE_DATA = [
'test name#0 data',
'test name#1 data',
'test name#2 data',
'test name#3 data',
'test name#4 data'
].freeze
# Constants for: SslCert.sha1_fingerprint
- 1
SC_SHA1_FINGERPRINT_DATA = [
'test sha1_fingerprint#0 data',
'test sha1_fingerprint#1 data',
'test sha1_fingerprint#2 data',
'test sha1_fingerprint#3 data',
'test sha1_fingerprint#4 data'
].freeze
# Constants for: Tier.project
- 1
T_PROJECT_DATA = [
'test project#0 data',
'test project#1 data',
'test project#2 data',
'test project#3 data',
'test project#4 data'
].freeze
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
require 'spec_helper'
# TODO(alexstephen): Reformat tests to use nested describe blocks
# TODO(alexstephen): Add title == name tests
# Test Matrix:
#
# +--------------------------------------------------------+
# | Action | Exists | Changes | Success | Result |
# +--------------------------------------------------------+
# | create | Y | Y | Y | Edit |
# | create | Y | Y | N | Fail |
# | create | Y | N | Y | Fetch (no-op) |
# | create | Y | N | N | Fail |
# | create | N | Y | Y | Create |
# | create | N | Y | N | Fail |
# +--------------------------------------------------------+
# | delete | Y | Y | Y | Delete |
# | delete | Y | Y | N | Fail |
# | delete | N | Y | Y | Fail (no delete)|
# | delete | N | Y | N | Fail |
# +--------------------------------------------------------+
# TODO(alexstephen): Add tests for manage
# TODO(alexstephen): Add tests for modify
- 1
context 'gsql_tier' do
- 1
context 'resource exists' do
# Ensure ignore: resource exists, no change
- 1
context 'no changes == no action' do
# Ensure ignore: resource exists, no change, no name, pass
- 1
context 'title == name (pass)' do
# TODO(alexstephen): Implement new test format.
end
# Ensure ignore: resource exists, no change, has name, pass
- 1
context 'title != name (pass)' do
# TODO(alexstephen): Implement new test format.
end
end
# Ensure ignore: resource exists, changes
- 1
context 'changes == action' do
# Ensure ignore: resource exists, changes, no name, fail
- 1
context 'title == name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
# Ensure ignore: resource exists, changes, has name, fail
- 1
context 'title != name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
end
end
- 1
context 'resource missing' do
# Ensure ignore: resource missing, ignore, no name, fail
- 1
context 'title == name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
# Ensure ignore: resource missing, ignore, has name, fail
- 1
context 'title != name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
end
- 1
def expand_variables(template, data, extra_data = {})
Google::GSQL::Tier
.action_class.expand_variables(template, data, extra_data)
end
- 1
def expect_network_get_success(id, data = {})
id_data = data.fetch(:name, '').include?('title') ? 'title' : 'name'
body = load_network_result("success#{id}~#{id_data}.yaml").to_json
request = double('request')
allow(request).to receive(:send).and_return(http_success(body))
debug_network "!! GET #{self_link(uri_data(id).merge(data))}"
expect(Google::Sql::Network::Get).to receive(:new)
.with(self_link(uri_data(id).merge(data)),
instance_of(Google::FakeAuthorization)) do |args|
debug_network ">> GET #{args}"
request
end
end
- 1
def http_success(body)
response = Net::HTTPOK.new(1.0, 200, 'OK')
response.body = body
response.instance_variable_set(:@read, true)
response
end
- 1
def expect_network_get_failed(id, data = {})
request = double('request')
allow(request).to receive(:send).and_return(http_failed_object_missing)
debug_network "!! #{self_link(uri_data(id).merge(data))}"
expect(Google::Sql::Network::Get).to receive(:new)
.with(self_link(uri_data(id).merge(data)),
instance_of(Google::FakeAuthorization)) do |args|
debug_network ">> GET [failed] #{args}"
request
end
end
- 1
def http_failed_object_missing
Net::HTTPNotFound.new(1.0, 404, 'Not Found')
end
- 1
def load_network_result(file)
results = File.join(File.dirname(__FILE__), 'data', 'network',
'gsql_tier', file)
debug("Loading result file: #{results}")
raise "Network result data file #{results}" unless File.exist?(results)
data = YAML.safe_load(File.read(results))
raise "Invalid network results #{results}" unless data.class <= Hash
data
end
- 1
def debug(message)
puts(message) if ENV['RSPEC_DEBUG']
end
- 1
def debug_network(message)
puts("Network #{message}") \
if ENV['RSPEC_DEBUG'] || ENV['RSPEC_HTTP_VERBOSE']
end
- 1
def collection(data)
URI.join(
'https://www.googleapis.com/sql/v1beta4/',
expand_variables(
'projects/{{project}}/tiers',
data
)
)
end
- 1
def self_link(data)
URI.join(
'https://www.googleapis.com/sql/v1beta4/',
expand_variables(
'projects/{{project}}/tiers',
data
)
)
end
# Creates variable test data to comply with self_link URI parameters
- 1
def uri_data(id)
{
project: GoogleTests::Constants::T_PROJECT_DATA[(id - 1) \
% GoogleTests::Constants::T_PROJECT_DATA.size]
}
end
- 1
def build_cred
<<-CRED
gauth_credential 'mycred' do
action :serviceaccount
path '/home'
scopes [
'test_path'
]
end
CRED
end
# Creates a test recipe file and runs a block before destroying the file
- 1
def apply_recipe(recipe)
# Creates a random string name
recipe_name = "recipe~test~#{(0...8).map { (65 + rand(26)).chr }.join}"
recipe_loc = File.join(File.dirname(__FILE__), '..', 'recipes',
"#{recipe_name}.rb")
File.open(recipe_loc, 'w') do |file|
file.write([build_cred, recipe].join("\n"))
end
recipe_path = "google-gsql::#{recipe_name}"
begin
yield recipe_path
ensure
File.delete(recipe_loc)
end
end
end
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in README.md and
# CONTRIBUTING.md located at the root of this package.
#
# ----------------------------------------------------------------------------
- 1
require 'spec_helper'
# TODO(alexstephen): Reformat tests to use nested describe blocks
# TODO(alexstephen): Add title == name tests
# Test Matrix:
#
# +--------------------------------------------------------+
# | Action | Exists | Changes | Success | Result |
# +--------------------------------------------------------+
# | create | Y | Y | Y | Edit |
# | create | Y | Y | N | Fail |
# | create | Y | N | Y | Fetch (no-op) |
# | create | Y | N | N | Fail |
# | create | N | Y | Y | Create |
# | create | N | Y | N | Fail |
# +--------------------------------------------------------+
# | delete | Y | Y | Y | Delete |
# | delete | Y | Y | N | Fail |
# | delete | N | Y | Y | Fail (no delete)|
# | delete | N | Y | N | Fail |
# +--------------------------------------------------------+
# TODO(alexstephen): Add tests for manage
# TODO(alexstephen): Add tests for modify
- 1
context 'gsql_user' do
- 1
context 'ensure == present' do
- 1
context 'resource exists' do
# Ensure present: resource exists, no change
- 1
context 'no changes == no action' do
# Ensure present: resource exists, no change, no name
- 1
context 'title == name' do
# Ensure present: resource exists, no change, no name, pass
- 1
context 'title == name (pass)' do
- 1
before do
- 9
allow(Time).to receive(:now).and_return(
Time.new(2017, 1, 2, 3, 4, 5)
)
- 9
expect_network_get_success 1, name: 'title0', instance: 'test name#0 data'
- 9
expect_network_get_success 2, name: 'title1', instance: 'test name#1 data'
- 9
expect_network_get_success 3, name: 'title2', instance: 'test name#2 data'
- 9
expect_network_get_success_instance 1
- 9
expect_network_get_success_instance 2
- 9
expect_network_get_success_instance 3
end
- 1
let(:runner) do
# This path ensures that the current cookbook is
# loaded for testing.
# This path will load all other cookbooks in the
# parent directory.
# Under most circumstances, this will include the
# real google-gauth cookbook.
- 9
parent_dir = File.join(File.dirname(__FILE__), '..', '..')
- 9
cookbook_paths = [parent_dir]
# If there's no real version of the google-gauth ,
# add in the mocked version so that the tests do not fail.
# Since cookbooks can have any name, we assume that
# any directory with the word auth is the google-gauth cookbook.
- 9
cookbook_paths << File.join(File.dirname(__FILE__), 'cookbooks')
- 9
ChefSpec::SoloRunner.new(
step_into: %w[gsql_user gsql_instance],
cookbook_path: cookbook_paths,
platform: 'ubuntu',
version: '16.04'
)
end
- 1
let(:chef_run) do
apply_recipe(
<<-MANIFEST
gsql_instance 'resource(instance,0)' do
action :create
i_label 'test name#0 data'
project 'test project#0 data'
credential 'mycred'
end
gsql_instance 'resource(instance,1)' do
action :create
i_label 'test name#1 data'
project 'test project#1 data'
credential 'mycred'
end
gsql_instance 'resource(instance,2)' do
action :create
i_label 'test name#2 data'
project 'test project#2 data'
credential 'mycred'
end
gsql_user 'title0' do
action :create
host 'test host#0 data'
instance 'resource(instance,0)'
password 'test password#0 data'
project 'test project#0 data'
credential 'mycred'
end
gsql_user 'title1' do
action :create
host 'test host#1 data'
instance 'resource(instance,1)'
password 'test password#1 data'
project 'test project#1 data'
credential 'mycred'
end
gsql_user 'title2' do
action :create
host 'test host#2 data'
instance 'resource(instance,2)'
password 'test password#2 data'
project 'test project#2 data'
credential 'mycred'
end
MANIFEST
- 9
) do |recipe_name|
- 9
runner.converge(recipe_name) do
- 9
cred = Google::CredentialResourceMock.new('mycred',
runner.run_context)
- 9
runner.resource_collection.insert(cred)
end
end
end
- 1
context 'gsql_user[title0]' do
- 1
subject do
- 3
chef_run.find_resource(:gsql_user, 'title0')
end
- 2
it { is_expected.to have_attributes(host: 'test host#0 data') }
- 2
it { is_expected.to have_attributes(u_label: 'title0') }
# TODO(alexstephen): Implement resourceref test.
# it 'instance' do
# # Add test code here
# end
- 2
it { is_expected.to have_attributes(password: 'test password#0 data') }
end
- 1
context 'gsql_user[title1]' do
- 1
subject do
- 3
chef_run.find_resource(:gsql_user, 'title1')
end
- 2
it { is_expected.to have_attributes(host: 'test host#1 data') }
- 2
it { is_expected.to have_attributes(u_label: 'title1') }
# TODO(alexstephen): Implement resourceref test.
# it 'instance' do
# # Add test code here
# end
- 2
it { is_expected.to have_attributes(password: 'test password#1 data') }
end
- 1
context 'gsql_user[title2]' do
- 1
subject do
- 3
chef_run.find_resource(:gsql_user, 'title2')
end
- 2
it { is_expected.to have_attributes(host: 'test host#2 data') }
- 2
it { is_expected.to have_attributes(u_label: 'title2') }
# TODO(alexstephen): Implement resourceref test.
# it 'instance' do
# # Add test code here
# end
- 2
it { is_expected.to have_attributes(password: 'test password#2 data') }
end
end
# Ensure present: resource exists, no change, no name, fail
- 1
context 'title == name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
end
# Ensure present: resource exists, no change, has name
- 1
context 'title != name' do
# Ensure present: resource exists, no change, has name, pass
- 1
context 'title != name (pass)' do
- 1
before do
- 9
allow(Time).to receive(:now).and_return(
Time.new(2017, 1, 2, 3, 4, 5)
)
- 9
expect_network_get_success 1, instance: 'test name#0 data'
- 9
expect_network_get_success 2, instance: 'test name#1 data'
- 9
expect_network_get_success 3, instance: 'test name#2 data'
- 9
expect_network_get_success_instance 1
- 9
expect_network_get_success_instance 2
- 9
expect_network_get_success_instance 3
end
- 1
let(:runner) do
# This path ensures that the current cookbook is
# loaded for testing.
# This path will load all other cookbooks in the
# parent directory.
# Under most circumstances, this will include the
# real google-gauth cookbook.
- 9
parent_dir = File.join(File.dirname(__FILE__), '..', '..')
- 9
cookbook_paths = [parent_dir]
# If there's no real version of the google-gauth ,
# add in the mocked version so that the tests do not fail.
# Since cookbooks can have any name, we assume that
# any directory with the word auth is the google-gauth cookbook.
- 9
cookbook_paths << File.join(File.dirname(__FILE__), 'cookbooks')
- 9
ChefSpec::SoloRunner.new(
step_into: %w[gsql_user gsql_instance],
cookbook_path: cookbook_paths,
platform: 'ubuntu',
version: '16.04'
)
end
- 1
let(:chef_run) do
apply_recipe(
<<-MANIFEST
gsql_instance 'resource(instance,0)' do
action :create
i_label 'test name#0 data'
project 'test project#0 data'
credential 'mycred'
end
gsql_instance 'resource(instance,1)' do
action :create
i_label 'test name#1 data'
project 'test project#1 data'
credential 'mycred'
end
gsql_instance 'resource(instance,2)' do
action :create
i_label 'test name#2 data'
project 'test project#2 data'
credential 'mycred'
end
gsql_user 'title0' do
action :create
host 'test host#0 data'
instance 'resource(instance,0)'
password 'test password#0 data'
u_label 'test name#0 data'
project 'test project#0 data'
credential 'mycred'
end
gsql_user 'title1' do
action :create
host 'test host#1 data'
instance 'resource(instance,1)'
password 'test password#1 data'
u_label 'test name#1 data'
project 'test project#1 data'
credential 'mycred'
end
gsql_user 'title2' do
action :create
host 'test host#2 data'
instance 'resource(instance,2)'
password 'test password#2 data'
u_label 'test name#2 data'
project 'test project#2 data'
credential 'mycred'
end
MANIFEST
- 9
) do |recipe_name|
- 9
runner.converge(recipe_name) do
- 9
cred = Google::CredentialResourceMock.new('mycred',
runner.run_context)
- 9
runner.resource_collection.insert(cred)
end
end
end
- 1
context 'gsql_user[title0]' do
- 1
subject do
- 3
chef_run.find_resource(:gsql_user, 'title0')
end
- 2
it { is_expected.to have_attributes(host: 'test host#0 data') }
- 2
it { is_expected.to have_attributes(u_label: 'test name#0 data') }
# TODO(alexstephen): Implement resourceref test.
# it 'instance' do
# # Add test code here
# end
- 2
it { is_expected.to have_attributes(password: 'test password#0 data') }
end
- 1
context 'gsql_user[title1]' do
- 1
subject do
- 3
chef_run.find_resource(:gsql_user, 'title1')
end
- 2
it { is_expected.to have_attributes(host: 'test host#1 data') }
- 2
it { is_expected.to have_attributes(u_label: 'test name#1 data') }
# TODO(alexstephen): Implement resourceref test.
# it 'instance' do
# # Add test code here
# end
- 2
it { is_expected.to have_attributes(password: 'test password#1 data') }
end
- 1
context 'gsql_user[title2]' do
- 1
subject do
- 3
chef_run.find_resource(:gsql_user, 'title2')
end
- 2
it { is_expected.to have_attributes(host: 'test host#2 data') }
- 2
it { is_expected.to have_attributes(u_label: 'test name#2 data') }
# TODO(alexstephen): Implement resourceref test.
# it 'instance' do
# # Add test code here
# end
- 2
it { is_expected.to have_attributes(password: 'test password#2 data') }
end
end
# Ensure present: resource exists, no change, has name, fail
- 1
context 'title != name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
end
end
# Ensure present: resource exists, changes
- 1
context 'changes == action' do
# Ensure present: resource exists, changes, no name
- 1
context 'title == name' do
# Ensure present: resource exists, changes, no name, pass
- 1
context 'title == name (pass)' do
# TODO(alexstephen): Implement new test format.
end
# Ensure present: resource exists, changes, no name, fail
- 1
context 'title == name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
end
# Ensure present: resource exists, changes, has name
- 1
context 'title != name' do
# Ensure present: resource exists, changes, has name, pass
- 1
context 'title != name (pass)' do
# TODO(alexstephen): Implement new test format
end
# Ensure present: resource exists, changes, has name, fail
- 1
context 'title != name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
end
end
end
- 1
context 'resource missing' do
# Ensure present: resource missing, ignore, no name
- 1
context 'title == name' do
# Ensure present: resource missing, ignore, no name, pass
- 1
context 'title == name (pass)' do
- 1
before do
- 4
expect_network_get_failed 1, name: 'title0', instance: 'test name#0 data'
expect_network_create \
- 4
1,
{
'kind' => 'sql#user',
'host' => 'test host#0 data',
'name' => 'title0',
'password' => 'test password#0 data'
},
name: 'title0',
instance: 'test name#0 data'
- 4
expect_network_get_async 1, name: 'title0', instance: 'test name#0 data'
- 4
expect_network_get_success_instance 1
end
- 1
let(:runner) do
# This path ensures that the current cookbook is
# loaded for testing.
# This path will load all other cookbooks in the
# parent directory.
# Under most circumstances, this will include the
# real google-gauth cookbook.
- 4
parent_dir = File.join(File.dirname(__FILE__), '..', '..')
- 4
cookbook_paths = [parent_dir]
# If there's no real version of the google-gauth ,
# add in the mocked version so that the tests do not fail.
# Since cookbooks can have any name, we assume that
# any directory with the word auth is the google-gauth cookbook.
- 4
cookbook_paths << File.join(File.dirname(__FILE__), 'cookbooks')
- 4
ChefSpec::SoloRunner.new(
step_into: %w[gsql_user gsql_instance],
cookbook_path: cookbook_paths,
platform: 'ubuntu',
version: '16.04'
)
end
- 1
let(:chef_run) do
apply_recipe(
<<-MANIFEST
gsql_instance 'resource(instance,0)' do
action :create
i_label 'test name#0 data'
project 'test project#0 data'
credential 'mycred'
end
gsql_user 'title0' do
action :create
host 'test host#0 data'
instance 'resource(instance,0)'
password 'test password#0 data'
project 'test project#0 data'
credential 'mycred'
end
MANIFEST
- 4
) do |recipe_name|
- 4
runner.converge(recipe_name) do
- 4
cred = Google::CredentialResourceMock.new('mycred',
runner.run_context)
- 4
runner.resource_collection.insert(cred)
end
end
end
- 1
subject do
- 3
chef_run.find_resource(:gsql_user, 'title0')
end
- 1
it 'should run test correctly' do
- 1
expect(chef_run).to create(:gsql_user,
'title0')
end
- 2
it { is_expected.to have_attributes(host: 'test host#0 data') }
- 2
it { is_expected.to have_attributes(u_label: 'title0') }
# TODO(alexstephen): Implement resourceref test.
# it 'instance' do
# # Add test code here
# end
- 2
it { is_expected.to have_attributes(password: 'test password#0 data') }
end
# Ensure present: resource missing, ignore, no name, fail
- 1
context 'title == name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
end
# Ensure present: resource missing, ignore, has name
- 1
context 'title != name' do
# Ensure present: resource missing, ignore, has name, pass
- 1
context 'title != name (pass)' do
- 1
before do
- 4
expect_network_get_failed 1, instance: 'test name#0 data'
expect_network_create \
- 4
1,
{
'kind' => 'sql#user',
'host' => 'test host#0 data',
'name' => 'test name#0 data',
'password' => 'test password#0 data'
},
instance: 'test name#0 data'
- 4
expect_network_get_async 1, instance: 'test name#0 data'
- 4
expect_network_get_success_instance 1
end
- 1
let(:runner) do
# This path ensures that the current cookbook is
# loaded for testing.
# This path will load all other cookbooks in the
# parent directory.
# Under most circumstances, this will include the
# real google-gauth cookbook.
- 4
parent_dir = File.join(File.dirname(__FILE__), '..', '..')
- 4
cookbook_paths = [parent_dir]
# If there's no real version of the google-gauth ,
# add in the mocked version so that the tests do not fail.
# Since cookbooks can have any name, we assume that
# any directory with the word auth is the google-gauth cookbook.
- 4
cookbook_paths << File.join(File.dirname(__FILE__), 'cookbooks')
- 4
ChefSpec::SoloRunner.new(
step_into: %w[gsql_user gsql_instance],
cookbook_path: cookbook_paths,
platform: 'ubuntu',
version: '16.04'
)
end
- 1
let(:chef_run) do
apply_recipe(
<<-MANIFEST
gsql_instance 'resource(instance,0)' do
action :create
i_label 'test name#0 data'
project 'test project#0 data'
credential 'mycred'
end
gsql_user 'title0' do
action :create
host 'test host#0 data'
instance 'resource(instance,0)'
password 'test password#0 data'
u_label 'test name#0 data'
project 'test project#0 data'
credential 'mycred'
end
MANIFEST
- 4
) do |recipe_name|
- 4
runner.converge(recipe_name) do
- 4
cred = Google::CredentialResourceMock.new('mycred',
runner.run_context)
- 4
runner.resource_collection.insert(cred)
end
end
end
- 1
subject do
- 3
chef_run.find_resource(:gsql_user, 'title0')
end
- 1
it 'should run test correctly' do
- 1
expect(chef_run).to create(:gsql_user,
'title0')
end
- 2
it { is_expected.to have_attributes(host: 'test host#0 data') }
- 2
it { is_expected.to have_attributes(u_label: 'test name#0 data') }
# TODO(alexstephen): Implement resourceref test.
# it 'instance' do
# # Add test code here
# end
- 2
it { is_expected.to have_attributes(password: 'test password#0 data') }
end
# Ensure present: resource missing, ignore, has name, fail
- 1
context 'title != name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
end
end
end
- 1
context 'ensure == absent' do
- 1
context 'resource missing' do
# Ensure absent: resource missing, ignore, no name
- 1
context 'title == name' do
# Ensure absent: resource missing, ignore, no name, pass
- 1
context 'title == name (pass)' do
- 1
before do
expect_network_get_failed 1, name: 'title0', instance: 'test name#0 data'
expect_network_get_success_instance 1
end
- 1
let(:runner) do
# This path ensures that the current cookbook is
# loaded for testing.
# This path will load all other cookbooks in the
# parent directory.
# Under most circumstances, this will include the
# real google-gauth cookbook.
parent_dir = File.join(File.dirname(__FILE__), '..', '..')
cookbook_paths = [parent_dir]
# If there's no real version of the google-gauth ,
# add in the mocked version so that the tests do not fail.
# Since cookbooks can have any name, we assume that
# any directory with the word auth is the google-gauth cookbook.
cookbook_paths << File.join(File.dirname(__FILE__), 'cookbooks')
ChefSpec::SoloRunner.new(
step_into: %w[gsql_user gsql_instance],
cookbook_path: cookbook_paths,
platform: 'ubuntu',
version: '16.04'
)
end
- 1
let(:chef_run) do
apply_recipe(
<<-MANIFEST
gsql_instance 'resource(instance,0)' do
action :create
i_label 'test name#0 data'
project 'test project#0 data'
credential 'mycred'
end
gsql_user 'title0' do
action :delete
host 'test host#0 data'
instance 'resource(instance,0)'
project 'test project#0 data'
credential 'mycred'
end
MANIFEST
) do |recipe_name|
runner.converge(recipe_name) do
cred = Google::CredentialResourceMock.new('mycred',
runner.run_context)
runner.resource_collection.insert(cred)
end
end
end
- 1
subject do
chef_run.find_resource(:gsql_user, 'title0')
end
end
# Ensure absent: resource missing, ignore, no name, fail
- 1
context 'title == name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
end
# Ensure absent: resource missing, ignore, has name
- 1
context 'title != name' do
# Ensure absent: resource missing, ignore, has name, pass
- 1
context 'title != name (pass)' do
- 1
before do
expect_network_get_failed 1, instance: 'test name#0 data'
expect_network_get_success_instance 1
end
- 1
let(:runner) do
# This path ensures that the current cookbook is
# loaded for testing.
# This path will load all other cookbooks in the
# parent directory.
# Under most circumstances, this will include the
# real google-gauth cookbook.
parent_dir = File.join(File.dirname(__FILE__), '..', '..')
cookbook_paths = [parent_dir]
# If there's no real version of the google-gauth ,
# add in the mocked version so that the tests do not fail.
# Since cookbooks can have any name, we assume that
# any directory with the word auth is the google-gauth cookbook.
cookbook_paths << File.join(File.dirname(__FILE__), 'cookbooks')
ChefSpec::SoloRunner.new(
step_into: %w[gsql_user gsql_instance],
cookbook_path: cookbook_paths,
platform: 'ubuntu',
version: '16.04'
)
end
- 1
let(:chef_run) do
apply_recipe(
<<-MANIFEST
gsql_instance 'resource(instance,0)' do
action :create
i_label 'test name#0 data'
project 'test project#0 data'
credential 'mycred'
end
gsql_user 'title0' do
action :delete
host 'test host#0 data'
instance 'resource(instance,0)'
u_label 'test name#0 data'
project 'test project#0 data'
credential 'mycred'
end
MANIFEST
) do |recipe_name|
runner.converge(recipe_name) do
cred = Google::CredentialResourceMock.new('mycred',
runner.run_context)
runner.resource_collection.insert(cred)
end
end
end
- 1
subject do
chef_run.find_resource(:gsql_user, 'title0')
end
end
# Ensure absent: resource missing, ignore, has name, fail
- 1
context 'title != name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
end
end
- 1
context 'resource exists' do
# Ensure absent: resource exists, ignore, no name
- 1
context 'title == name' do
# Ensure absent: resource exists, ignore, no name, pass
- 1
context 'title == name (pass)' do
- 1
before do
- 1
expect_network_get_success 1, name: 'title0', instance: 'test name#0 data'
- 1
expect_network_delete 1, 'title0', instance: 'test name#0 data'
- 1
expect_network_get_async 1, name: 'title0', instance: 'test name#0 data'
- 1
expect_network_get_success_instance 1
end
- 1
let(:runner) do
# This path ensures that the current cookbook is
# loaded for testing.
# This path will load all other cookbooks in the
# parent directory.
# Under most circumstances, this will include the
# real google-gauth cookbook.
- 1
parent_dir = File.join(File.dirname(__FILE__), '..', '..')
- 1
cookbook_paths = [parent_dir]
# If there's no real version of the google-gauth ,
# add in the mocked version so that the tests do not fail.
# Since cookbooks can have any name, we assume that
# any directory with the word auth is the google-gauth cookbook.
- 1
cookbook_paths << File.join(File.dirname(__FILE__), 'cookbooks')
- 1
ChefSpec::SoloRunner.new(
step_into: %w[gsql_user gsql_instance],
cookbook_path: cookbook_paths,
platform: 'ubuntu',
version: '16.04'
)
end
- 1
let(:chef_run) do
apply_recipe(
<<-MANIFEST
gsql_instance 'resource(instance,0)' do
action :create
i_label 'test name#0 data'
project 'test project#0 data'
credential 'mycred'
end
gsql_user 'title0' do
action :delete
host 'test host#0 data'
instance 'resource(instance,0)'
project 'test project#0 data'
credential 'mycred'
end
MANIFEST
- 1
) do |recipe_name|
- 1
runner.converge(recipe_name) do
- 1
cred = Google::CredentialResourceMock.new('mycred',
runner.run_context)
- 1
runner.resource_collection.insert(cred)
end
end
end
- 1
subject do
chef_run.find_resource(:gsql_user, 'title0')
end
- 1
it 'should run test correctly' do
- 1
expect(chef_run).to delete(:gsql_user,
'title0')
end
end
# Ensure absent: resource exists, ignore, no name, fail
- 1
context 'title == name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
end
# Ensure absent: resource exists, ignore, has name
- 1
context 'title != name' do
# Ensure absent: resource exists, ignore, has name, pass
- 1
context 'title != name (pass)' do
- 1
before do
- 1
expect_network_get_success 1, instance: 'test name#0 data'
- 1
expect_network_delete 1, nil, instance: 'test name#0 data'
- 1
expect_network_get_async 1, instance: 'test name#0 data'
- 1
expect_network_get_success_instance 1
end
- 1
let(:runner) do
# This path ensures that the current cookbook is
# loaded for testing.
# This path will load all other cookbooks in the
# parent directory.
# Under most circumstances, this will include the
# real google-gauth cookbook.
- 1
parent_dir = File.join(File.dirname(__FILE__), '..', '..')
- 1
cookbook_paths = [parent_dir]
# If there's no real version of the google-gauth ,
# add in the mocked version so that the tests do not fail.
# Since cookbooks can have any name, we assume that
# any directory with the word auth is the google-gauth cookbook.
- 1
cookbook_paths << File.join(File.dirname(__FILE__), 'cookbooks')
- 1
ChefSpec::SoloRunner.new(
step_into: %w[gsql_user gsql_instance],
cookbook_path: cookbook_paths,
platform: 'ubuntu',
version: '16.04'
)
end
- 1
let(:chef_run) do
apply_recipe(
<<-MANIFEST
gsql_instance 'resource(instance,0)' do
action :create
i_label 'test name#0 data'
project 'test project#0 data'
credential 'mycred'
end
gsql_user 'title0' do
action :delete
host 'test host#0 data'
instance 'resource(instance,0)'
u_label 'test name#0 data'
project 'test project#0 data'
credential 'mycred'
end
MANIFEST
- 1
) do |recipe_name|
- 1
runner.converge(recipe_name) do
- 1
cred = Google::CredentialResourceMock.new('mycred',
runner.run_context)
- 1
runner.resource_collection.insert(cred)
end
end
end
- 1
subject do
chef_run.find_resource(:gsql_user, 'title0')
end
- 1
it 'should run test correctly' do
- 1
expect(chef_run).to delete(:gsql_user,
'title0')
end
end
# Ensure absent: resource exists, ignore, has name, fail
- 1
context 'title != name (fail)' do
# TODO(alexstephen): Implement new test format.
- 3
subject { -> { raise '[placeholder] This should fail.' } }
- 2
it { is_expected.to raise_error(RuntimeError, /placeholder/) }
end
end
end
end
- 1
def expand_variables(template, data, extra_data = {})
Google::GSQL::User
- 178
.action_class.expand_variables(template, data, extra_data)
end
- 1
def expect_network_get_success(id, data = {})
- 56
id_data = data.fetch(:name, '').include?('title') ? 'title' : 'name'
- 56
body = load_network_result("success#{id}~#{id_data}.yaml").to_json
- 56
request = double('request')
- 56
allow(request).to receive(:send).and_return(http_success(body))
- 56
debug_network "!! GET #{self_link(uri_data(id).merge(data))}"
- 56
expect(Google::Sql::Network::Get).to receive(:new)
.with(self_link(uri_data(id).merge(data)),
instance_of(Google::FakeAuthorization)) do |args|
- 56
debug_network ">> GET #{args}"
- 56
request
end
end
- 1
def http_success(body)
- 140
response = Net::HTTPOK.new(1.0, 200, 'OK')
- 140
response.body = body
- 140
response.instance_variable_set(:@read, true)
- 140
response
end
- 1
def expect_network_get_async(id, data = {})
- 10
body = { kind: 'sql#usersList' }.to_json
- 10
request = double('request')
- 10
allow(request).to receive(:send).and_return(http_success(body))
- 10
debug_network "!! #{self_link(uri_data(id).merge(data))}"
- 10
expect(Google::Sql::Network::Get).to receive(:new)
.with(self_link(uri_data(id).merge(data)),
instance_of(Google::FakeAuthorization)) do |args|
- 10
debug_network ">> GET <async> #{args}"
- 10
request
end
end
- 1
def expect_network_get_failed(id, data = {})
- 8
request = double('request')
- 8
allow(request).to receive(:send).and_return(http_failed_object_missing)
- 8
debug_network "!! #{self_link(uri_data(id).merge(data))}"
- 8
expect(Google::Sql::Network::Get).to receive(:new)
.with(self_link(uri_data(id).merge(data)),
instance_of(Google::FakeAuthorization)) do |args|
- 8
debug_network ">> GET [failed] #{args}"
- 8
request
end
end
- 1
def http_failed_object_missing
- 8
Net::HTTPNotFound.new(1.0, 404, 'Not Found')
end
- 1
def expect_network_create(id, expected_body, data = {})
- 8
merged_uri = uri_data(id).merge(data)
- 8
body = { kind: 'sql#operation',
status: 'DONE', targetLink: self_link(merged_uri) }.to_json
# Remove refs that are also part of the body
- 8
expected_body = Hash[expected_body.map do |k, v|
- 32
[k.is_a?(Symbol) ? k.id2name : k, v]
end]
- 8
request = double('request')
- 8
allow(request).to receive(:send).and_return(http_success(body))
- 8
debug_network "!! POST #{collection(merged_uri)}"
- 8
expect(Google::Sql::Network::Post).to receive(:new)
.with(collection(merged_uri), instance_of(Google::FakeAuthorization),
'application/json', expected_body.to_json) do |args|
- 8
debug_network ">> POST #{args} = body(#{body})"
- 8
request
end
end
- 1
def expect_network_delete(id, name = nil, data = {})
- 2
delete_data = uri_data(id).merge(data)
- 2
delete_data[:name] = name unless name.nil?
- 2
body = { kind: 'sql#operation',
status: 'DONE',
targetLink: self_link(delete_data) }.to_json
- 2
request = double('request')
- 2
allow(request).to receive(:send).and_return(http_success(body))
- 2
debug_network "!! DELETE #{self_link(delete_data)}"
- 2
expect(Google::Sql::Network::Delete).to receive(:new)
.with(self_link(delete_data),
instance_of(Google::FakeAuthorization)) do |args|
- 2
debug_network ">> DELETE #{args}"
- 2
request
end
end
- 1
def load_network_result(file)
- 56
results = File.join(File.dirname(__FILE__), 'data', 'network',
'gsql_user', file)
- 56
debug("Loading result file: #{results}")
- 56
raise "Network result data file #{results}" unless File.exist?(results)
- 56
data = YAML.safe_load(File.read(results))
- 56
raise "Invalid network results #{results}" unless data.class <= Hash
- 56
data
end
- 1
def expect_network_get_success_instance(id, data = {})
- 64
id_data = data.fetch(:name, '').include?('title') ? 'title' : 'name'
- 64
body = load_network_result_instance("success#{id}~" \
"#{id_data}.yaml")
.to_json
- 64
uri = uri_data_instance(id).merge(data)
- 64
request = double('request')
- 64
allow(request).to receive(:send).and_return(http_success(body))
- 64
debug_network "!! GET #{uri}"
- 64
expect(Google::Sql::Network::Get).to receive(:new)
.with(self_link_instance(uri),
instance_of(Google::FakeAuthorization)) do |args|
- 64
debug_network ">> GET #{args}"
- 64
request
end
end
- 1
def load_network_result_instance(file)
- 64
results = File.join(File.dirname(__FILE__), 'data', 'network',
'gsql_instance', file)
- 64
raise "Network result data file #{results}" unless File.exist?(results)
- 64
data = YAML.safe_load(File.read(results))
- 64
raise "Invalid network results #{results}" unless data.class <= Hash
- 64
data
end
# Creates variable test data to comply with self_link URI parameters
# Only used for gsql_instance objects
- 1
def uri_data_instance(id)
- 64
{
- 64
project: GoogleTests::Constants::I_PROJECT_DATA[(id - 1) \
% GoogleTests::Constants::I_PROJECT_DATA.size],
- 64
name: GoogleTests::Constants::I_NAME_DATA[(id - 1) \
% GoogleTests::Constants::I_NAME_DATA.size]
}
end
- 1
def self_link_instance(data)
- 64
URI.join(
'https://www.googleapis.com/sql/v1beta4/',
expand_variables_instance(
'projects/{{project}}/instances/{{name}}',
data
)
)
end
- 1
def debug(message)
- 56
puts(message) if ENV['RSPEC_DEBUG']
end
- 1
def debug_network(message)
puts("Network #{message}") \
- 296
if ENV['RSPEC_DEBUG'] || ENV['RSPEC_HTTP_VERBOSE']
end
- 1
def expand_variables_instance(template, data, ext_dat = {})
Google::GSQL::Instance
- 64
.action_class.expand_variables(template, data, ext_dat)
end
- 1
def collection(data)
- 16
URI.join(
'https://www.googleapis.com/sql/v1beta4/',
expand_variables(
'projects/{{project}}/instances/{{instance}}/users',
data
)
)
end
- 1
def self_link(data)
- 162
URI.join(
'https://www.googleapis.com/sql/v1beta4/',
expand_variables(
[
'projects/{{project}}/instances/{{instance}}/users',
'?name={{name}}&host={{host}}'
].join,
data
)
)
end
# Creates variable test data to comply with self_link URI parameters
- 1
def uri_data(id)
- 158
{
- 158
project: GoogleTests::Constants::U_PROJECT_DATA[(id - 1) \
% GoogleTests::Constants::U_PROJECT_DATA.size],
- 158
instance: GoogleTests::Constants::U_INSTANCE_DATA[(id - 1) \
% GoogleTests::Constants::U_INSTANCE_DATA.size],
- 158
name: GoogleTests::Constants::U_NAME_DATA[(id - 1) \
% GoogleTests::Constants::U_NAME_DATA.size],
- 158
host: GoogleTests::Constants::U_HOST_DATA[(id - 1) \
% GoogleTests::Constants::U_HOST_DATA.size]
}
end
- 1
def build_cred
- 28
<<-CRED
gauth_credential 'mycred' do
action :serviceaccount
path '/home'
scopes [
'test_path'
]
end
CRED
end
# Creates a test recipe file and runs a block before destroying the file
- 1
def apply_recipe(recipe)
# Creates a random string name
- 252
recipe_name = "recipe~test~#{(0...8).map { (65 + rand(26)).chr }.join}"
- 28
recipe_loc = File.join(File.dirname(__FILE__), '..', 'recipes',
"#{recipe_name}.rb")
- 28
File.open(recipe_loc, 'w') do |file|
- 28
file.write([build_cred, recipe].join("\n"))
end
- 28
recipe_path = "google-gsql::#{recipe_name}"
- 28
begin
- 28
yield recipe_path
ensure
- 28
File.delete(recipe_loc)
end
end
end