Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Instantiate Container Template #10737

Merged
merged 1 commit into from
Jan 17, 2017
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
64 changes: 64 additions & 0 deletions app/models/container_template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,68 @@ class ContainerTemplate < ApplicationRecord
serialize :objects, Array

acts_as_miq_taggable

MIQ_ENTITY_MAPPING = {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@simon3z I added this mapping (only for objects we collect & can instantiate) so the automation side will be able to know in which table to look for the objects.
We may consider adding a more general mapping to reuse it later on in different places.
cc @moolitayer

"Route" => ContainerRoute,
"Build" => ContainerBuildPod,
"BuildConfig" => ContainerBuild,
"Template" => ContainerTemplate,
"ResourceQuota" => ContainerQuota,
"LimitRange" => ContainerLimit,
"ReplicationController" => ContainerReplicator,
"PersistentVolumeClaim" => PersistentVolumeClaim,
"Pod" => ContainerGroup,
"Service" => ContainerService,
}.freeze

def instantiate(params, project = nil)
project ||= container_project.name
processed_template = process_template(ext_management_system.connect,
:metadata => {
:name => name,
:namespace => project
},
:objects => objects,
:parameters => params)
create_objects(processed_template['objects'], project)
@created_objects.each { |obj| obj[:kind] = MIQ_ENTITY_MAPPING[obj[:kind]] }
end

def process_template(client, template)
client.process_template(template)
rescue KubeException => e
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We normally rescue provider exceptions and re-raise a corresponding miq-exception.

raise MiqException::MiqProvisionError, "Unexpected Exception while processing template: #{e}"
end

def create_objects(objects, project)
@created_objects = []
objects.each { |obj| @created_objects << create_object(obj, project).to_h }
end

def create_object(obj, project)
obj = obj.symbolize_keys
obj[:metadata][:namespace] = project
method_name = "create_#{obj[:kind].underscore}"
begin
ext_management_system.connect_client(obj[:apiVersion], method_name).send(method_name, obj)
rescue KubeException => e
rollback_objects(@created_objects)
raise MiqException::MiqProvisionError, "Unexpected Exception while creating object: #{e}"
end
end

def rollback_objects(objects)
objects.each { |obj| rollback_object(obj) }
end

def rollback_object(obj)
method_name = "delete_#{obj[:kind].underscore}"
begin
ext_management_system.connect_client(obj[:apiVersion], method_name).send(method_name,
obj[:metadata][:name],
obj[:metadata][:namespace])
rescue KubeException => e
_log.error("Unexpected Exception while deleting object: #{e}")
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ def kubernetes_connect(hostname, port, options)
require 'kubeclient'

Kubeclient::Client.new(
raw_api_endpoint(hostname, port),
kubernetes_version,
raw_api_endpoint(hostname, port, options[:path]),
options[:version] || kubernetes_version,
:ssl_options => { :verify_ssl => verify_ssl_mode },
:auth_options => kubernetes_auth_options(options),
:http_proxy_uri => VMDB::Util.http_proxy_uri
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,10 @@ def self.event_monitor_class
def supported_auth_attributes
%w(userid password auth_key)
end

def create_project(project)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bzwei project here is a hash that represents the project to be created in openshift and then collected and saved in VMDB table container_projects.

connect.create_project_request(project)
rescue KubeException => e
raise MiqException::MiqProvisionError, "Unexpected Exception while creating project: #{e}"
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,25 @@ def openshift_connect(hostname, port, options)

Kubeclient::Client.new(
raw_api_endpoint(hostname, port, '/oapi'),
api_version,
options[:version] || api_version,
:ssl_options => { :verify_ssl => verify_ssl_mode },
:auth_options => kubernetes_auth_options(options),
:http_proxy_uri => VMDB::Util.http_proxy_uri
)
end
end

def connect_client(api_version, method_name)
@clients ||= {}
api, version = api_version.split('/', 2)
if version
@clients[api_version] ||= connect(:service => 'kubernetes', :version => version, :path => '/apis/' + api)
else
openshift = 'oapi' + api_version
kubernetes = 'api' + api_version
@clients[openshift] ||= connect(:version => api_version)
@clients[kubernetes] ||= connect(:service => 'kubernetes', :version => api_version)
@clients[openshift].respond_to?(method_name) ? @clients[openshift] : @clients[kubernetes]
end
end
end