From 37e6ece42078e38421e2b7f1e2fb6c28338a2efc Mon Sep 17 00:00:00 2001 From: Zahi Akiva Date: Wed, 24 Aug 2016 16:29:30 +0300 Subject: [PATCH] Instantiate Container Template --- app/models/container_template.rb | 64 +++++++++++++++++++ .../kubernetes/container_manager_mixin.rb | 4 +- .../providers/openshift/container_manager.rb | 6 ++ .../openshift/container_manager_mixin.rb | 16 ++++- 4 files changed, 87 insertions(+), 3 deletions(-) diff --git a/app/models/container_template.rb b/app/models/container_template.rb index ebae1a30862..f2b2ac5f182 100644 --- a/app/models/container_template.rb +++ b/app/models/container_template.rb @@ -12,4 +12,68 @@ class ContainerTemplate < ApplicationRecord serialize :objects, Array acts_as_miq_taggable + + MIQ_ENTITY_MAPPING = { + "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 + 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 diff --git a/app/models/manageiq/providers/kubernetes/container_manager_mixin.rb b/app/models/manageiq/providers/kubernetes/container_manager_mixin.rb index 9ae5a877979..8fc30dff27a 100644 --- a/app/models/manageiq/providers/kubernetes/container_manager_mixin.rb +++ b/app/models/manageiq/providers/kubernetes/container_manager_mixin.rb @@ -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 diff --git a/app/models/manageiq/providers/openshift/container_manager.rb b/app/models/manageiq/providers/openshift/container_manager.rb index 61b22c10a70..3ecaa817729 100644 --- a/app/models/manageiq/providers/openshift/container_manager.rb +++ b/app/models/manageiq/providers/openshift/container_manager.rb @@ -23,4 +23,10 @@ def self.event_monitor_class def supported_auth_attributes %w(userid password auth_key) end + + def create_project(project) + connect.create_project_request(project) + rescue KubeException => e + raise MiqException::MiqProvisionError, "Unexpected Exception while creating project: #{e}" + end end diff --git a/app/models/manageiq/providers/openshift/container_manager_mixin.rb b/app/models/manageiq/providers/openshift/container_manager_mixin.rb index 1224f490fac..715f8637d8d 100644 --- a/app/models/manageiq/providers/openshift/container_manager_mixin.rb +++ b/app/models/manageiq/providers/openshift/container_manager_mixin.rb @@ -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