Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions kitchen-oci.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ lib = File.expand_path("lib", __dir__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require "kitchen/driver/oci_version"

Gem::Specification.new do |spec|
Gem::Specification.new do |spec| # rubocop: disable Metrics/BlockLength
spec.name = "kitchen-oci"
spec.version = Kitchen::Driver::OCI_VERSION
spec.authors = ["Stephen Pearson", "Justin Steele"]
Expand All @@ -31,13 +31,20 @@ Gem::Specification.new do |spec|
spec.files = `git ls-files`.split($/).grep(/LICENSE|^lib|^tpl/)
spec.executables = []
spec.require_paths = ["lib"]

spec.metadata = {
"bug_tracker_uri" => "https://github.com/stephenpearson/kitchen-oci/issues",
"changelog_uri" => "https://github.com/stephenpearson/kitchen-oci/blob/master/CHANGELOG.md",
"documentation_uri" => "https://github.com/stephenpearson/kitchen-oci/blob/master/README.md",
"homepage_uri" => "https://github.com/stephenpearson/kitchen-oci",
"source_code_uri" => "https://github.com/stephenpearson/kitchen-oci",
"rubygems_mfa_required" => "true",
}
spec.add_dependency "oci", "~> 2.18"
spec.add_dependency "test-kitchen"

spec.add_development_dependency "bundler"
spec.add_development_dependency "chefstyle"
spec.add_development_dependency "pry"
spec.add_development_dependency "rake"
spec.add_development_dependency "rspec"
end
spec.add_development_dependency "yard"
end # rubocop: enable Metrics/BlockLength
65 changes: 20 additions & 45 deletions lib/kitchen/driver/oci.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ module Driver
# Oracle OCI driver for Kitchen.
#
# @author Stephen Pearson <stephen.pearson@oracle.com>
class Oci < Kitchen::Driver::Base # rubocop:disable Metrics/ClassLength
class Oci < Kitchen::Driver::Base
require_relative "oci_version"
require_relative "oci/models"
require_relative "oci/volumes"
require_relative "oci/mixin/actions"
require_relative "oci/mixin/models"
require_relative "oci/mixin/volumes"

plugin_version Kitchen::Driver::OCI_VERSION
kitchen_driver_api_version 2
Expand Down Expand Up @@ -115,9 +116,10 @@ def self.validation_error(message, driver)
raise UserError, "#{driver.class}<#{driver.instance.name}>#config#{message}"
end

include Kitchen::Driver::Oci::Models
include Kitchen::Driver::Oci::Volumes

# Creates an instance.
# (see Kitchen::Driver::Base#create)
#
# @param state [Hash] (see Kitchen::StateFile)
def create(state)
return if state[:server_id]

Expand All @@ -130,6 +132,10 @@ def create(state)
reboot(state, inst)
end

# Destorys an instance.
# (see Kitchen::Driver::Base#destroy)
#
# @param state [Hash] (see Kitchen::StateFile)
def destroy(state)
return unless state[:server_id]

Expand All @@ -141,51 +147,20 @@ def destroy(state)

private

include Kitchen::Driver::Oci::Mixin::Actions
include Kitchen::Driver::Oci::Mixin::Models
include Kitchen::Driver::Oci::Mixin::Volumes

# Creates the OCI config and API clients.
#
# @param action [Symbol] the name of the method that called this method.
# @return [Oci::Config, Oci::Api]
def auth(action)
oci = Oci::Config.new(config)
api = Oci::Api.new(oci.config, config)
oci.compartment if action == :create
[oci, api]
end

def launch(state, inst)
state_details = inst.launch
state.merge!(state_details)
instance.transport.connection(state).wait_until_ready
end

def process_post_script(state)
return if config[:post_create_script].nil?

info("Running post create script")
script = config[:post_create_script]
instance.transport.connection(state).execute(script)
end

def reboot(state, inst)
return unless config[:post_create_reboot]

instance.transport.connection(state).close
inst.reboot
instance.transport.connection(state).wait_until_ready
end

def detatch_and_delete_volumes(state, oci, api)
return unless state[:volumes]

bls = Blockstorage.new(config: config, state: state, oci: oci, api: api, action: :destroy, logger: instance.logger)
state[:volume_attachments].each { |att| bls.detatch_volume(att) }
state[:volumes].each { |vol| bls.delete_volume(vol) }
end

def terminate(state, inst)
instance.transport.connection(state).close
inst.terminate
if state[:ssh_key]
FileUtils.rm_f(state[:ssh_key])
FileUtils.rm_f("#{state[:ssh_key]}.pub")
end
end
end
end
end
43 changes: 36 additions & 7 deletions lib/kitchen/driver/oci/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,49 +20,66 @@
module Kitchen
module Driver
class Oci
# Api class that defines the various API classes used to interact with OCI
# Defines the various API classes used to interact with OCI.
#
# @author Justin Steele <justin.steele@oracle.com>
class Api
def initialize(oci_config, config)
@oci_config = oci_config
@config = config
end

#
# The config used to authenticate to OCI
# The config used to authenticate to OCI.
#
# @return [OCI::Config]
#
attr_reader :oci_config

#
# The config provided by the driver
# The config provided by the driver.
#
# @return [Kitchen::LazyHash]
#
attr_reader :config

# Creates a Compute API client.
#
# @return [OCI::Core::ComputeClient]
def compute
generic_api(OCI::Core::ComputeClient)
end

# Creates a Network API client.
#
# @return [OCI::Core::VirtualNetworkClient]
def network
generic_api(OCI::Core::VirtualNetworkClient)
end

# Creates a Database API client.
#
# @return [OCI::Core::DatabaseClient]
def dbaas
generic_api(OCI::Database::DatabaseClient)
end

# Creates an Identity API client.
#
# @return [OCI::Core::IdentityClient]
def identity
generic_api(OCI::Identity::IdentityClient)
end

# Creates a Blockstorage API client.
#
# @return [OCI::Core::BlockstorageClient]
def blockstorage
generic_api(OCI::Core::BlockstorageClient)
end

private

# Instantiates the specified client class.
#
# @param klass [Class] The client class to instantiate.
# @return [Object] an instance of <b>klass</b>.
def generic_api(klass)
params = {}
params[:proxy_settings] = api_proxy if api_proxy
Expand All @@ -73,6 +90,9 @@ def generic_api(klass)
klass.new(**params)
end

# Determines the signing method if one is specified.
#
# @return [OCI::Auth::Signers::InstancePrincipalsSecurityTokenSigner, OCI::Auth::Signers::SecurityTokenSigner] an instance of the specified token signer.
def signer
if config[:use_instance_principals]
OCI::Auth::Signers::InstancePrincipalsSecurityTokenSigner.new
Expand All @@ -81,6 +101,9 @@ def signer
end
end

# Creates the token signer with a provided key.
#
# @return [OCI::Auth::Signers::SecurityTokenSigner]
def token_signer
pkey_content = oci_config.key_content || File.read(oci_config.key_file).strip
pkey = OpenSSL::PKey::RSA.new(pkey_content, oci_config.pass_phrase)
Expand All @@ -89,6 +112,9 @@ def token_signer
OCI::Auth::Signers::SecurityTokenSigner.new(token, pkey)
end

# Parse any specified proxy from either the kitchen config or the environment.
#
# @return [URI] a parsed proxy host.
def proxy_config
if config[:proxy_url]
URI.parse(config[:proxy_url])
Expand All @@ -97,6 +123,9 @@ def proxy_config
end
end

# Create the proxy settings for the OCI API.
#
# @return [OCI::ApiClientProxySettings]
def api_proxy
prx = proxy_config
return unless prx
Expand Down
Loading