mirror of
https://github.com/OpenNebula/one.git
synced 2024-12-22 13:33:52 +03:00
F #5076: Implement provider/provision template
co-authored-by: Alejandro Huertas <ahuertas@opennebula.io>
This commit is contained in:
parent
994098a249
commit
728142e205
@ -18,7 +18,7 @@
|
||||
#define DOCUMENT_H_
|
||||
|
||||
#include "PoolObjectSQL.h"
|
||||
#include "Template.h"
|
||||
#include "DocumentTemplate.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -48,7 +48,7 @@ public:
|
||||
*/
|
||||
std::unique_ptr<Template> get_new_template() const override
|
||||
{
|
||||
return std::make_unique<Template>();
|
||||
return std::make_unique<DocumentTemplate>();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -57,7 +57,7 @@ public:
|
||||
*/
|
||||
std::unique_ptr<Template> clone_template() const
|
||||
{
|
||||
return std::make_unique<Template>(*obj_template);
|
||||
return std::make_unique<DocumentTemplate>(*obj_template);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -28,7 +28,10 @@ class DocumentPool : public PoolSQL
|
||||
{
|
||||
public:
|
||||
|
||||
DocumentPool(SqlDB * db) : PoolSQL(db, one_db::doc_table) {};
|
||||
DocumentPool(SqlDB * db, std::vector<const SingleAttribute *>& ea) :
|
||||
PoolSQL(db, one_db::doc_table) {
|
||||
DocumentTemplate::parse_encrypted(ea);
|
||||
};
|
||||
|
||||
~DocumentPool(){};
|
||||
|
||||
|
64
include/DocumentTemplate.h
Normal file
64
include/DocumentTemplate.h
Normal file
@ -0,0 +1,64 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2020, OpenNebula Project, OpenNebula Systems */
|
||||
/* */
|
||||
/* 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. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef DOCUMENT_TEMPLATE_H_
|
||||
#define DOCUMENT_TEMPLATE_H_
|
||||
|
||||
#include "Template.h"
|
||||
|
||||
/**
|
||||
* Document Template class, it represents the attributes of a Document
|
||||
*/
|
||||
class DocumentTemplate : public Template
|
||||
{
|
||||
public:
|
||||
DocumentTemplate() : Template(false,'=',"TEMPLATE"){};
|
||||
|
||||
~DocumentTemplate(){};
|
||||
|
||||
DocumentTemplate(DocumentTemplate& dt):Template(dt){};
|
||||
|
||||
DocumentTemplate(const Template& tmpl):Template(tmpl){};
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Encrypted attributes interface implementation
|
||||
// -------------------------------------------------------------------------
|
||||
virtual void encrypt(const std::string& one_key)
|
||||
{
|
||||
Template::encrypt(one_key, encrypted);
|
||||
}
|
||||
|
||||
virtual void decrypt(const std::string& one_key)
|
||||
{
|
||||
Template::decrypt(one_key, encrypted);
|
||||
}
|
||||
|
||||
static void parse_encrypted(std::vector<const SingleAttribute *>& ea)
|
||||
{
|
||||
Template::parse_encrypted(ea, encrypted);
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Encrypted attribute list for DocumentTemplates
|
||||
*/
|
||||
static std::map<std::string, std::set<std::string> > encrypted;
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#endif /*DOCUMENT_TEMPLATE_H_*/
|
83
install.sh
83
install.sh
@ -292,9 +292,12 @@ LIB_DIRS="$LIB_LOCATION/ruby \
|
||||
$LIB_LOCATION/ruby/vcenter_driver \
|
||||
$LIB_LOCATION/ruby/nsx_driver \
|
||||
$LIB_LOCATION/oneprovision/lib \
|
||||
$LIB_LOCATION/oneprovision/lib/resources \
|
||||
$LIB_LOCATION/oneprovision/lib/resources/virtual \
|
||||
$LIB_LOCATION/oneprovision/lib/resources/physical"
|
||||
$LIB_LOCATION/oneprovision/lib/provision \
|
||||
$LIB_LOCATION/oneprovision/lib/provision_template \
|
||||
$LIB_LOCATION/oneprovision/lib/provider \
|
||||
$LIB_LOCATION/oneprovision/lib/provision/resources \
|
||||
$LIB_LOCATION/oneprovision/lib/provision/resources/virtual \
|
||||
$LIB_LOCATION/oneprovision/lib/provision/resources/physical"
|
||||
|
||||
VAR_DIRS="$VAR_LOCATION/remotes \
|
||||
$VAR_LOCATION/remotes/etc \
|
||||
@ -725,9 +728,12 @@ INSTALL_ONEPROVISION_FILES=(
|
||||
ONEPROVISION_TEMPLATES_FILES:$SHARE_LOCATION/oneprovision
|
||||
ONEPROVISION_EXAMPLES_FILES:$SHARE_LOCATION/oneprovision
|
||||
ONEPROVISION_LIB_FILES:$LIB_LOCATION/oneprovision/lib
|
||||
ONEPROVISION_LIB_RESOURCES_FILES:$LIB_LOCATION/oneprovision/lib/resources
|
||||
ONEPROVISION_LIB_PHYSICAL_R_FILES:$LIB_LOCATION/oneprovision/lib/resources/physical
|
||||
ONEPROVISION_LIB_VIRTUAL_R_FILES:$LIB_LOCATION/oneprovision/lib/resources/virtual
|
||||
ONEPROVISION_LIB_PROVISION_FILES:$LIB_LOCATION/oneprovision/lib/provision
|
||||
ONEPROVISION_LIB_RESOURCES_FILES:$LIB_LOCATION/oneprovision/lib/provision/resources
|
||||
ONEPROVISION_LIB_PHYSICAL_R_FILES:$LIB_LOCATION/oneprovision/lib/provision/resources/physical
|
||||
ONEPROVISION_LIB_VIRTUAL_R_FILES:$LIB_LOCATION/oneprovision/lib/provision/resources/virtual
|
||||
ONEPROVISION_LIB_PROVIDER_FILES:$LIB_LOCATION/oneprovision/lib/provider
|
||||
ONEPROVISION_LIB_PROVISION_TEMPLATE_FILES:$LIB_LOCATION/oneprovision/lib/provision_template
|
||||
)
|
||||
|
||||
INSTALL_SUNSTONE_RUBY_FILES=(
|
||||
@ -2360,11 +2366,17 @@ CLI_CONF_FILES="src/cli/etc/onegroup.yaml \
|
||||
# Provision files
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
ONEPROVISION_BIN_FILES="src/cli/oneprovision"
|
||||
ONEPROVISION_BIN_FILES="src/cli/oneprovision \
|
||||
src/cli/oneprovider \
|
||||
src/cli/oneprovision-template"
|
||||
|
||||
ONEPROVISION_ONE_LIB_FILES="src/cli/one_helper/oneprovision_helper.rb"
|
||||
ONEPROVISION_ONE_LIB_FILES="src/cli/one_helper/oneprovision_helper.rb \
|
||||
src/cli/one_helper/oneprovider_helper.rb \
|
||||
src/cli/one_helper/oneprovision_template_helper.rb"
|
||||
|
||||
ONEPROVISION_CONF_FILES="src/cli/etc/oneprovision.yaml"
|
||||
ONEPROVISION_CONF_FILES="src/cli/etc/oneprovision.yaml \
|
||||
src/cli/etc/oneprovider.yaml \
|
||||
src/cli/etc/oneprovision_template.yaml"
|
||||
|
||||
ONEPROVISION_ANSIBLE_FILES="share/oneprovision/ansible"
|
||||
|
||||
@ -2372,31 +2384,40 @@ ONEPROVISION_TEMPLATES_FILES="share/oneprovision/templates"
|
||||
|
||||
ONEPROVISION_EXAMPLES_FILES="share/oneprovision/examples"
|
||||
|
||||
ONEPROVISION_LIB_FILES="src/oneprovision/lib/ansible.rb \
|
||||
src/oneprovision/lib/oneprovision.rb \
|
||||
src/oneprovision/lib/driver.rb \
|
||||
src/oneprovision/lib/provision.rb \
|
||||
src/oneprovision/lib/provision_pool.rb \
|
||||
src/oneprovision/lib/resources.rb \
|
||||
src/oneprovision/lib/utils.rb"
|
||||
ONEPROVISION_LIB_FILES="src/oneprovision/lib/oneprovision.rb \
|
||||
src/oneprovision/lib/provision_element.rb"
|
||||
|
||||
ONEPROVISION_LIB_RESOURCES_FILES="src/oneprovision/lib/resources/virtual.rb \
|
||||
src/oneprovision/lib/resources/resource.rb \
|
||||
src/oneprovision/lib/resources/physical.rb"
|
||||
ONEPROVISION_LIB_PROVISION_FILES="src/oneprovision/lib/provision/ansible.rb \
|
||||
src/oneprovision/lib/provision/oneprovision.rb \
|
||||
src/oneprovision/lib/provision/driver.rb \
|
||||
src/oneprovision/lib/provision/provision.rb \
|
||||
src/oneprovision/lib/provision/provision_pool.rb \
|
||||
src/oneprovision/lib/provision/resources.rb \
|
||||
src/oneprovision/lib/provision/utils.rb"
|
||||
|
||||
ONEPROVISION_LIB_PHYSICAL_R_FILES="src/oneprovision/lib/resources/physical/cluster.rb \
|
||||
src/oneprovision/lib/resources/physical/datastore.rb \
|
||||
src/oneprovision/lib/resources/physical/host.rb \
|
||||
src/oneprovision/lib/resources/physical/physical_resource.rb \
|
||||
src/oneprovision/lib/resources/physical/network.rb"
|
||||
ONEPROVISION_LIB_RESOURCES_FILES="src/oneprovision/lib/provision/resources/virtual.rb \
|
||||
src/oneprovision/lib/provision/resources/resource.rb \
|
||||
src/oneprovision/lib/provision/resources/physical.rb"
|
||||
|
||||
ONEPROVISION_LIB_VIRTUAL_R_FILES="src/oneprovision/lib/resources/virtual/virtual_resource.rb \
|
||||
src/oneprovision/lib/resources/virtual/virtual_sync_resource.rb \
|
||||
src/oneprovision/lib/resources/virtual/image.rb \
|
||||
src/oneprovision/lib/resources/virtual/marketplaceapp.rb \
|
||||
src/oneprovision/lib/resources/virtual/template.rb \
|
||||
src/oneprovision/lib/resources/virtual/flowtemplate.rb \
|
||||
src/oneprovision/lib/resources/virtual/vntemplate.rb"
|
||||
ONEPROVISION_LIB_PHYSICAL_R_FILES="src/oneprovision/lib/provision/resources/physical/cluster.rb \
|
||||
src/oneprovision/lib/provision/resources/physical/datastore.rb \
|
||||
src/oneprovision/lib/provision/resources/physical/host.rb \
|
||||
src/oneprovision/lib/provision/resources/physical/physical_resource.rb \
|
||||
src/oneprovision/lib/provision/resources/physical/network.rb"
|
||||
|
||||
ONEPROVISION_LIB_VIRTUAL_R_FILES="src/oneprovision/lib/provision/resources/virtual/virtual_resource.rb \
|
||||
src/oneprovision/lib/provision/resources/virtual/virtual_sync_resource.rb \
|
||||
src/oneprovision/lib/provision/resources/virtual/image.rb \
|
||||
src/oneprovision/lib/provision/resources/virtual/marketplaceapp.rb \
|
||||
src/oneprovision/lib/provision/resources/virtual/template.rb \
|
||||
src/oneprovision/lib/provision/resources/virtual/flowtemplate.rb \
|
||||
src/oneprovision/lib/provision/resources/virtual/vntemplate.rb"
|
||||
|
||||
ONEPROVISION_LIB_PROVIDER_FILES="src/oneprovision/lib/provider/provider.rb \
|
||||
src/oneprovision/lib/provider/provider_pool.rb"
|
||||
|
||||
ONEPROVISION_LIB_PROVISION_TEMPLATE_FILES="src/oneprovision/lib/provision_template/provision_template.rb \
|
||||
src/oneprovision/lib/provision_template/provision_template_pool.rb"
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Sunstone files
|
||||
|
@ -991,9 +991,10 @@ VM_ENCRYPTED_ATTR = "CONTEXT/PASSWORD"
|
||||
# VNET_ENCRYPTED_ATTR = "PROVISION/PACKET_TOKEN
|
||||
|
||||
# DDC encrypted attrs
|
||||
HOST_ENCRYPTED_ATTR = "PROVISION/PACKET_TOKEN"
|
||||
HOST_ENCRYPTED_ATTR = "PROVISION/EC2_ACCESS"
|
||||
HOST_ENCRYPTED_ATTR = "PROVISION/EC2_SECRET"
|
||||
HOST_ENCRYPTED_ATTR = "PROVISION/PACKET_TOKEN"
|
||||
HOST_ENCRYPTED_ATTR = "PROVISION/EC2_ACCESS"
|
||||
HOST_ENCRYPTED_ATTR = "PROVISION/EC2_SECRET"
|
||||
DOCUMENT_ENCRYPTED_ATTR = "PROVISION_BODY"
|
||||
|
||||
VNET_ENCRYPTED_ATTR = "AR/PACKET_TOKEN"
|
||||
|
||||
|
@ -520,6 +520,8 @@ AllCops:
|
||||
- src/tm_mad/one_tm.rb
|
||||
- src/oca/ruby/opennebula/flow/grammar.rb
|
||||
- src/oca/ruby/opennebula/flow/validator.rb
|
||||
- src/sunstone/models/OpenNebulaValidateFireedge.rb
|
||||
- src/sunstone/OpenNebulaVMRC.rb
|
||||
NewCops: enable
|
||||
|
||||
########
|
||||
|
@ -45,7 +45,10 @@ COMMANDS=(
|
||||
'onemarketapp' 'manages appliances from Marketplaces'
|
||||
'onevmgroup' 'manages VM groups'
|
||||
'onevntemplate' 'manages Virtual Network Templates'
|
||||
'oneprovision' 'manages OpenNebula provisions'
|
||||
|
||||
'oneprovision' 'manages OpenNebula provisions'
|
||||
'oneprovider' 'manages OpenNebula providers'
|
||||
'oneprovision-template' 'manages OpenNebula provision templates'
|
||||
|
||||
'oneflow' 'Manage oneFlow Services'
|
||||
'oneflow-template' 'Manage oneFlow Templates'
|
||||
|
@ -518,6 +518,52 @@ _oneprovision() {
|
||||
fi
|
||||
}
|
||||
|
||||
_oneprovision_template() {
|
||||
local cur prev opts cmd
|
||||
COMPREPLY=()
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||
opts="create instantiate list show delete update"
|
||||
cmd=oneprovision-template
|
||||
if [ "$COMP_CWORD" == 1 ]; then
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||
return 0
|
||||
elif [ "$COMP_CWORD" == 2 ]; then
|
||||
case "$prev" in
|
||||
show|delete|update|instantiate)
|
||||
_complete $cmd ID
|
||||
;;
|
||||
create)
|
||||
COMPREPLY=( $(compgen -A file -- "${cur}") )
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
}
|
||||
|
||||
_oneprovider() {
|
||||
local cur prev opts cmd
|
||||
COMPREPLY=()
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||
opts="create list show delete update"
|
||||
cmd=oneprovider
|
||||
if [ "$COMP_CWORD" == 1 ]; then
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||
return 0
|
||||
elif [ "$COMP_CWORD" == 2 ]; then
|
||||
case "$prev" in
|
||||
show|delete|update)
|
||||
_complete $cmd ID
|
||||
;;
|
||||
create)
|
||||
COMPREPLY=( $(compgen -A file -- "${cur}") )
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
}
|
||||
|
||||
_onesecgroup() {
|
||||
local cur prev opts cmd
|
||||
COMPREPLY=()
|
||||
@ -864,6 +910,8 @@ complete -F _oneimage oneimage
|
||||
complete -F _onemarket onemarket
|
||||
complete -F _onemarketapp onemarketapp
|
||||
complete -F _oneprovision oneprovision
|
||||
complete -F _oneprovision_template oneprovision-template
|
||||
complete -F _oneprovider oneprovider
|
||||
complete -F _onesecgroup onesecgroup
|
||||
complete -F _oneshowback oneshowback
|
||||
complete -F _onetemplate onetemplate
|
||||
|
19
src/cli/etc/oneprovider.yaml
Normal file
19
src/cli/etc/oneprovider.yaml
Normal file
@ -0,0 +1,19 @@
|
||||
---
|
||||
:ID:
|
||||
:desc: Provider identifier
|
||||
:size: 4
|
||||
|
||||
:NAME:
|
||||
:desc: Name of the Provider
|
||||
:size: 15
|
||||
:left: true
|
||||
:expand: true
|
||||
|
||||
:REGTIME:
|
||||
:desc: Registration time of the Provider
|
||||
:size: 15
|
||||
|
||||
:default:
|
||||
- :ID
|
||||
- :NAME
|
||||
- :REGTIME
|
19
src/cli/etc/oneprovision_template.yaml
Normal file
19
src/cli/etc/oneprovision_template.yaml
Normal file
@ -0,0 +1,19 @@
|
||||
---
|
||||
:ID:
|
||||
:desc: Provision Template identifier
|
||||
:size: 4
|
||||
|
||||
:NAME:
|
||||
:desc: Name of the Provision Template
|
||||
:size: 15
|
||||
:left: true
|
||||
:expand: true
|
||||
|
||||
:REGTIME:
|
||||
:desc: Registration time of the Provision Template
|
||||
:size: 15
|
||||
|
||||
:default:
|
||||
- :ID
|
||||
- :NAME
|
||||
- :REGTIME
|
@ -613,8 +613,15 @@ EOT
|
||||
pname = pool.pool_name
|
||||
ename = pool.element_name
|
||||
|
||||
page = pool.to_hash
|
||||
elems = page["#{pname}"]["#{ename}"]
|
||||
if options[:decrypt]
|
||||
page = pool.map do |element|
|
||||
element.info(true)
|
||||
element.to_hash[ename]
|
||||
end
|
||||
else
|
||||
page = pool.to_hash
|
||||
elems = page[pname][ename]
|
||||
end
|
||||
|
||||
if elems.class == Array
|
||||
elements = elems.length
|
||||
@ -1561,6 +1568,39 @@ EOT
|
||||
end
|
||||
end
|
||||
|
||||
def OpenNebulaHelper.update_obj(obj, file)
|
||||
rc = obj.info(true)
|
||||
|
||||
return rc if OpenNebula.is_error?(rc)
|
||||
|
||||
if file
|
||||
path = file
|
||||
else
|
||||
tmp = Tempfile.new(obj['ID'])
|
||||
path = tmp.path
|
||||
|
||||
tmp.write(yield(obj)) if block_given?
|
||||
tmp.flush
|
||||
|
||||
if ENV['EDITOR']
|
||||
editor_path = ENV['EDITOR']
|
||||
else
|
||||
editor_path = EDITOR_PATH
|
||||
end
|
||||
|
||||
system("#{editor_path} #{path}")
|
||||
|
||||
unless $CHILD_STATUS.exitstatus.zero?
|
||||
STDERR.puts 'Editor not defined'
|
||||
exit(-1)
|
||||
end
|
||||
|
||||
tmp.close
|
||||
end
|
||||
|
||||
obj.update(File.read(path))
|
||||
end
|
||||
|
||||
def OpenNebulaHelper.editor_input(contents=nil)
|
||||
require 'tempfile'
|
||||
|
||||
|
199
src/cli/one_helper/oneprovider_helper.rb
Normal file
199
src/cli/one_helper/oneprovider_helper.rb
Normal file
@ -0,0 +1,199 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2020, OpenNebula Project, OpenNebula Systems #
|
||||
# #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'json'
|
||||
require 'yaml'
|
||||
|
||||
require 'provision_element'
|
||||
|
||||
# OneProvider Helper
|
||||
class OneProviderHelper < OpenNebulaHelper::OneHelper
|
||||
|
||||
TAG = OneProvision::ProvisionElement::TEMPLATE_TAG
|
||||
|
||||
# Resource name
|
||||
def self.rname
|
||||
'DOCUMENT'
|
||||
end
|
||||
|
||||
# Configuration file name
|
||||
def self.conf_file
|
||||
'oneprovider.yaml'
|
||||
end
|
||||
|
||||
# Format pool for CLI list operation
|
||||
def format_pool(_)
|
||||
config_file = self.class.table_conf
|
||||
|
||||
CLIHelper::ShowTable.new(config_file, self) do
|
||||
column :ID, 'Provider identifier', :size => 4 do |p|
|
||||
p['ID']
|
||||
end
|
||||
|
||||
column :NAME, 'Name of the provider', :left, :size => 25 do |p|
|
||||
p['NAME']
|
||||
end
|
||||
|
||||
column :REGTIME,
|
||||
'Registration time of the Provider',
|
||||
:size => 15 do |p|
|
||||
p.extend(CLIHelper::HashWithSearch)
|
||||
p = JSON.parse(p.dsearch("TEMPLATE/#{TAG}"))
|
||||
|
||||
OpenNebulaHelper.time_to_str(p['registration_time'])
|
||||
end
|
||||
|
||||
default :ID, :NAME, :REGTIME
|
||||
end
|
||||
end
|
||||
|
||||
# Shows provider information
|
||||
#
|
||||
# @param id [Integer] Provider ID
|
||||
# @param options [Hash] User CLI options
|
||||
#
|
||||
# @return [Array] [rc, information to show]
|
||||
def show_resource(id, options)
|
||||
# Add body paremter to get resource in hash format
|
||||
options[:body] = true
|
||||
options[:decrypt] = true
|
||||
info = super
|
||||
|
||||
return info if info[0] != 0
|
||||
|
||||
if options[:json]
|
||||
info[1]['DOCUMENT']['TEMPLATE'][TAG] = JSON.parse(
|
||||
info[1]['DOCUMENT']['TEMPLATE'][TAG]
|
||||
)
|
||||
info[1] = JSON.pretty_generate(info[1])
|
||||
elsif options[:yaml]
|
||||
yaml = YAML.safe_load(info[1])
|
||||
yaml['DOCUMENT']['TEMPLATE'][TAG] = JSON.parse(
|
||||
yaml['DOCUMENT']['TEMPLATE'][TAG]
|
||||
)
|
||||
info[1] = yaml.to_yaml(:indent => 4)
|
||||
end
|
||||
|
||||
info
|
||||
end
|
||||
|
||||
# Format resource to output it in show command
|
||||
#
|
||||
# @param provider [Hash] Provider information
|
||||
def format_resource(provider, _)
|
||||
str_h1 = '%-80s'
|
||||
id = provider['ID']
|
||||
body = provider.body
|
||||
|
||||
CLIHelper.print_header(str_h1 % "PROVIDER #{id} INFORMATION")
|
||||
puts format('ID : %<s>s', :s => id)
|
||||
puts format('NAME : %<s>s', :s => provider['NAME'])
|
||||
|
||||
# Get max size to adjust all the values
|
||||
size = body['connection'].keys.map {|k| k.size }.max
|
||||
data = {}
|
||||
|
||||
# Generate data value with the new key adjusted format
|
||||
body['connection'].map {|k, v| data[k.ljust(size)] = v }
|
||||
|
||||
puts
|
||||
CLIHelper.print_header(str_h1 % 'CONNECTION INFORMATION')
|
||||
data.each do |key, value|
|
||||
CLIHelper.scr_bold
|
||||
print "#{key} : "
|
||||
CLIHelper.scr_restore
|
||||
puts value
|
||||
end
|
||||
end
|
||||
|
||||
#######################################################################
|
||||
# Helper provider functions
|
||||
#######################################################################
|
||||
|
||||
# Creates a new provider
|
||||
#
|
||||
# @param template [String] Path to file with template information
|
||||
#
|
||||
# @param [Integer] Provider ID
|
||||
def create(template)
|
||||
rc = validate(template)
|
||||
|
||||
return rc if OpenNebula.is_error?(rc)
|
||||
|
||||
xml = OneProvision::Provider.build_xml
|
||||
provider = OneProvision::Provider.new(xml, @client)
|
||||
|
||||
rc = provider.allocate(rc)
|
||||
|
||||
return rc if OpenNebula.is_error?(rc)
|
||||
|
||||
rc = provider.info(true)
|
||||
|
||||
return rc if OpenNebula.is_error?(rc)
|
||||
|
||||
provider['ID']
|
||||
end
|
||||
|
||||
# Updates provider information
|
||||
#
|
||||
# @param provider [OneProvision::Provider] Provider object
|
||||
# @param file [String] Path to file with update content
|
||||
#
|
||||
# @return [0, OpenNebula::Error]
|
||||
def update(provider, file)
|
||||
OpenNebulaHelper.update_obj(provider, file) do |prov|
|
||||
JSON.pretty_generate(prov.body)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Validates that configuration file can be loaded and it follows structure
|
||||
#
|
||||
# @param template [String] Path to file with template information
|
||||
#
|
||||
# @return [YAML] Template in YAML format
|
||||
def validate(template)
|
||||
begin
|
||||
template = YAML.load_file(template)
|
||||
|
||||
raise 'Name not found' unless template['name']
|
||||
raise 'Connection info not found' unless template['connection']
|
||||
|
||||
template
|
||||
rescue StandardError => e
|
||||
OpenNebula::Error.new("ERROR: #{e}")
|
||||
end
|
||||
end
|
||||
|
||||
# Returns a new provider object
|
||||
#
|
||||
# @param id [Integer] Provider ID
|
||||
def factory(id = nil)
|
||||
if id
|
||||
OneProvision::Provider.new_with_id(id, @client)
|
||||
else
|
||||
OneProvision::Provider.new(OneProvision::Provider.build_xml,
|
||||
@client)
|
||||
end
|
||||
end
|
||||
|
||||
# Returns provider pool
|
||||
def factory_pool(_)
|
||||
OneProvision::ProviderPool.new(@client)
|
||||
end
|
||||
|
||||
end
|
@ -16,9 +16,227 @@
|
||||
|
||||
require 'json'
|
||||
|
||||
require 'oneprovision'
|
||||
|
||||
# OneProvision Helper
|
||||
class OneProvisionHelper < OpenNebulaHelper::OneHelper
|
||||
|
||||
########################################################################
|
||||
# Global Options
|
||||
########################################################################
|
||||
|
||||
############################ Output Modes ##############################
|
||||
|
||||
VERBOSE = {
|
||||
:name => 'verbose',
|
||||
:short => '-d',
|
||||
:large => '--verbose',
|
||||
:description => 'Set verbose logging mode'
|
||||
}
|
||||
|
||||
DEBUG = {
|
||||
:name => 'debug',
|
||||
:short => '-D',
|
||||
:large => '--debug',
|
||||
:description => 'Set debug logging mode',
|
||||
:format => String
|
||||
}
|
||||
|
||||
############################# Run Modes ################################
|
||||
|
||||
BATCH = {
|
||||
:name => 'batch',
|
||||
:short => '-b',
|
||||
:large => '--batch',
|
||||
:description => 'Run in non-interactive mode (no questions)',
|
||||
:format => String
|
||||
}
|
||||
|
||||
FAIL_MODES = {
|
||||
:name => 'fail_modes',
|
||||
:large => '--fail-modes mode1,mode2',
|
||||
:description => 'Fail modes to apply in order',
|
||||
:format => Array,
|
||||
:proc => lambda do |_, options|
|
||||
options = options[:fail_modes].map do |v|
|
||||
v = v.downcase.to_sym
|
||||
|
||||
unless OneProvision::DEFAULT_FAIL_MODES.include?(v)
|
||||
STDERR.puts "Wrong fail mode `#{v}`"
|
||||
exit(-1)
|
||||
end
|
||||
|
||||
v
|
||||
end
|
||||
|
||||
[0, options]
|
||||
end
|
||||
}
|
||||
|
||||
FAIL_RETRY = {
|
||||
:name => 'fail_retry',
|
||||
:large => '--fail-retry number',
|
||||
:description => 'Set batch failover mode to number of retries',
|
||||
:format => Integer
|
||||
}
|
||||
|
||||
FAIL_CLEANUP = {
|
||||
:name => 'fail_cleanup',
|
||||
:large => '--fail-cleanup',
|
||||
:description => 'Set batch failover mode to clean up and quit'
|
||||
}
|
||||
|
||||
FAIL_SKIP = {
|
||||
:name => 'fail_skip',
|
||||
:large => '--fail-skip',
|
||||
:description => 'Set batch failover mode to skip failing part'
|
||||
}
|
||||
|
||||
FAIL_QUIT = {
|
||||
:name => 'fail_quit',
|
||||
:large => '--fail-quit',
|
||||
:description => 'Set batch failover mode to quit (default)'
|
||||
}
|
||||
|
||||
FAIL_SLEEP = {
|
||||
:name => 'fail_sleep',
|
||||
:large => '--fail-sleep seconds',
|
||||
:description => 'Time in seconds between each fail mode is executed ' \
|
||||
'and between each retry',
|
||||
:format => Integer
|
||||
}
|
||||
|
||||
############################## Create ##################################
|
||||
|
||||
PING_TIMEOUT = {
|
||||
:name => 'ping_timeout',
|
||||
:large => '--ping-timeout seconds',
|
||||
:description => 'Set timeout for ping ' \
|
||||
"(default: #{OneProvision::PING_TIMEOUT_DEFAULT} secs)",
|
||||
:format => Integer
|
||||
}
|
||||
|
||||
PING_RETRIES = {
|
||||
:name => 'ping_retries',
|
||||
:large => '--ping-retries number',
|
||||
:description => 'Set retries for ping ' \
|
||||
"(default: #{OneProvision::PING_RETRIES_DEFAULT})",
|
||||
:format => Integer
|
||||
}
|
||||
|
||||
SKIP_PROVISION = {
|
||||
:name => 'skip_provision',
|
||||
:large => '--skip-provision',
|
||||
:description => 'Skip provision and configuration hosts phases'
|
||||
}
|
||||
|
||||
SKIP_CONFIG = {
|
||||
:name => 'skip_config',
|
||||
:large => '--skip-config',
|
||||
:description => 'Skip configuration hosts phase'
|
||||
}
|
||||
|
||||
WAIT_READY = {
|
||||
:name => 'wait_ready',
|
||||
:large => '--wait-ready',
|
||||
:description => 'Wait resources to be ready in OpenNebula'
|
||||
}
|
||||
|
||||
WAIT_TIMEOUT = {
|
||||
:name => 'wait_timeout',
|
||||
:large => '--wait-timeout timeout',
|
||||
:description => 'Timeout to wait objects to be ready',
|
||||
:format => Integer
|
||||
}
|
||||
|
||||
PROVIDER = {
|
||||
:name => 'provider',
|
||||
:large => '--provider provider',
|
||||
:description => 'Provider to deploy provision',
|
||||
:format => String
|
||||
}
|
||||
|
||||
########################################################################
|
||||
|
||||
THREADS = {
|
||||
:name => 'threads',
|
||||
:short => '-t threads',
|
||||
:large => '--threads threads',
|
||||
:description => 'Set threads for create (default: ' \
|
||||
"#{OneProvision::THREADS_DEFAULT})",
|
||||
:format => Integer
|
||||
}
|
||||
|
||||
FORCE = {
|
||||
:name => 'force',
|
||||
:short => '-F',
|
||||
:large => '--force',
|
||||
:description => 'Force configure to execute',
|
||||
:format => String
|
||||
}
|
||||
|
||||
HARD = {
|
||||
:name => 'hard',
|
||||
:short => '-H',
|
||||
:large => '--hard',
|
||||
:description => 'Reset the host',
|
||||
:format => String
|
||||
}
|
||||
|
||||
CLEANUP = {
|
||||
:name => 'cleanup',
|
||||
:large => '--cleanup',
|
||||
:description => 'Delete all vms and images first, ' \
|
||||
'then delete the resources.'
|
||||
}
|
||||
|
||||
CLEANUP_TIMEOUT = {
|
||||
:name => 'cleanup_timeout',
|
||||
:large => '--cleanup-timeout timeout',
|
||||
:description => 'Change the default timeout when deleting VMs/Images.'
|
||||
}
|
||||
|
||||
DUMP = {
|
||||
:name => 'dump',
|
||||
:large => '--dump',
|
||||
:description => 'Dump the configuration file result.'
|
||||
}
|
||||
|
||||
DONE = {
|
||||
:name => 'done',
|
||||
:large => '--done',
|
||||
:description => 'List provisions in DONE state'
|
||||
}
|
||||
|
||||
########################################################################
|
||||
|
||||
MODES = CommandParser::OPTIONS - [CommandParser::VERBOSE] +
|
||||
[VERBOSE,
|
||||
DEBUG,
|
||||
BATCH,
|
||||
FAIL_RETRY,
|
||||
FAIL_CLEANUP,
|
||||
FAIL_SKIP,
|
||||
FAIL_QUIT,
|
||||
FAIL_MODES,
|
||||
FAIL_SLEEP]
|
||||
|
||||
CREATE_OPTIONS = [THREADS,
|
||||
MODES,
|
||||
PING_TIMEOUT,
|
||||
PING_RETRIES,
|
||||
CLEANUP,
|
||||
CLEANUP_TIMEOUT,
|
||||
SKIP_PROVISION,
|
||||
SKIP_CONFIG,
|
||||
WAIT_READY,
|
||||
WAIT_TIMEOUT,
|
||||
PROVIDER]
|
||||
|
||||
ONE_OPTIONS = CommandParser::OPTIONS +
|
||||
CLIHelper::OPTIONS +
|
||||
OpenNebulaHelper::OPTIONS
|
||||
|
||||
# Resource name
|
||||
def self.rname
|
||||
'DOCUMENT'
|
||||
@ -53,27 +271,37 @@ class OneProvisionHelper < OpenNebulaHelper::OneHelper
|
||||
end
|
||||
|
||||
column :CLUSTERS, 'Number of Clusters', :size => 8 do |p|
|
||||
p = OneProvisionHelper.body(p)
|
||||
p.extend(CLIHelper::HashWithSearch)
|
||||
p = JSON.parse(p.dsearch('TEMPLATE/BODY'))
|
||||
|
||||
p['provision']['infrastructure']['clusters'].size rescue 0
|
||||
end
|
||||
|
||||
column :HOSTS, 'Number of Hosts', :size => 5 do |p|
|
||||
p = OneProvisionHelper.body(p)
|
||||
p.extend(CLIHelper::HashWithSearch)
|
||||
p = JSON.parse(p.dsearch('TEMPLATE/BODY'))
|
||||
|
||||
p['provision']['infrastructure']['hosts'].size rescue 0
|
||||
end
|
||||
|
||||
column :NETWORKS, 'Number of Networks', :size => 8 do |p|
|
||||
p = OneProvisionHelper.body(p)
|
||||
p.extend(CLIHelper::HashWithSearch)
|
||||
p = JSON.parse(p.dsearch('TEMPLATE/BODY'))
|
||||
|
||||
p['provision']['infrastructure']['networks'].size rescue 0
|
||||
end
|
||||
|
||||
column :DATASTORES, 'Number of Datastores', :size => 10 do |p|
|
||||
p = OneProvisionHelper.body(p)
|
||||
p.extend(CLIHelper::HashWithSearch)
|
||||
p = JSON.parse(p.dsearch('TEMPLATE/BODY'))
|
||||
|
||||
p['provision']['infrastructure']['datastores'].size rescue 0
|
||||
end
|
||||
|
||||
column :STAT, 'Provision state', :size => 12 do |p|
|
||||
p = OneProvisionHelper.body(p)
|
||||
p.extend(CLIHelper::HashWithSearch)
|
||||
p = JSON.parse(p.dsearch('TEMPLATE/BODY'))
|
||||
|
||||
OneProvision::Provision::STATE_STR[p['state']] rescue '-'
|
||||
end
|
||||
|
||||
@ -113,10 +341,11 @@ class OneProvisionHelper < OpenNebulaHelper::OneHelper
|
||||
body = provision.body
|
||||
|
||||
CLIHelper.print_header(str_h1 % "PROVISION #{id} INFORMATION")
|
||||
puts format('ID : %<s>s', :s => id)
|
||||
puts format('NAME : %<s>s', :s => provision['NAME'])
|
||||
puts format('STATE : %<s>s',
|
||||
puts format('ID : %<s>s', :s => id)
|
||||
puts format('NAME : %<s>s', :s => provision['NAME'])
|
||||
puts format('STATE : %<s>s',
|
||||
:s => OneProvision::Provision::STATE_STR[body['state']])
|
||||
puts format('PROVIDER : %<s>s', :s => body['provider'])
|
||||
|
||||
infrastructure = provision.infrastructure_objects
|
||||
resource = provision.resource_objects
|
||||
@ -138,17 +367,27 @@ class OneProvisionHelper < OpenNebulaHelper::OneHelper
|
||||
|
||||
# Creates a new provision
|
||||
#
|
||||
# @param config [String] Path to deployment file
|
||||
# @param cleanup [Boolean] True to cleanup everything
|
||||
# @param timeout [Integer] Timeout in seconds to connect to hosts
|
||||
# @param skip [Symbol] Skip provision, configuration or anything
|
||||
# @param config [String] Path to deployment file
|
||||
# @param cleanup [Boolean] True to cleanup everything
|
||||
# @param timeout [Integer] Timeout in seconds to connect to hosts
|
||||
# @param skip [Symbol] Skip provision, configuration or anything
|
||||
# @param provider [String/Integer] Provider to deploy the provision
|
||||
#
|
||||
# @param [Intenger] New provision ID
|
||||
def create(config, cleanup, timeout, skip)
|
||||
def create(config, cleanup, timeout, skip, provider)
|
||||
xml = OneProvision::Provision.build_xml
|
||||
provision = OneProvision::Provision.new(xml, @client)
|
||||
|
||||
provision.deploy(config, cleanup, timeout, skip)
|
||||
# If user has sepcified a provider, get it from the pool
|
||||
if provider
|
||||
provider = OneProvision::Provider.by_name(@client, provider)
|
||||
|
||||
return provider if OpenNebula.is_error?(provider)
|
||||
|
||||
return OpenNebula::Error.new('Provider not found') unless provider
|
||||
end
|
||||
|
||||
provision.deploy(config, cleanup, timeout, skip, provider)
|
||||
end
|
||||
|
||||
# Configures provision hosts
|
||||
@ -300,7 +539,8 @@ class OneProvisionHelper < OpenNebulaHelper::OneHelper
|
||||
|
||||
# Iterate over pool to get IDs and get the filter option
|
||||
pool.each do |obj|
|
||||
body = OneProvisionHelper.body(obj)
|
||||
obj.extend(CLIHelper::HashWithSearch)
|
||||
body = JSON.parse(obj.dsearch('TEMPLATE/BODY'))
|
||||
|
||||
next unless body['provision'][path][type.downcase]
|
||||
|
||||
@ -358,17 +598,6 @@ class OneProvisionHelper < OpenNebulaHelper::OneHelper
|
||||
OneProvision::ProvisionPool.new(@client)
|
||||
end
|
||||
|
||||
class << self
|
||||
|
||||
# Returns provision body in JSON format
|
||||
#
|
||||
# @param document [Hash] Provision document
|
||||
def body(document)
|
||||
JSON.parse(document['TEMPLATE']['BODY'])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Returns helper and filter depending on type
|
||||
#
|
||||
# @param type [String] Helper type
|
||||
|
199
src/cli/one_helper/oneprovision_template_helper.rb
Normal file
199
src/cli/one_helper/oneprovision_template_helper.rb
Normal file
@ -0,0 +1,199 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2020, OpenNebula Project, OpenNebula Systems #
|
||||
# #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'json'
|
||||
require 'yaml'
|
||||
|
||||
# OneProvisionTemplate Helper
|
||||
class OneProvisionTemplateHelper < OpenNebulaHelper::OneHelper
|
||||
|
||||
TAG = OneProvision::ProvisionElement::TEMPLATE_TAG
|
||||
|
||||
# Resource name
|
||||
def self.rname
|
||||
'DOCUMENT'
|
||||
end
|
||||
|
||||
# Configuration file name
|
||||
def self.conf_file
|
||||
'oneprovision_template.yaml'
|
||||
end
|
||||
|
||||
# Format pool for CLI list operation
|
||||
def format_pool(_)
|
||||
config_file = self.class.table_conf
|
||||
|
||||
CLIHelper::ShowTable.new(config_file, self) do
|
||||
column :ID, 'Provision Template identifier', :size => 4 do |p|
|
||||
p['ID']
|
||||
end
|
||||
|
||||
column :NAME, 'Name of the template', :left, :size => 25 do |p|
|
||||
p['NAME']
|
||||
end
|
||||
|
||||
column :REGTIME,
|
||||
'Registration time of the Provision Template',
|
||||
:size => 15 do |p|
|
||||
p.extend(CLIHelper::HashWithSearch)
|
||||
p = JSON.parse(p.dsearch("TEMPLATE/#{TAG}"))
|
||||
|
||||
OpenNebulaHelper.time_to_str(p['registration_time'])
|
||||
end
|
||||
|
||||
default :ID, :NAME, :REGTIME
|
||||
end
|
||||
end
|
||||
|
||||
# Shows provision template information
|
||||
#
|
||||
# @param id [Integer] Template ID
|
||||
# @param options [Hash] User CLI options
|
||||
#
|
||||
# @return [Array] [rc, information to show]
|
||||
def show_resource(id, options)
|
||||
# Add body paremter to get resource in hash format
|
||||
options[:body] = true
|
||||
options[:decrypt] = true
|
||||
info = super
|
||||
|
||||
return info if info[0] != 0
|
||||
|
||||
if options[:json]
|
||||
info[1]['DOCUMENT']['TEMPLATE'][TAG] = JSON.parse(
|
||||
info[1]['DOCUMENT']['TEMPLATE'][TAG]
|
||||
)
|
||||
info[1] = JSON.pretty_generate(info[1])
|
||||
elsif options[:yaml]
|
||||
yaml = YAML.safe_load(info[1])
|
||||
yaml['DOCUMENT']['TEMPLATE'][TAG] = JSON.parse(
|
||||
yaml['DOCUMENT']['TEMPLATE'][TAG]
|
||||
)
|
||||
info[1] = yaml.to_yaml(:indent => 4)
|
||||
end
|
||||
|
||||
info
|
||||
end
|
||||
|
||||
# Format resource to output it in show command
|
||||
#
|
||||
# @param template [Hash] Provision template information
|
||||
def format_resource(template, _)
|
||||
str_h1 = '%-80s'
|
||||
id = template['ID']
|
||||
body = template.body
|
||||
|
||||
CLIHelper.print_header(str_h1 % "PROVISION TEMPLATE #{id} INFORMATION")
|
||||
puts format('ID : %<s>s', :s => id)
|
||||
puts format('NAME : %<s>s', :s => template['NAME'])
|
||||
|
||||
puts
|
||||
CLIHelper.print_header(str_h1 % 'PROVISION TEMPLATE')
|
||||
puts JSON.pretty_generate(body)
|
||||
end
|
||||
|
||||
#######################################################################
|
||||
# Helper provision template functions
|
||||
#######################################################################
|
||||
|
||||
# Creates a new provision template
|
||||
#
|
||||
# @param template [String] Path to file with template information
|
||||
#
|
||||
# @param [Integer] Provision Template ID
|
||||
def create(template)
|
||||
rc = validate(template)
|
||||
|
||||
return rc if OpenNebula.is_error?(rc)
|
||||
|
||||
xml = OneProvision::ProvisionTemplate.build_xml
|
||||
template = OneProvision::ProvisionTemplate.new(xml, @client)
|
||||
|
||||
rc = template.allocate(rc)
|
||||
|
||||
return rc if OpenNebula.is_error?(rc)
|
||||
|
||||
rc = template.info(true)
|
||||
|
||||
return rc if OpenNebula.is_error?(rc)
|
||||
|
||||
template['ID']
|
||||
end
|
||||
|
||||
# Updates provision template information
|
||||
#
|
||||
# @param template [OneProvision::ProvisionTemplate] Template object
|
||||
# @param file [String] Path to file with update content
|
||||
#
|
||||
# @return [0, OpenNebula::Error]
|
||||
def update(template, file)
|
||||
OpenNebulaHelper.update_obj(template, file) do |tmpl|
|
||||
JSON.pretty_generate(tmpl.body)
|
||||
end
|
||||
end
|
||||
|
||||
# Updates provision template information
|
||||
#
|
||||
# @param template [OneProvision::ProvisionTemplate] Template object
|
||||
#
|
||||
# @return [0, OpenNebula::Error]
|
||||
def instantiate(template)
|
||||
rc = template.info(true)
|
||||
|
||||
return rc if OpenNebula.is_error?(rc)
|
||||
|
||||
template.instantiate
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Validates that configuration file can be loaded and it follows structure
|
||||
#
|
||||
# @param template [String] Path to file with template information
|
||||
#
|
||||
# @return [YAML] Template in YAML format
|
||||
def validate(template)
|
||||
begin
|
||||
template = OneProvision::Utils.read_config(template)
|
||||
provider = OneProvision::Provision.read_provider(template)
|
||||
|
||||
raise 'Name not found' unless template['name']
|
||||
raise 'Provider not found in template' unless provider
|
||||
|
||||
template
|
||||
rescue StandardError => e
|
||||
OpenNebula::Error.new("ERROR: #{e}")
|
||||
end
|
||||
end
|
||||
|
||||
# Returns a new provision template object
|
||||
#
|
||||
# @param id [Integer] Provision Template ID
|
||||
def factory(id = nil)
|
||||
if id
|
||||
OneProvision::ProvisionTemplate.new_with_id(id, @client)
|
||||
else
|
||||
xml = OneProvision::ProvisionTemplate.build_xml
|
||||
OneProvision::ProvisionTemplate.new(xml, @client)
|
||||
end
|
||||
end
|
||||
|
||||
# Returns provision template pool
|
||||
def factory_pool(_)
|
||||
OneProvision::ProvisionTemplatePool.new(@client)
|
||||
end
|
||||
|
||||
end
|
214
src/cli/oneprovider
Executable file
214
src/cli/oneprovider
Executable file
@ -0,0 +1,214 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2020, OpenNebula Project, OpenNebula Systems #
|
||||
# #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
ONE_LOCATION = ENV['ONE_LOCATION']
|
||||
|
||||
if !ONE_LOCATION
|
||||
LIB_LOCATION = '/usr/lib/one'
|
||||
RUBY_LIB_LOCATION = '/usr/lib/one/ruby'
|
||||
GEMS_LOCATION = '/usr/share/one/gems'
|
||||
else
|
||||
LIB_LOCATION = ONE_LOCATION + '/lib'
|
||||
RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby'
|
||||
GEMS_LOCATION = ONE_LOCATION + '/share/gems'
|
||||
end
|
||||
|
||||
if File.directory?(GEMS_LOCATION)
|
||||
$LOAD_PATH.reject! {|l| l =~ /vendor_ruby/ }
|
||||
require 'rubygems'
|
||||
Gem.use_paths(File.realpath(GEMS_LOCATION))
|
||||
end
|
||||
|
||||
$LOAD_PATH << RUBY_LIB_LOCATION
|
||||
$LOAD_PATH << RUBY_LIB_LOCATION + '/cli'
|
||||
$LOAD_PATH << LIB_LOCATION + '/oneprovision/lib'
|
||||
$LOAD_PATH << LIB_LOCATION + '/oneflow/lib'
|
||||
|
||||
require 'command_parser'
|
||||
|
||||
require 'one_helper'
|
||||
require 'one_helper/onegroup_helper'
|
||||
require 'one_helper/oneprovider_helper'
|
||||
|
||||
require 'oneprovision'
|
||||
|
||||
CommandParser::CmdParser.new(ARGV) do
|
||||
usage '`oneprovider` <command> [<file>] [<args>] [<options>]'
|
||||
version OpenNebulaHelper::ONE_VERSION
|
||||
|
||||
helper = OneProviderHelper.new
|
||||
|
||||
before_proc do
|
||||
helper.set_client(options)
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Global options
|
||||
########################################################################
|
||||
|
||||
cmd_options = CommandParser::OPTIONS - [CommandParser::VERBOSE]
|
||||
set :option, cmd_options + OpenNebulaHelper::CLIENT_OPTIONS
|
||||
|
||||
########################################################################
|
||||
# Formatters for arguments
|
||||
########################################################################
|
||||
|
||||
set :format, :providerid, OneProviderHelper.to_id_desc do |arg|
|
||||
helper.to_id(arg)
|
||||
end
|
||||
|
||||
set :format, :providerid_list, OneProviderHelper.list_to_id_desc do |arg|
|
||||
helper.list_to_id(arg)
|
||||
end
|
||||
|
||||
set :format, :groupid, OneGroupHelper.to_id_desc do |arg|
|
||||
h = OneGroupHelper.new
|
||||
h.set_client(options)
|
||||
h.to_id(arg)
|
||||
end
|
||||
|
||||
set :format, :userid, OpenNebulaHelper.rname_to_id_desc('USER') do |arg|
|
||||
OpenNebulaHelper.rname_to_id(arg, 'USER')
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Commands
|
||||
########################################################################
|
||||
|
||||
create_desc = <<-EOT.unindent
|
||||
Allocate a new provider. Configuration file must be written in YAML.
|
||||
|
||||
$ cat packet.yaml
|
||||
name: packet
|
||||
connection:
|
||||
packet_token: "Packet token"
|
||||
packet_project: "Packet project"
|
||||
facility: "Packet facility"
|
||||
|
||||
$ cat ec2.yaml
|
||||
name: "ec2",
|
||||
connection:
|
||||
ec2_access: "AWS access key"
|
||||
ec2_secret: "AWS secret key"
|
||||
region_name: "AWS region name""
|
||||
EOT
|
||||
|
||||
command :create, create_desc, :template do
|
||||
rc = helper.create(args[0])
|
||||
|
||||
if OpenNebula.is_error?(rc)
|
||||
STDERR.puts rc.message
|
||||
exit(-1)
|
||||
else
|
||||
puts "ID: #{rc}"
|
||||
0
|
||||
end
|
||||
end
|
||||
|
||||
###
|
||||
|
||||
delete_desc = <<-EOT.unindent
|
||||
Delete a provider
|
||||
EOT
|
||||
|
||||
command :delete, delete_desc, [:range, :providerid_list] do
|
||||
helper.perform_actions(args[0], options, 'deleted') do |provider|
|
||||
provider.delete
|
||||
end
|
||||
end
|
||||
|
||||
###
|
||||
|
||||
list_desc = <<-EOT.unindent
|
||||
List all avaliable providers
|
||||
EOT
|
||||
|
||||
command :list,
|
||||
list_desc,
|
||||
:options => CLIHelper::OPTIONS + [OpenNebulaHelper::FORMAT] do
|
||||
options[:decrypt] = true
|
||||
helper.list_pool(options)
|
||||
end
|
||||
|
||||
###
|
||||
|
||||
show_desc = <<-EOT.unindent
|
||||
Show provider details
|
||||
EOT
|
||||
|
||||
command :show,
|
||||
show_desc,
|
||||
:providerid,
|
||||
:options => OpenNebulaHelper::FORMAT do
|
||||
helper.show_resource(args[0], options)
|
||||
end
|
||||
|
||||
###
|
||||
|
||||
update_desc = <<-EOT.unindent
|
||||
Update provider information
|
||||
EOT
|
||||
|
||||
command :update, update_desc, :providerid, [:file, nil] do
|
||||
helper.perform_action(args[0], options, 'updated') do |obj|
|
||||
helper.update(obj, args[1])
|
||||
end
|
||||
end
|
||||
|
||||
###
|
||||
|
||||
chgrp_desc = <<-EOT.unindent
|
||||
Changes the Provider group
|
||||
EOT
|
||||
|
||||
command :chgrp, chgrp_desc, [:range, :providerid_list], :groupid do
|
||||
helper.perform_actions(args[0], options, 'Group changed') do |p|
|
||||
p.chown(-1, args[1].to_i)
|
||||
end
|
||||
end
|
||||
|
||||
###
|
||||
|
||||
chown_desc = <<-EOT.unindent
|
||||
Changes the Provider owner and group
|
||||
EOT
|
||||
|
||||
command :chown,
|
||||
chown_desc,
|
||||
[:range, :providerid_list],
|
||||
:userid,
|
||||
[:groupid, nil] do
|
||||
args[2].nil? ? gid = -1 : gid = args[2].to_i
|
||||
|
||||
helper.perform_actions(args[0], options, 'Owner/Group changed') do |p|
|
||||
p.chown(args[1].to_i, gid)
|
||||
end
|
||||
end
|
||||
|
||||
###
|
||||
|
||||
chmod_desc = <<-EOT.unindent
|
||||
Changes the Provider permissions
|
||||
EOT
|
||||
|
||||
command :chmod, chmod_desc, [:range, :providerid_list], :octet do
|
||||
helper.perform_actions(args[0], options, 'Permissions changed') do |p|
|
||||
p.chmod_octet(args[1])
|
||||
end
|
||||
end
|
||||
end
|
@ -29,7 +29,7 @@ else
|
||||
RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby'
|
||||
GEMS_LOCATION = ONE_LOCATION + '/share/gems'
|
||||
REMOTES_LOCATION = ONE_LOCATION + '/var/remotes'
|
||||
ANSIBLE_LOCATION = ONE_LOCATION + '/usr/share/oneprovision/ansible'
|
||||
ANSIBLE_LOCATION = ONE_LOCATION + '/share/oneprovision/ansible'
|
||||
end
|
||||
|
||||
if File.directory?(GEMS_LOCATION)
|
||||
@ -43,16 +43,6 @@ $LOAD_PATH << RUBY_LIB_LOCATION + '/cli'
|
||||
$LOAD_PATH << LIB_LOCATION + '/oneprovision/lib'
|
||||
$LOAD_PATH << LIB_LOCATION + '/oneflow/lib'
|
||||
|
||||
PING_TIMEOUT_DEFAULT = 20
|
||||
PING_RETRIES_DEFAULT = 10
|
||||
MAX_RETRIES_DEFAULT = 3
|
||||
RUN_MODE_DEFAULT = :interactive
|
||||
FAIL_CHOICE_DEFAULT = :quit
|
||||
DEFAULT_FAIL_MODES = [:cleanup, :retry, :skip, :quit]
|
||||
CLEANUP_DEFAULT = false
|
||||
THREADS_DEFAULT = 3
|
||||
WAIT_TIMEOUT_DEFAULT = 60
|
||||
|
||||
require 'command_parser'
|
||||
|
||||
require 'one_helper'
|
||||
@ -79,211 +69,23 @@ CommandParser::CmdParser.new(ARGV) do
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Global Options
|
||||
# Global options
|
||||
########################################################################
|
||||
|
||||
############################ Output Modes ##############################
|
||||
|
||||
VERBOSE = {
|
||||
:name => 'verbose',
|
||||
:short => '-d',
|
||||
:large => '--verbose',
|
||||
:description => 'Set verbose logging mode'
|
||||
}
|
||||
|
||||
DEBUG = {
|
||||
:name => 'debug',
|
||||
:short => '-D',
|
||||
:large => '--debug',
|
||||
:description => 'Set debug logging mode',
|
||||
:format => String
|
||||
}
|
||||
|
||||
############################# Run Modes ################################
|
||||
|
||||
BATCH = {
|
||||
:name => 'batch',
|
||||
:short => '-b',
|
||||
:large => '--batch',
|
||||
:description => 'Run in non-interactive mode (no questions)',
|
||||
:format => String
|
||||
}
|
||||
|
||||
FAIL_MODES = {
|
||||
:name => 'fail_modes',
|
||||
:large => '--fail-modes mode1,mode2',
|
||||
:description => 'Fail modes to apply in order',
|
||||
:format => Array,
|
||||
:proc => lambda do |_, options|
|
||||
options = options[:fail_modes].map do |v|
|
||||
v = v.downcase.to_sym
|
||||
|
||||
unless DEFAULT_FAIL_MODES.include?(v)
|
||||
STDERR.puts "Wrong fail mode `#{v}`"
|
||||
exit(-1)
|
||||
end
|
||||
|
||||
v
|
||||
end
|
||||
|
||||
[0, options]
|
||||
end
|
||||
}
|
||||
|
||||
FAIL_RETRY = {
|
||||
:name => 'fail_retry',
|
||||
:large => '--fail-retry number',
|
||||
:description => 'Set batch failover mode to number of retries',
|
||||
:format => Integer
|
||||
}
|
||||
|
||||
FAIL_CLEANUP = {
|
||||
:name => 'fail_cleanup',
|
||||
:large => '--fail-cleanup',
|
||||
:description => 'Set batch failover mode to clean up and quit'
|
||||
}
|
||||
|
||||
FAIL_SKIP = {
|
||||
:name => 'fail_skip',
|
||||
:large => '--fail-skip',
|
||||
:description => 'Set batch failover mode to skip failing part'
|
||||
}
|
||||
|
||||
FAIL_QUIT = {
|
||||
:name => 'fail_quit',
|
||||
:large => '--fail-quit',
|
||||
:description => 'Set batch failover mode to quit (default)'
|
||||
}
|
||||
|
||||
FAIL_SLEEP = {
|
||||
:name => 'fail_sleep',
|
||||
:large => '--fail-sleep seconds',
|
||||
:description => 'Time in seconds between each fail mode is executed ' \
|
||||
'and between each retry',
|
||||
:format => Integer
|
||||
}
|
||||
|
||||
############################## Create ##################################
|
||||
|
||||
PING_TIMEOUT = {
|
||||
:name => 'ping_timeout',
|
||||
:large => '--ping-timeout seconds',
|
||||
:description => 'Set timeout for ping ' \
|
||||
"(default: #{PING_TIMEOUT_DEFAULT} secs)",
|
||||
:format => Integer
|
||||
}
|
||||
|
||||
PING_RETRIES = {
|
||||
:name => 'ping_retries',
|
||||
:large => '--ping-retries number',
|
||||
:description => 'Set retries for ping ' \
|
||||
"(default: #{PING_RETRIES_DEFAULT})",
|
||||
:format => Integer
|
||||
}
|
||||
|
||||
SKIP_PROVISION = {
|
||||
:name => 'skip_provision',
|
||||
:large => '--skip-provision',
|
||||
:description => 'Skip provision and configuration hosts phases'
|
||||
}
|
||||
|
||||
SKIP_CONFIG = {
|
||||
:name => 'skip_config',
|
||||
:large => '--skip-config',
|
||||
:description => 'Skip configuration hosts phase'
|
||||
}
|
||||
|
||||
WAIT_READY = {
|
||||
:name => 'wait_ready',
|
||||
:large => '--wait-ready',
|
||||
:description => 'Wait resources to be ready in OpenNebula'
|
||||
}
|
||||
|
||||
WAIT_TIMEOUT = {
|
||||
:name => 'wait_timeout',
|
||||
:large => '--wait-timeout timeout',
|
||||
:description => 'Timeout to wait objects to be ready',
|
||||
:format => Integer
|
||||
}
|
||||
cmd_options = CommandParser::OPTIONS - [CommandParser::VERBOSE]
|
||||
set :option, cmd_options + OpenNebulaHelper::CLIENT_OPTIONS
|
||||
|
||||
########################################################################
|
||||
|
||||
THREADS = {
|
||||
:name => 'threads',
|
||||
:short => '-t threads',
|
||||
:large => '--threads threads',
|
||||
:description => "Set threads for create (default: #{THREADS_DEFAULT})",
|
||||
:format => Integer
|
||||
}
|
||||
|
||||
FORCE = {
|
||||
:name => 'force',
|
||||
:short => '-F',
|
||||
:large => '--force',
|
||||
:description => 'Force configure to execute',
|
||||
:format => String
|
||||
}
|
||||
|
||||
HARD = {
|
||||
:name => 'hard',
|
||||
:short => '-H',
|
||||
:large => '--hard',
|
||||
:description => 'Reset the host',
|
||||
:format => String
|
||||
}
|
||||
|
||||
CLEANUP = {
|
||||
:name => 'cleanup',
|
||||
:large => '--cleanup',
|
||||
:description => 'Delete all vms and images first, ' \
|
||||
'then delete the resources.'
|
||||
}
|
||||
|
||||
CLEANUP_TIMEOUT = {
|
||||
:name => 'cleanup_timeout',
|
||||
:large => '--cleanup-timeout timeout',
|
||||
:description => 'Change the default timeout when deleting VMs/Images.'
|
||||
}
|
||||
|
||||
DUMP = {
|
||||
:name => 'dump',
|
||||
:large => '--dump',
|
||||
:description => 'Dump the configuration file result.'
|
||||
}
|
||||
|
||||
DONE = {
|
||||
:name => 'done',
|
||||
:large => '--done',
|
||||
:description => 'List provisions in DONE state'
|
||||
}
|
||||
|
||||
# Formatters for arguments
|
||||
########################################################################
|
||||
|
||||
MODES = CommandParser::OPTIONS - [CommandParser::VERBOSE] +
|
||||
[VERBOSE,
|
||||
DEBUG,
|
||||
BATCH,
|
||||
FAIL_RETRY,
|
||||
FAIL_CLEANUP,
|
||||
FAIL_SKIP,
|
||||
FAIL_QUIT,
|
||||
FAIL_MODES,
|
||||
FAIL_SLEEP]
|
||||
set :format, :provisionid, OneProvisionHelper.to_id_desc do |arg|
|
||||
helper.to_id(arg)
|
||||
end
|
||||
|
||||
CREATE_OPTIONS = [THREADS,
|
||||
MODES,
|
||||
PING_TIMEOUT,
|
||||
PING_RETRIES,
|
||||
CLEANUP,
|
||||
CLEANUP_TIMEOUT,
|
||||
SKIP_PROVISION,
|
||||
SKIP_CONFIG,
|
||||
WAIT_READY,
|
||||
WAIT_TIMEOUT]
|
||||
|
||||
ONE_OPTIONS = CommandParser::OPTIONS +
|
||||
CLIHelper::OPTIONS +
|
||||
OpenNebulaHelper::OPTIONS
|
||||
set :format, :provisionid_list, OneProvisionHelper.list_to_id_desc do |arg|
|
||||
helper.list_to_id(arg)
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Provision Commands
|
||||
@ -293,7 +95,10 @@ CommandParser::CmdParser.new(ARGV) do
|
||||
Provision a new cluster via bare metal provider
|
||||
EOT
|
||||
|
||||
command :create, create_desc, :config, :options => CREATE_OPTIONS do
|
||||
command :create,
|
||||
create_desc,
|
||||
:config,
|
||||
:options => OneProvisionHelper::CREATE_OPTIONS do
|
||||
helper.parse_options(options)
|
||||
|
||||
if options[:cleanup_timeout].nil?
|
||||
@ -311,7 +116,11 @@ CommandParser::CmdParser.new(ARGV) do
|
||||
skip = :none
|
||||
end
|
||||
|
||||
rc = helper.create(args[0], (options.key? :cleanup), timeout, skip)
|
||||
rc = helper.create(args[0],
|
||||
(options.key? :cleanup),
|
||||
timeout,
|
||||
skip,
|
||||
options[:provider])
|
||||
|
||||
if OpenNebula.is_error?(rc)
|
||||
STDERR.puts rc.message
|
||||
@ -328,7 +137,10 @@ CommandParser::CmdParser.new(ARGV) do
|
||||
Validate configuration file
|
||||
EOT
|
||||
|
||||
command :validate, validate_desc, [:config_file], :options => DUMP do
|
||||
command :validate,
|
||||
validate_desc,
|
||||
[:config_file],
|
||||
:options => OneProvisionHelper::DUMP do
|
||||
dump = options.key? :dump
|
||||
|
||||
OneProvision::Utils.validate_configuration(args[0], dump)
|
||||
@ -342,9 +154,8 @@ CommandParser::CmdParser.new(ARGV) do
|
||||
|
||||
command :list,
|
||||
provision_list_desc,
|
||||
:options => CommandParser::OPTIONS +
|
||||
CLIHelper::OPTIONS +
|
||||
[OpenNebulaHelper::FORMAT, DONE] do
|
||||
:options => CLIHelper::OPTIONS +
|
||||
[OpenNebulaHelper::FORMAT, OneProvisionHelper::DONE] do
|
||||
if !(options.key? :filter) && !(options.key? :done)
|
||||
options[:filter] = ['STAT!=DONE']
|
||||
end
|
||||
@ -361,7 +172,7 @@ CommandParser::CmdParser.new(ARGV) do
|
||||
command :show,
|
||||
provision_show_desc,
|
||||
:provisionid,
|
||||
:options => CommandParser::OPTIONS + OpenNebulaHelper::FORMAT do
|
||||
:options => OpenNebulaHelper::FORMAT do
|
||||
helper.show_resource(args[0], options)
|
||||
end
|
||||
|
||||
@ -374,7 +185,8 @@ CommandParser::CmdParser.new(ARGV) do
|
||||
command :configure,
|
||||
provision_configure_desc,
|
||||
:provisionid,
|
||||
:options => [MODES, FORCE] do
|
||||
:options => [OneProvisionHelper::MODES,
|
||||
OneProvisionHelper::FORCE] do
|
||||
helper.parse_options(options)
|
||||
|
||||
rc = helper.configure(args[0], options.key?(:force))
|
||||
@ -396,7 +208,10 @@ CommandParser::CmdParser.new(ARGV) do
|
||||
command :delete,
|
||||
provision_delete_desc,
|
||||
:provisionid,
|
||||
:options => [MODES, THREADS, CLEANUP, CLEANUP_TIMEOUT] do
|
||||
:options => [OneProvisionHelper::MODES,
|
||||
OneProvisionHelper::THREADS,
|
||||
OneProvisionHelper::CLEANUP,
|
||||
OneProvisionHelper::CLEANUP_TIMEOUT] do
|
||||
helper.parse_options(options)
|
||||
|
||||
if options[:cleanup_timeout].nil?
|
||||
@ -426,7 +241,7 @@ CommandParser::CmdParser.new(ARGV) do
|
||||
command [:host, :resume],
|
||||
host_resume_desc,
|
||||
[:range, :hostid_list],
|
||||
:options => [MODES] do
|
||||
:options => [OneProvisionHelper::MODES] do
|
||||
operation = { :operation => 'resume', :message => 'enabled' }
|
||||
|
||||
rc = helper.resources_operation(args, operation, options, 'HOSTS')
|
||||
@ -446,7 +261,7 @@ CommandParser::CmdParser.new(ARGV) do
|
||||
command [:host, :poweroff],
|
||||
host_poweroff_desc,
|
||||
[:range, :hostid_list],
|
||||
:options => [MODES] do
|
||||
:options => [OneProvisionHelper::MODES] do
|
||||
operation = { :operation => 'poweroff', :message => 'disabled' }
|
||||
|
||||
rc = helper.resources_operation(args, operation, options, 'HOSTS')
|
||||
@ -466,7 +281,7 @@ CommandParser::CmdParser.new(ARGV) do
|
||||
command [:host, :reboot],
|
||||
host_reboot_desc,
|
||||
[:range, :hostid_list],
|
||||
:options => [MODES, HARD] do
|
||||
:options => [OneProvisionHelper::MODES, OneProvisionHelper::HARD] do
|
||||
operation = { :operation => 'reboot', :message => 'enabled' }
|
||||
|
||||
rc = helper.resources_operation(args, operation, options, 'HOSTS')
|
||||
@ -486,7 +301,7 @@ CommandParser::CmdParser.new(ARGV) do
|
||||
command [:host, :delete],
|
||||
host_delete_desc,
|
||||
[:range, :hostid_list],
|
||||
:options => [MODES] do
|
||||
:options => [OneProvisionHelper::MODES] do
|
||||
operation = { :operation => 'delete', :message => 'deleted' }
|
||||
|
||||
rc = helper.resources_operation(args, operation, options, 'HOSTS')
|
||||
@ -506,8 +321,9 @@ CommandParser::CmdParser.new(ARGV) do
|
||||
command [:host, :configure],
|
||||
host_configure_desc,
|
||||
[:range, :hostid_list],
|
||||
:options => [MODES, FORCE] do
|
||||
operation = { :operation => 'configure', :message => 'enabled' }
|
||||
:options => [OneProvisionHelper::MODES,
|
||||
OneProvisionHelper::FORCE] do
|
||||
operation = { :operation => 'configure', :message => 'enabled' }
|
||||
|
||||
rc = helper.resources_operation(args, operation, options, 'HOSTS')
|
||||
|
||||
@ -545,7 +361,8 @@ CommandParser::CmdParser.new(ARGV) do
|
||||
|
||||
command [:host, :list],
|
||||
host_list_desc,
|
||||
:options => ONE_OPTIONS + [OpenNebulaHelper::DESCRIBE] do
|
||||
:options => OneProvisionHelper::ONE_OPTIONS +
|
||||
[OpenNebulaHelper::DESCRIBE] do
|
||||
helper.list_objects('HOSTS', options)
|
||||
end
|
||||
|
||||
@ -557,7 +374,7 @@ CommandParser::CmdParser.new(ARGV) do
|
||||
|
||||
command [:host, :top],
|
||||
host_top_desc,
|
||||
:options => ONE_OPTIONS do
|
||||
:options => OneProvisionHelper::ONE_OPTIONS do
|
||||
helper.list_objects('HOSTS', options, true)
|
||||
end
|
||||
|
||||
@ -574,7 +391,8 @@ CommandParser::CmdParser.new(ARGV) do
|
||||
|
||||
command [resource.chomp('s').to_sym, :list],
|
||||
list_desc,
|
||||
:options => ONE_OPTIONS + [OpenNebulaHelper::DESCRIBE] do
|
||||
:options => OneProvisionHelper::ONE_OPTIONS +
|
||||
[OpenNebulaHelper::DESCRIBE] do
|
||||
helper.list_objects(resource.upcase, options)
|
||||
end
|
||||
end
|
||||
@ -591,7 +409,8 @@ CommandParser::CmdParser.new(ARGV) do
|
||||
command [resource.chomp('s').to_sym, :delete],
|
||||
delete_desc,
|
||||
[:range, :id_list],
|
||||
:options => [MODES, FORCE] do
|
||||
:options => [OneProvisionHelper::MODES,
|
||||
OneProvisionHelper::FORCE] do
|
||||
rc = helper.resources_operation(args,
|
||||
{},
|
||||
options,
|
||||
|
253
src/cli/oneprovision-template
Executable file
253
src/cli/oneprovision-template
Executable file
@ -0,0 +1,253 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2020, OpenNebula Project, OpenNebula Systems #
|
||||
# #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
ONE_LOCATION = ENV['ONE_LOCATION']
|
||||
|
||||
if !ONE_LOCATION
|
||||
LIB_LOCATION = '/usr/lib/one'
|
||||
RUBY_LIB_LOCATION = '/usr/lib/one/ruby'
|
||||
GEMS_LOCATION = '/usr/share/one/gems'
|
||||
REMOTES_LOCATION = '/var/lib/one/remotes'
|
||||
ANSIBLE_LOCATION = '/usr/share/one/oneprovision/ansible'
|
||||
else
|
||||
LIB_LOCATION = ONE_LOCATION + '/lib'
|
||||
RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby'
|
||||
GEMS_LOCATION = ONE_LOCATION + '/share/gems'
|
||||
REMOTES_LOCATION = ONE_LOCATION + '/var/remotes'
|
||||
ANSIBLE_LOCATION = ONE_LOCATION + '/share/oneprovision/ansible'
|
||||
end
|
||||
|
||||
if File.directory?(GEMS_LOCATION)
|
||||
$LOAD_PATH.reject! {|l| l =~ /vendor_ruby/ }
|
||||
require 'rubygems'
|
||||
Gem.use_paths(File.realpath(GEMS_LOCATION))
|
||||
end
|
||||
|
||||
$LOAD_PATH << RUBY_LIB_LOCATION
|
||||
$LOAD_PATH << RUBY_LIB_LOCATION + '/cli'
|
||||
$LOAD_PATH << LIB_LOCATION + '/oneprovision/lib'
|
||||
$LOAD_PATH << LIB_LOCATION + '/oneflow/lib'
|
||||
|
||||
require 'command_parser'
|
||||
|
||||
require 'one_helper'
|
||||
require 'one_helper/onegroup_helper'
|
||||
require 'one_helper/oneprovision_helper'
|
||||
require 'one_helper/oneprovision_template_helper'
|
||||
|
||||
require 'oneprovision'
|
||||
|
||||
CommandParser::CmdParser.new(ARGV) do
|
||||
usage '`oneprovision-template` <command> [<file>] [<args>] [<options>]'
|
||||
version OpenNebulaHelper::ONE_VERSION
|
||||
|
||||
helper = OneProvisionTemplateHelper.new
|
||||
|
||||
before_proc do
|
||||
helper.set_client(options)
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Global options
|
||||
########################################################################
|
||||
|
||||
cmd_options = CommandParser::OPTIONS - [CommandParser::VERBOSE]
|
||||
set :option, cmd_options + OpenNebulaHelper::CLIENT_OPTIONS
|
||||
|
||||
########################################################################
|
||||
# Formatters for arguments
|
||||
########################################################################
|
||||
|
||||
set :format, :templateid, OneProvisionTemplateHelper.to_id_desc do |arg|
|
||||
helper.to_id(arg)
|
||||
end
|
||||
|
||||
set :format,
|
||||
:templateid_list,
|
||||
OneProvisionTemplateHelper.list_to_id_desc do |arg|
|
||||
helper.list_to_id(arg)
|
||||
end
|
||||
|
||||
set :format, :groupid, OneGroupHelper.to_id_desc do |arg|
|
||||
h = OneGroupHelper.new
|
||||
h.set_client(options)
|
||||
h.to_id(arg)
|
||||
end
|
||||
|
||||
set :format, :userid, OpenNebulaHelper.rname_to_id_desc('USER') do |arg|
|
||||
OpenNebulaHelper.rname_to_id(arg, 'USER')
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Commands
|
||||
########################################################################
|
||||
|
||||
create_desc = <<-EOT.unindent
|
||||
Allocate a new template. File must be written in YAML.
|
||||
EOT
|
||||
|
||||
command :create, create_desc, :template do
|
||||
rc = helper.create(args[0])
|
||||
|
||||
if OpenNebula.is_error?(rc)
|
||||
STDERR.puts rc.message
|
||||
exit(-1)
|
||||
else
|
||||
puts "ID: #{rc}"
|
||||
0
|
||||
end
|
||||
end
|
||||
|
||||
###
|
||||
|
||||
delete_desc = <<-EOT.unindent
|
||||
Delete a template
|
||||
EOT
|
||||
|
||||
command :delete, delete_desc, [:range, :templateid_list] do
|
||||
helper.perform_actions(args[0], options, 'deleted') do |template|
|
||||
template.delete
|
||||
end
|
||||
end
|
||||
|
||||
###
|
||||
|
||||
list_desc = <<-EOT.unindent
|
||||
List all avaliable templates
|
||||
EOT
|
||||
|
||||
command :list,
|
||||
list_desc,
|
||||
:options => CLIHelper::OPTIONS + [OpenNebulaHelper::FORMAT] do
|
||||
options[:decrypt] = true
|
||||
helper.list_pool(options)
|
||||
end
|
||||
|
||||
###
|
||||
|
||||
show_desc = <<-EOT.unindent
|
||||
Show template details
|
||||
EOT
|
||||
|
||||
command :show,
|
||||
show_desc,
|
||||
:templateid,
|
||||
:options => OpenNebulaHelper::FORMAT do
|
||||
helper.show_resource(args[0], options)
|
||||
end
|
||||
|
||||
###
|
||||
|
||||
update_desc = <<-EOT.unindent
|
||||
Update template information
|
||||
EOT
|
||||
|
||||
command :update, update_desc, :templateid, [:file, nil] do
|
||||
helper.perform_action(args[0], options, 'updated') do |obj|
|
||||
helper.update(obj, args[1])
|
||||
end
|
||||
end
|
||||
|
||||
###
|
||||
|
||||
instantiate_desc = <<-EOT.unindent
|
||||
Instantiate the template
|
||||
EOT
|
||||
|
||||
command :instantiate,
|
||||
instantiate_desc,
|
||||
:templateid,
|
||||
[:extra_file, nil],
|
||||
:options => OneProvisionHelper::CREATE_OPTIONS do
|
||||
helper.perform_action(args[0], options, 'instantiated') do |obj|
|
||||
h = OneProvisionHelper.new
|
||||
h.parse_options(options)
|
||||
|
||||
if options[:cleanup_timeout].nil?
|
||||
timeout = 20
|
||||
else
|
||||
timeout = options[:cleanup_timeout]
|
||||
end
|
||||
|
||||
# Get skip mode
|
||||
if options.key? :skip_provision
|
||||
skip = :all
|
||||
elsif options.key? :skip_config
|
||||
skip = :config
|
||||
else
|
||||
skip = :none
|
||||
end
|
||||
|
||||
rc = obj.instantiate((options.key? :cleanup),
|
||||
timeout,
|
||||
skip,
|
||||
options[:provider],
|
||||
args[1])
|
||||
|
||||
if OpenNebula.is_error?(rc)
|
||||
STDERR.puts rc.message
|
||||
exit(-1)
|
||||
else
|
||||
puts "ID: #{rc}"
|
||||
0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
###
|
||||
|
||||
chgrp_desc = <<-EOT.unindent
|
||||
Changes the Provision Template group
|
||||
EOT
|
||||
|
||||
command :chgrp, chgrp_desc, [:range, :templateid_list], :groupid do
|
||||
helper.perform_actions(args[0], options, 'Group changed') do |p|
|
||||
p.chown(-1, args[1].to_i)
|
||||
end
|
||||
end
|
||||
|
||||
###
|
||||
|
||||
chown_desc = <<-EOT.unindent
|
||||
Changes the Provision Template owner and group
|
||||
EOT
|
||||
|
||||
command :chown,
|
||||
chown_desc,
|
||||
[:range, :templateid_list],
|
||||
:userid,
|
||||
[:groupid, nil] do
|
||||
args[2].nil? ? gid = -1 : gid = args[2].to_i
|
||||
|
||||
helper.perform_actions(args[0], options, 'Owner/Group changed') do |p|
|
||||
p.chown(args[1].to_i, gid)
|
||||
end
|
||||
end
|
||||
|
||||
###
|
||||
|
||||
chmod_desc = <<-EOT.unindent
|
||||
Changes the Provision Template permissions
|
||||
EOT
|
||||
|
||||
command :chmod, chmod_desc, [:range, :templateid_list], :octet do
|
||||
helper.perform_actions(args[0], options, 'Permissions changed') do |p|
|
||||
p.chmod_octet(args[1])
|
||||
end
|
||||
end
|
||||
end
|
@ -36,11 +36,11 @@ Document::Document( int id,
|
||||
{
|
||||
if (_template_contents)
|
||||
{
|
||||
obj_template = move(_template_contents);
|
||||
obj_template = make_unique<DocumentTemplate>(*_template_contents);
|
||||
}
|
||||
else
|
||||
{
|
||||
obj_template = make_unique<Template>();
|
||||
obj_template = make_unique<DocumentTemplate>();
|
||||
}
|
||||
|
||||
set_umask(_umask);
|
||||
@ -72,6 +72,9 @@ int Document::insert(SqlDB *db, string& error_str)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Encrypt all the secrets
|
||||
encrypt();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Insert the Document
|
||||
// ------------------------------------------------------------------------
|
||||
|
22
src/document/DocumentTemplate.cc
Normal file
22
src/document/DocumentTemplate.cc
Normal file
@ -0,0 +1,22 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2020, OpenNebula Project, OpenNebula Systems */
|
||||
/* */
|
||||
/* 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. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#include "DocumentTemplate.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
std::map<std::string, std::set<std::string> > DocumentTemplate::encrypted;
|
@ -22,7 +22,8 @@ lib_name='nebula_document'
|
||||
|
||||
# Sources to generate the library
|
||||
source_files=[
|
||||
'Document.cc'
|
||||
'Document.cc',
|
||||
'DocumentTemplate.cc'
|
||||
]
|
||||
|
||||
# Build library
|
||||
|
@ -765,7 +765,11 @@ void Nebula::start(bool bootstrap_only)
|
||||
dspool = new DatastorePool(logdb, inherit_ds_attrs, ds_encrypted_attrs);
|
||||
|
||||
/* ----- Document, Zone, VDC, VMTemplate, SG and Makerket Pools ----- */
|
||||
docpool = new DocumentPool(logdb);
|
||||
vector<const SingleAttribute *> doc_encrypted_attrs;
|
||||
|
||||
nebula_configuration->get("DOCUMENT_ENCRYPTED_ATTR", doc_encrypted_attrs);
|
||||
|
||||
docpool = new DocumentPool(logdb, doc_encrypted_attrs);
|
||||
zonepool = new ZonePool(db_ptr, is_federation_slave());
|
||||
vdcpool = new VdcPool(db_ptr, is_federation_slave());
|
||||
|
||||
|
@ -86,8 +86,8 @@ module OpenNebula
|
||||
#
|
||||
# @return [nil, OpenNebula::Error] nil in case of success, Error
|
||||
# otherwise
|
||||
def info()
|
||||
rc = super(DOCUMENT_METHODS[:info], 'DOCUMENT')
|
||||
def info(decrypt = false)
|
||||
rc = super(DOCUMENT_METHODS[:info], 'DOCUMENT', decrypt)
|
||||
|
||||
if !OpenNebula.is_error?(rc) && self['TYPE'].to_i != document_type
|
||||
return OpenNebula::Error.new("[DocumentInfo] Error getting document [#{@pe_id}].")
|
||||
|
@ -21,6 +21,15 @@ module OpenNebula
|
||||
|
||||
TEMPLATE_TAG = "BODY"
|
||||
|
||||
# Returns current template tag
|
||||
def template_tag
|
||||
if @tag
|
||||
@tag
|
||||
else
|
||||
TEMPLATE_TAG
|
||||
end
|
||||
end
|
||||
|
||||
# Allocate a new Document containing the json inside the TEMPLATE
|
||||
#
|
||||
# @param [String] template_json json to be inserted in the TEMPLATE
|
||||
@ -30,7 +39,9 @@ module OpenNebula
|
||||
# @return [nil, OpenNebula::Error] nil in case of success, Error
|
||||
# otherwise
|
||||
#
|
||||
def allocate(template_json, name=nil)
|
||||
def allocate(template_json, name = nil, tag = nil)
|
||||
@tag = tag if tag
|
||||
|
||||
text = build_template_xml(template_json, name)
|
||||
|
||||
super(text)
|
||||
@ -41,8 +52,8 @@ module OpenNebula
|
||||
# @return [nil, OpenNebula::Error] nil in case of success, Error
|
||||
# otherwise
|
||||
#
|
||||
def info
|
||||
rc = super
|
||||
def info(decrypt = false)
|
||||
rc = super(decrypt)
|
||||
if OpenNebula.is_error?(rc)
|
||||
return rc
|
||||
end
|
||||
@ -90,10 +101,10 @@ module OpenNebula
|
||||
def to_json(pretty_generate=true)
|
||||
hash = self.to_hash
|
||||
|
||||
body = hash['DOCUMENT']['TEMPLATE']["#{TEMPLATE_TAG}"]
|
||||
body = hash['DOCUMENT']['TEMPLATE']["#{template_tag}"]
|
||||
if body
|
||||
body_hash = JSON.parse(body)
|
||||
hash['DOCUMENT']['TEMPLATE']["#{TEMPLATE_TAG}"] = body_hash
|
||||
hash['DOCUMENT']['TEMPLATE']["#{template_tag}"] = body_hash
|
||||
end
|
||||
|
||||
if pretty_generate
|
||||
@ -106,7 +117,7 @@ module OpenNebula
|
||||
|
||||
# Fill the @body hash with the values of the template
|
||||
def load_body
|
||||
body_str = self["TEMPLATE/#{TEMPLATE_TAG}"]
|
||||
body_str = self["TEMPLATE/#{template_tag}"]
|
||||
|
||||
if body_str
|
||||
begin
|
||||
@ -134,9 +145,9 @@ module OpenNebula
|
||||
|
||||
text << "<NAME>#{name}</NAME>" if name
|
||||
|
||||
text << "<#{TEMPLATE_TAG}>"
|
||||
text << "<#{template_tag}>"
|
||||
text << "<![CDATA[#{template_json}]]>"
|
||||
text << "</#{TEMPLATE_TAG}>"
|
||||
text << "</#{template_tag}>"
|
||||
|
||||
text << "</TEMPLATE>"
|
||||
|
||||
|
61
src/oneprovision/etc/packet_driver.conf
Normal file
61
src/oneprovision/etc/packet_driver.conf
Normal file
@ -0,0 +1,61 @@
|
||||
:plans:
|
||||
Type 2A5:
|
||||
cpu: 1
|
||||
memory: 96.0
|
||||
c2.large.arm:
|
||||
cpu: 1
|
||||
memory: 128.0
|
||||
c2.medium.x86:
|
||||
cpu: 1
|
||||
memory: 64.0
|
||||
c3.medium.x86:
|
||||
cpu: 1
|
||||
memory: 64.0
|
||||
c3.small.x86:
|
||||
cpu: 1
|
||||
memory: 32.0
|
||||
g2.large.x86:
|
||||
cpu: 2
|
||||
memory: 192.0
|
||||
m2.xlarge.x86:
|
||||
cpu: 2
|
||||
memory: 384.0
|
||||
m3.large.x86:
|
||||
cpu: 1
|
||||
memory: 256.0
|
||||
n2.xlarge.x86:
|
||||
cpu: 2
|
||||
memory: 384.0
|
||||
s3.xlarge.x86:
|
||||
cpu: 2
|
||||
memory: 192.0
|
||||
x2.xlarge.x86:
|
||||
cpu: 2
|
||||
memory: 384.0
|
||||
x.large.arm:
|
||||
cpu: 2
|
||||
memory: 256.0
|
||||
c1.large.arm:
|
||||
cpu: 2
|
||||
memory: 128.0
|
||||
c1.large.arm.xda:
|
||||
cpu: 2
|
||||
memory: 128.0
|
||||
c1.small.x86:
|
||||
cpu: 1
|
||||
memory: 32.0
|
||||
c1.xlarge.x86:
|
||||
cpu: 2
|
||||
memory: 128.0
|
||||
m1.xlarge.x86:
|
||||
cpu: 2
|
||||
memory: 256.0
|
||||
s1.large.x86:
|
||||
cpu: 1
|
||||
memory: 64.0
|
||||
t1.small.x86:
|
||||
cpu: 1
|
||||
memory: 8.0
|
||||
x1.small.x86:
|
||||
cpu: 1
|
||||
memory: 32.0
|
52
src/oneprovision/etc/packet_plans.rb
Executable file
52
src/oneprovision/etc/packet_plans.rb
Executable file
@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require 'json'
|
||||
require 'net/http'
|
||||
|
||||
unless ARGV[0]
|
||||
STDERR.puts 'No API token provied'
|
||||
STDERR.puts '`packet_plans.rb` <API_TOKEN>'
|
||||
exit(-1)
|
||||
end
|
||||
|
||||
uri = URI('https://api.packet.net/plans')
|
||||
req = Net::HTTP::Get.new(uri)
|
||||
|
||||
req['Accept'] = 'application/json'
|
||||
req['X-Auth-Token'] = ARGV[0]
|
||||
|
||||
res = Net::HTTP.new(uri.hostname, uri.port)
|
||||
res.use_ssl = true
|
||||
|
||||
response = res.request(req)
|
||||
|
||||
unless response.is_a? Net::HTTPOK
|
||||
STDERR.puts 'Error getting plans from Packet'
|
||||
exit(-1)
|
||||
end
|
||||
|
||||
plans = JSON.parse(response.body)['plans']
|
||||
file = ":plans:\n"
|
||||
|
||||
plans.each do |plan|
|
||||
specs = plan['specs']
|
||||
|
||||
specs['cpus'].nil? ? cpu = 0 : cpu = specs['cpus'][0]['count']
|
||||
specs['memory'].nil? ? mem = 0 : mem = specs['memory']['total']
|
||||
|
||||
next if cpu == 0 || mem == 0
|
||||
|
||||
file << " #{plan['name']}:\n"
|
||||
file << " cpu: #{cpu}\n"
|
||||
file << " memory: #{mem[/\d+/]}.0\n"
|
||||
end
|
||||
|
||||
puts file
|
||||
puts
|
||||
|
||||
print 'Do you want to overwrite file packet_driver.conf? '
|
||||
over = STDIN.readline.chop.downcase
|
||||
|
||||
exit if over != 'yes'
|
||||
|
||||
File.open('packet_driver.conf', 'w') {|f| f.write(file) }
|
@ -14,298 +14,24 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'ansible'
|
||||
require 'driver'
|
||||
require 'provision'
|
||||
require 'provision_pool'
|
||||
require 'resources'
|
||||
require 'utils'
|
||||
|
||||
require 'logger'
|
||||
require 'singleton'
|
||||
require 'provision_element'
|
||||
require 'provision/oneprovision'
|
||||
require 'provision_template/provision_template'
|
||||
require 'provision_template/provision_template_pool'
|
||||
require 'provider/provider'
|
||||
require 'provider/provider_pool'
|
||||
|
||||
# OneProvision module
|
||||
module OneProvision
|
||||
|
||||
# Singleton OneProvision Logger
|
||||
class OneProvisionLogger
|
||||
|
||||
include Singleton
|
||||
|
||||
attr_reader :logger
|
||||
|
||||
# Class constructor
|
||||
def initialize
|
||||
@logger = Logger.new(STDERR)
|
||||
end
|
||||
|
||||
# Gets the logger
|
||||
#
|
||||
# @param options [Key-Value Object] CLI options
|
||||
def self.get_logger(options)
|
||||
format = '%Y-%m-%d %H:%M:%S'
|
||||
|
||||
instance.logger.formatter = proc do |severity, datetime, _p, msg|
|
||||
"#{datetime.strftime(format)} #{severity.ljust(5)} : #{msg}\n"
|
||||
end
|
||||
|
||||
if options.key? :debug
|
||||
instance.logger.level = Logger::DEBUG
|
||||
elsif options.key? :verbose
|
||||
instance.logger.level = Logger::INFO
|
||||
else
|
||||
instance.logger.level = Logger::UNKNOWN
|
||||
end
|
||||
end
|
||||
|
||||
# Shows a debug message
|
||||
#
|
||||
# @param msg [String] Message to show
|
||||
def self.debug(msg)
|
||||
instance.logger.debug(msg)
|
||||
end
|
||||
|
||||
# Shows an error message
|
||||
#
|
||||
# @param msg [String] Message to show
|
||||
def self.error(msg)
|
||||
instance.logger.error(msg)
|
||||
end
|
||||
|
||||
# Shows an info message
|
||||
#
|
||||
# @param msg [String] Message to show
|
||||
def self.info(msg)
|
||||
instance.logger.info(msg)
|
||||
end
|
||||
|
||||
# Shows a warning message
|
||||
#
|
||||
# @param msg [String] Message to show
|
||||
def self.warn(msg)
|
||||
instance.logger.warn(msg)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Singleton running mode
|
||||
class Mode
|
||||
|
||||
include Singleton
|
||||
|
||||
attr_reader :run_mode
|
||||
|
||||
# Class constructor
|
||||
def initialize
|
||||
@run_mode = {}
|
||||
end
|
||||
|
||||
# Gets running mode
|
||||
#
|
||||
# @param options [Key-Value Object] CLI options
|
||||
def self.get_run_mode(options)
|
||||
if options.key? :batch
|
||||
instance.run_mode[:mode] = :batch
|
||||
else
|
||||
instance.run_mode[:mode] = RUN_MODE_DEFAULT
|
||||
end
|
||||
|
||||
instance.run_mode[:fail_modes] = []
|
||||
|
||||
if options.key? :fail_modes
|
||||
instance.run_mode[:fail_modes] << options[:fail_modes]
|
||||
end
|
||||
|
||||
options.each do |key, _|
|
||||
next unless key =~ /^fail_/
|
||||
|
||||
next if key =~ /sleep/ || key =~ /modes/
|
||||
|
||||
instance.run_mode[:fail_modes] << key.to_s.split('_')[1].to_sym
|
||||
end
|
||||
|
||||
if instance.run_mode[:fail_modes].empty?
|
||||
instance.run_mode[:fail_modes] << FAIL_CHOICE_DEFAULT
|
||||
end
|
||||
|
||||
instance.run_mode[:fail_modes].flatten!
|
||||
|
||||
if options.key? :fail_sleep
|
||||
instance.run_mode[:fail_sleep] = options[:fail_sleep]
|
||||
end
|
||||
|
||||
if options[:fail_retry]
|
||||
instance.run_mode[:max_retries] = options[:fail_retry].to_i
|
||||
else
|
||||
instance.run_mode[:max_retries] = MAX_RETRIES_DEFAULT
|
||||
end
|
||||
|
||||
instance.run_mode[:cleanup] = CLEANUP_DEFAULT
|
||||
end
|
||||
|
||||
# Gets cleanup value
|
||||
#
|
||||
# @return [Boolean] Cleanup
|
||||
def self.cleanup
|
||||
instance.run_mode[:cleanup]
|
||||
end
|
||||
|
||||
# Gets fail choice value
|
||||
#
|
||||
# @return [Sym] Choice value
|
||||
def self.fail_choice
|
||||
instance.run_mode[:fail_modes][0]
|
||||
end
|
||||
|
||||
# Gets time between fail modes
|
||||
#
|
||||
# @return [Integer] Time in seconds
|
||||
def self.fail_sleep
|
||||
instance.run_mode[:fail_sleep]
|
||||
end
|
||||
|
||||
# Gets next fail choice value
|
||||
#
|
||||
# @return [Sym] Choice value
|
||||
def self.next_fail_choice
|
||||
instance.run_mode[:fail_modes].shift
|
||||
end
|
||||
|
||||
# Gets max retries value
|
||||
#
|
||||
# @return [Integer] Maximun retries
|
||||
def self.max_retries
|
||||
instance.run_mode[:max_retries]
|
||||
end
|
||||
|
||||
# Gets mode value
|
||||
#
|
||||
# @return [Sym] Mode value
|
||||
def self.mode
|
||||
instance.run_mode[:mode]
|
||||
end
|
||||
|
||||
# Sets cleanup value
|
||||
#
|
||||
# @param value [Boolean] New cleanup value
|
||||
def self.new_cleanup(value)
|
||||
instance.run_mode[:cleanup] = value
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Singleton options
|
||||
class Options
|
||||
|
||||
include Singleton
|
||||
|
||||
attr_reader :run_options
|
||||
|
||||
# Class constructor
|
||||
def initialize
|
||||
@run_options = {}
|
||||
end
|
||||
|
||||
# Gets options
|
||||
#
|
||||
# @param options [Key-Value Object] CLI Options
|
||||
def self.get_run_options(options)
|
||||
if options.key? :ping_timeout
|
||||
instance.run_options[:ping_timeout] = options[:ping_timeout]
|
||||
else
|
||||
instance.run_options[:ping_timeout] = PING_TIMEOUT_DEFAULT
|
||||
end
|
||||
|
||||
if options.key? :ping_retries
|
||||
instance.run_options[:ping_retries] = options[:ping_retries]
|
||||
else
|
||||
instance.run_options[:ping_retries] = PING_RETRIES_DEFAULT
|
||||
end
|
||||
|
||||
if options.key? :threads
|
||||
instance.run_options[:threads] = options[:threads]
|
||||
else
|
||||
instance.run_options[:threads] = THREADS_DEFAULT
|
||||
end
|
||||
end
|
||||
|
||||
# Gets ping retries value
|
||||
#
|
||||
# @return [Integer] Ping retries value
|
||||
def self.ping_retries
|
||||
instance.run_options[:ping_retries]
|
||||
end
|
||||
|
||||
# Gets ping timeout value
|
||||
#
|
||||
# @return [Integer] Ping timeout value
|
||||
def self.ping_timeout
|
||||
instance.run_options[:ping_timeout]
|
||||
end
|
||||
|
||||
# Gets number of threads
|
||||
#
|
||||
# @return [Integer] Number of threads
|
||||
def self.threads
|
||||
instance.run_options[:threads]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Singleton virtual objects options
|
||||
class ObjectOptions
|
||||
|
||||
include Singleton
|
||||
|
||||
attr_reader :obj_opts
|
||||
|
||||
# Class constructor
|
||||
def initialize
|
||||
@obj_opts = {}
|
||||
end
|
||||
|
||||
# Gets options
|
||||
#
|
||||
# @param options [Key-Value Object] CLI Options
|
||||
def self.get_obj_options(options)
|
||||
if options.key? :wait_ready
|
||||
instance.obj_opts[:wait_ready] = true
|
||||
else
|
||||
instance.obj_opts[:wait_ready] = false
|
||||
end
|
||||
|
||||
if options.key? :wait_timeout
|
||||
instance.obj_opts[:wait_timeout] = options[:wait_timeout]
|
||||
else
|
||||
instance.obj_opts[:wait_timeout] = WAIT_TIMEOUT_DEFAULT
|
||||
end
|
||||
end
|
||||
|
||||
# Get wait and timeout
|
||||
#
|
||||
# @param meta [Hash] Meta information from object
|
||||
#
|
||||
# @return [boolean, integer] [wait, timeout]
|
||||
def self.get_wait(meta)
|
||||
if meta
|
||||
wait = meta['wait']
|
||||
timeout = meta['wait_timeout']
|
||||
end
|
||||
|
||||
case wait
|
||||
when false
|
||||
[wait, nil]
|
||||
when true
|
||||
if timeout
|
||||
[wait, timeout]
|
||||
else
|
||||
[wait, instance.obj_opts[:wait_timeout]]
|
||||
end
|
||||
else
|
||||
[instance.obj_opts[:wait_ready],
|
||||
instance.obj_opts[:wait_timeout]]
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
PING_TIMEOUT_DEFAULT = 20
|
||||
PING_RETRIES_DEFAULT = 10
|
||||
MAX_RETRIES_DEFAULT = 3
|
||||
RUN_MODE_DEFAULT = :interactive
|
||||
FAIL_CHOICE_DEFAULT = :quit
|
||||
DEFAULT_FAIL_MODES = [:cleanup, :retry, :skip, :quit]
|
||||
CLEANUP_DEFAULT = false
|
||||
THREADS_DEFAULT = 3
|
||||
WAIT_TIMEOUT_DEFAULT = 60
|
||||
|
||||
end
|
||||
|
143
src/oneprovision/lib/provider/provider.rb
Normal file
143
src/oneprovision/lib/provider/provider.rb
Normal file
@ -0,0 +1,143 @@
|
||||
# #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'base64'
|
||||
|
||||
module OneProvision
|
||||
|
||||
# Provider class as wrapper of DocumentJSON
|
||||
class Provider < ProvisionElement
|
||||
|
||||
DOCUMENT_TYPE = 102
|
||||
|
||||
# These attributes can not be changed when updating the provider
|
||||
UNMUTABLE_ATTRS = %w[provider registration_time]
|
||||
|
||||
# Allocates a new document
|
||||
#
|
||||
# @param template [Hash] Document information
|
||||
def allocate(template)
|
||||
rc = Provider.by_name(@client, template['name'])
|
||||
|
||||
return rc if OpenNebula.is_error?(rc)
|
||||
|
||||
if rc
|
||||
return OpenNebula::Error.new("Provider #{template['name']} " \
|
||||
'already exists')
|
||||
end
|
||||
|
||||
rc = nil
|
||||
|
||||
begin
|
||||
rc = to_json(template)
|
||||
|
||||
return rc if OpenNebula.is_error?(rc)
|
||||
rescue StandardError => e
|
||||
return OpenNebula::Error.new(e)
|
||||
end
|
||||
|
||||
super(rc, template['name'], TEMPLATE_TAG)
|
||||
end
|
||||
|
||||
# Delete provider
|
||||
def delete
|
||||
info(true)
|
||||
|
||||
# Check if the provider is being used in any provision
|
||||
pool = ProvisionPool.new(@client)
|
||||
rc = pool.info_all
|
||||
|
||||
return rc if OpenNebula.is_error?(rc)
|
||||
|
||||
pool.each do |p|
|
||||
next unless p.body['provider'] == body['provider']
|
||||
|
||||
next if p.body['state'] == Provision::STATE['DONE']
|
||||
|
||||
return OpenNebula::Error.new(
|
||||
'Provider can not be deleted, it is used by ' \
|
||||
"provision with ID: #{p['ID']}"
|
||||
)
|
||||
end
|
||||
|
||||
pool = ProvisionTemplatePool.new(@client)
|
||||
rc = pool.info_all
|
||||
|
||||
return rc if OpenNebula.is_error?(rc)
|
||||
|
||||
pool.each do |p|
|
||||
next unless Integer(p.body['provider']) == Integer(self['ID'])
|
||||
|
||||
return OpenNebula::Error.new(
|
||||
'Provider can not be deleted, it is used by ' \
|
||||
"provision template with ID: #{p['ID']}"
|
||||
)
|
||||
end
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
# Gets connection information
|
||||
def connection
|
||||
conn = @body['connection']
|
||||
conn['provider'] = self['NAME']
|
||||
|
||||
conn
|
||||
end
|
||||
|
||||
# Gets provider object by name or ID
|
||||
#
|
||||
# @param client [Client] Client to make OpenNebula calls
|
||||
# @param provider [String] Provider name or ID
|
||||
#
|
||||
# @return [Provider]
|
||||
def self.by_name(client, provider)
|
||||
if provider.to_s.match(/^[0123456789]+$/)
|
||||
provider = Provider.new_with_id(Integer(provider), client)
|
||||
rc = provider.info(true)
|
||||
|
||||
return rc if OpenNebula.is_error?(rc)
|
||||
|
||||
provider
|
||||
else
|
||||
pool = ProviderPool.new(client)
|
||||
rc = pool.info_group
|
||||
|
||||
return rc if OpenNebula.is_error?(rc)
|
||||
|
||||
pool.find {|p| p['NAME'] == provider }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Generates document JSON information
|
||||
#
|
||||
# @param template [Hash] Provision information
|
||||
#
|
||||
# @return [JSON] Document information in JSON format
|
||||
def to_json(template)
|
||||
document = {}
|
||||
|
||||
# Create document JSON
|
||||
document['provider'] = template['name']
|
||||
document['connection'] = template['connection']
|
||||
document['registration_time'] = Time.now.to_i
|
||||
|
||||
document.to_json
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
39
src/oneprovision/lib/provider/provider_pool.rb
Normal file
39
src/oneprovision/lib/provider/provider_pool.rb
Normal file
@ -0,0 +1,39 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2020, OpenNebula Project, OpenNebula Systems #
|
||||
# #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'opennebula/document_pool_json'
|
||||
|
||||
module OneProvision
|
||||
|
||||
# ProviderPool class
|
||||
class ProviderPool < DocumentPoolJSON
|
||||
|
||||
DOCUMENT_TYPE = 102
|
||||
|
||||
def initialize(client, user_id = -2)
|
||||
super(client, user_id)
|
||||
end
|
||||
|
||||
def factory(element_xml)
|
||||
provider = OneProvision::Provider.new(element_xml, @client)
|
||||
provider.info(true)
|
||||
provider.load_body
|
||||
provider
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
311
src/oneprovision/lib/provision/oneprovision.rb
Normal file
311
src/oneprovision/lib/provision/oneprovision.rb
Normal file
@ -0,0 +1,311 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2020, OpenNebula Project, OpenNebula Systems #
|
||||
# #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'provision/ansible'
|
||||
require 'provision/driver'
|
||||
require 'provision/provision'
|
||||
require 'provision/provision_pool'
|
||||
require 'provision/resources'
|
||||
require 'provision/utils'
|
||||
|
||||
require 'logger'
|
||||
require 'singleton'
|
||||
|
||||
module OneProvision
|
||||
|
||||
# Singleton OneProvision Logger
|
||||
class OneProvisionLogger
|
||||
|
||||
include Singleton
|
||||
|
||||
attr_reader :logger
|
||||
|
||||
# Class constructor
|
||||
def initialize
|
||||
@logger = Logger.new(STDERR)
|
||||
end
|
||||
|
||||
# Gets the logger
|
||||
#
|
||||
# @param options [Key-Value Object] CLI options
|
||||
def self.get_logger(options)
|
||||
format = '%Y-%m-%d %H:%M:%S'
|
||||
|
||||
instance.logger.formatter = proc do |severity, datetime, _p, msg|
|
||||
"#{datetime.strftime(format)} #{severity.ljust(5)} : #{msg}\n"
|
||||
end
|
||||
|
||||
if options.key? :debug
|
||||
instance.logger.level = Logger::DEBUG
|
||||
elsif options.key? :verbose
|
||||
instance.logger.level = Logger::INFO
|
||||
else
|
||||
instance.logger.level = Logger::UNKNOWN
|
||||
end
|
||||
end
|
||||
|
||||
# Shows a debug message
|
||||
#
|
||||
# @param msg [String] Message to show
|
||||
def self.debug(msg)
|
||||
instance.logger.debug(msg)
|
||||
end
|
||||
|
||||
# Shows an error message
|
||||
#
|
||||
# @param msg [String] Message to show
|
||||
def self.error(msg)
|
||||
instance.logger.error(msg)
|
||||
end
|
||||
|
||||
# Shows an info message
|
||||
#
|
||||
# @param msg [String] Message to show
|
||||
def self.info(msg)
|
||||
instance.logger.info(msg)
|
||||
end
|
||||
|
||||
# Shows a warning message
|
||||
#
|
||||
# @param msg [String] Message to show
|
||||
def self.warn(msg)
|
||||
instance.logger.warn(msg)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Singleton running mode
|
||||
class Mode
|
||||
|
||||
include Singleton
|
||||
|
||||
attr_reader :run_mode
|
||||
|
||||
# Class constructor
|
||||
def initialize
|
||||
@run_mode = {}
|
||||
end
|
||||
|
||||
# Gets running mode
|
||||
#
|
||||
# @param options [Key-Value Object] CLI options
|
||||
def self.get_run_mode(options)
|
||||
if options.key? :batch
|
||||
instance.run_mode[:mode] = :batch
|
||||
else
|
||||
instance.run_mode[:mode] = RUN_MODE_DEFAULT
|
||||
end
|
||||
|
||||
instance.run_mode[:fail_modes] = []
|
||||
|
||||
if options.key? :fail_modes
|
||||
instance.run_mode[:fail_modes] << options[:fail_modes]
|
||||
end
|
||||
|
||||
options.each do |key, _|
|
||||
next unless key =~ /^fail_/
|
||||
|
||||
next if key =~ /sleep/ || key =~ /modes/
|
||||
|
||||
instance.run_mode[:fail_modes] << key.to_s.split('_')[1].to_sym
|
||||
end
|
||||
|
||||
if instance.run_mode[:fail_modes].empty?
|
||||
instance.run_mode[:fail_modes] << FAIL_CHOICE_DEFAULT
|
||||
end
|
||||
|
||||
instance.run_mode[:fail_modes].flatten!
|
||||
|
||||
if options.key? :fail_sleep
|
||||
instance.run_mode[:fail_sleep] = options[:fail_sleep]
|
||||
end
|
||||
|
||||
if options[:fail_retry]
|
||||
instance.run_mode[:max_retries] = Integer(options[:fail_retry])
|
||||
else
|
||||
instance.run_mode[:max_retries] = MAX_RETRIES_DEFAULT
|
||||
end
|
||||
|
||||
instance.run_mode[:cleanup] = CLEANUP_DEFAULT
|
||||
end
|
||||
|
||||
# Gets cleanup value
|
||||
#
|
||||
# @return [Boolean] Cleanup
|
||||
def self.cleanup
|
||||
instance.run_mode[:cleanup]
|
||||
end
|
||||
|
||||
# Gets fail choice value
|
||||
#
|
||||
# @return [Sym] Choice value
|
||||
def self.fail_choice
|
||||
instance.run_mode[:fail_modes][0]
|
||||
end
|
||||
|
||||
# Gets time between fail modes
|
||||
#
|
||||
# @return [Integer] Time in seconds
|
||||
def self.fail_sleep
|
||||
instance.run_mode[:fail_sleep]
|
||||
end
|
||||
|
||||
# Gets next fail choice value
|
||||
#
|
||||
# @return [Sym] Choice value
|
||||
def self.next_fail_choice
|
||||
instance.run_mode[:fail_modes].shift
|
||||
end
|
||||
|
||||
# Gets max retries value
|
||||
#
|
||||
# @return [Integer] Maximun retries
|
||||
def self.max_retries
|
||||
instance.run_mode[:max_retries]
|
||||
end
|
||||
|
||||
# Gets mode value
|
||||
#
|
||||
# @return [Sym] Mode value
|
||||
def self.mode
|
||||
instance.run_mode[:mode]
|
||||
end
|
||||
|
||||
# Sets cleanup value
|
||||
#
|
||||
# @param value [Boolean] New cleanup value
|
||||
def self.new_cleanup(value)
|
||||
instance.run_mode[:cleanup] = value
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Singleton options
|
||||
class Options
|
||||
|
||||
include Singleton
|
||||
|
||||
attr_reader :run_options
|
||||
|
||||
# Class constructor
|
||||
def initialize
|
||||
@run_options = {}
|
||||
end
|
||||
|
||||
# Gets options
|
||||
#
|
||||
# @param options [Key-Value Object] CLI Options
|
||||
def self.get_run_options(options)
|
||||
if options.key? :ping_timeout
|
||||
instance.run_options[:ping_timeout] = options[:ping_timeout]
|
||||
else
|
||||
instance.run_options[:ping_timeout] = PING_TIMEOUT_DEFAULT
|
||||
end
|
||||
|
||||
if options.key? :ping_retries
|
||||
instance.run_options[:ping_retries] = options[:ping_retries]
|
||||
else
|
||||
instance.run_options[:ping_retries] = PING_RETRIES_DEFAULT
|
||||
end
|
||||
|
||||
if options.key? :threads
|
||||
instance.run_options[:threads] = options[:threads]
|
||||
else
|
||||
instance.run_options[:threads] = THREADS_DEFAULT
|
||||
end
|
||||
end
|
||||
|
||||
# Gets ping retries value
|
||||
#
|
||||
# @return [Integer] Ping retries value
|
||||
def self.ping_retries
|
||||
instance.run_options[:ping_retries]
|
||||
end
|
||||
|
||||
# Gets ping timeout value
|
||||
#
|
||||
# @return [Integer] Ping timeout value
|
||||
def self.ping_timeout
|
||||
instance.run_options[:ping_timeout]
|
||||
end
|
||||
|
||||
# Gets number of threads
|
||||
#
|
||||
# @return [Integer] Number of threads
|
||||
def self.threads
|
||||
instance.run_options[:threads]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Singleton virtual objects options
|
||||
class ObjectOptions
|
||||
|
||||
include Singleton
|
||||
|
||||
attr_reader :obj_opts
|
||||
|
||||
# Class constructor
|
||||
def initialize
|
||||
@obj_opts = {}
|
||||
end
|
||||
|
||||
# Gets options
|
||||
#
|
||||
# @param options [Key-Value Object] CLI Options
|
||||
def self.get_obj_options(options)
|
||||
if options.key? :wait_ready
|
||||
instance.obj_opts[:wait_ready] = true
|
||||
else
|
||||
instance.obj_opts[:wait_ready] = false
|
||||
end
|
||||
|
||||
if options.key? :wait_timeout
|
||||
instance.obj_opts[:wait_timeout] = options[:wait_timeout]
|
||||
else
|
||||
instance.obj_opts[:wait_timeout] = WAIT_TIMEOUT_DEFAULT
|
||||
end
|
||||
end
|
||||
|
||||
# Get wait and timeout
|
||||
#
|
||||
# @param meta [Hash] Meta information from object
|
||||
#
|
||||
# @return [boolean, integer] [wait, timeout]
|
||||
def self.get_wait(meta)
|
||||
if meta
|
||||
wait = meta['wait']
|
||||
timeout = meta['wait_timeout']
|
||||
end
|
||||
|
||||
case wait
|
||||
when false
|
||||
[wait, nil]
|
||||
when true
|
||||
if timeout
|
||||
[wait, timeout]
|
||||
else
|
||||
[wait, instance.obj_opts[:wait_timeout]]
|
||||
end
|
||||
else
|
||||
[instance.obj_opts[:wait_ready],
|
||||
instance.obj_opts[:wait_timeout]]
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
@ -58,16 +58,27 @@ module OneProvision
|
||||
|
||||
# Allocates a new document
|
||||
#
|
||||
# @param template [Hash] Document information
|
||||
def allocate(template)
|
||||
super(generate_document_json(template), template['name'])
|
||||
# @param template [Hash] Document information
|
||||
# @param provider [String] Provision provider
|
||||
def allocate(template, provider)
|
||||
rc = nil
|
||||
|
||||
begin
|
||||
rc = to_json(template, provider)
|
||||
|
||||
return rc if OpenNebula.is_error?(rc)
|
||||
rescue StandardError => e
|
||||
return OpenNebula::Error.new(e)
|
||||
end
|
||||
|
||||
super(rc, template['name'])
|
||||
end
|
||||
|
||||
# Returns provision state
|
||||
#
|
||||
# @return [Intenger] Provision state
|
||||
def state
|
||||
@body['state'].to_i
|
||||
Integer(@body['state'])
|
||||
end
|
||||
|
||||
# Returns provision state in string format
|
||||
@ -116,16 +127,58 @@ module OneProvision
|
||||
|
||||
# Deploys a new provision
|
||||
#
|
||||
# @param config [String] Path to the configuration file
|
||||
# @param cleanup [Boolean] True to delete everything if something fails
|
||||
# @param timeout [Integer] Timeout for deleting running VMs
|
||||
# @param skip [Symbol] Skip provision, config or none phases
|
||||
def deploy(config, cleanup, timeout, skip)
|
||||
# @param config [String] Path to deployment file
|
||||
# @param cleanup [Boolean] True to cleanup everything
|
||||
# @param timeout [Integer] Timeout in seconds to connect to hosts
|
||||
# @param skip [Symbol] Skip provision, configuration or anything
|
||||
# @param provider [Provider] Provider to deploy the provision
|
||||
#
|
||||
# @return [Integer] Provision ID
|
||||
def deploy(config, cleanup, timeout, skip, provider)
|
||||
Ansible.check_ansible_version
|
||||
|
||||
begin
|
||||
cfg = Utils.read_config(config)
|
||||
|
||||
if provider
|
||||
# Respect user information, only add provider info if
|
||||
# the user hasn't specified any
|
||||
cfg['defaults'] = {} unless cfg['defaults']
|
||||
|
||||
# Get user UID to see if merge is possible or not
|
||||
# only merge attributes if the provider is owned by user
|
||||
info = Nokogiri::XML(@client.call('user.info', -1))
|
||||
uid = info.xpath('/USER/ID').text
|
||||
|
||||
# Get provider connection information
|
||||
conn = provider.connection
|
||||
|
||||
if uid == provider['UID']
|
||||
cfg['defaults']['provision'] = conn.merge(
|
||||
cfg['defaults']['provision']
|
||||
)
|
||||
|
||||
OneProvisionLogger.debug('Merging provider connection')
|
||||
else
|
||||
cfg['defaults']['provision'] = conn
|
||||
|
||||
OneProvisionLogger.debug('Using provider connection')
|
||||
end
|
||||
end
|
||||
|
||||
# read provision file
|
||||
cfg = Utils.create_config(Utils.read_config(config))
|
||||
cfg = Utils.create_config(cfg)
|
||||
|
||||
# read provider information
|
||||
if provider
|
||||
provider = provider['NAME']
|
||||
else
|
||||
provider = Provision.read_provider(cfg)
|
||||
end
|
||||
|
||||
unless provider
|
||||
return OpenNebula::Error.new('No provider found')
|
||||
end
|
||||
|
||||
# @name is used for ERB evaluation
|
||||
@name = cfg['name']
|
||||
@ -144,9 +197,9 @@ module OneProvision
|
||||
create_infra_resources(cfg, cfg['cluster']['id'])
|
||||
create_hosts(cfg, cfg['cluster']['id'])
|
||||
|
||||
allocate(cfg)
|
||||
allocate(cfg, provider)
|
||||
|
||||
info
|
||||
self.info
|
||||
|
||||
# @id is used for ERB evaluation
|
||||
@id = self['ID']
|
||||
@ -366,32 +419,43 @@ module OneProvision
|
||||
binding
|
||||
end
|
||||
|
||||
# Reads provider name from template
|
||||
#
|
||||
# @param template [Hash] Provision information
|
||||
#
|
||||
# @return [String] Provider name
|
||||
def self.read_provider(template)
|
||||
provider = nil
|
||||
|
||||
# Provider can be set in provision defaults or in hosts
|
||||
# it's the same for all hosts, taking the first one is enough
|
||||
if template['defaults'] && template['defaults']['provision']
|
||||
provider = template['defaults']['provision']['provider']
|
||||
end
|
||||
|
||||
if !provider && template['hosts'][0]['provision']
|
||||
provider = template['hosts'][0]['provision']['provider']
|
||||
end
|
||||
|
||||
provider
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Generates document JSON information
|
||||
#
|
||||
# @param template [Hash] Provision information
|
||||
# @param template [Hash] Provision information
|
||||
# @param provider [String] Provision provider
|
||||
#
|
||||
# @return [JSON] Document information in JSON format
|
||||
def generate_document_json(template)
|
||||
def to_json(template, provider)
|
||||
document = {}
|
||||
|
||||
document['name'] = template['name']
|
||||
document['description'] = template['description']
|
||||
document['start_time'] = Time.now.to_i
|
||||
document['state'] = STATE['DEPLOYING']
|
||||
|
||||
# Driver can be set in provision defaults or in hosts
|
||||
# it's the same for all hosts, taking the first one is enough
|
||||
if template['defaults'] && template['defaults']['provision']
|
||||
driver = template['defaults']['provision']['driver']
|
||||
end
|
||||
|
||||
if !driver && template['hosts'][0]['provision']
|
||||
driver = template['hosts'][0]['provision']['driver']
|
||||
end
|
||||
|
||||
document['provider'] = driver
|
||||
document['provider'] = provider
|
||||
|
||||
# Fill provision objects information
|
||||
document['provision'] = {}
|
||||
@ -529,7 +593,7 @@ module OneProvision
|
||||
|
||||
host = Host.new
|
||||
host = host.create(dfile.to_xml, cid, playbooks)
|
||||
h['id'] = host['ID']
|
||||
h['id'] = Integer(host['ID'])
|
||||
h['name'] = host['NAME']
|
||||
|
||||
host.offline
|
||||
@ -621,7 +685,7 @@ module OneProvision
|
||||
|
||||
Utils.exception(host.info(h['id']))
|
||||
|
||||
return true if host.one['HOST_SHARE/RUNNING_VMS'].to_i > 0
|
||||
return true if Integer(host.one['HOST_SHARE/RUNNING_VMS']) > 0
|
||||
end
|
||||
|
||||
false
|
||||
@ -646,7 +710,7 @@ module OneProvision
|
||||
next unless resource_objects['images']
|
||||
|
||||
resource_objects['images'].find do |value|
|
||||
true if image.to_i == value['id'].to_i
|
||||
true if Integer(image) == Integer(value['id'])
|
||||
end
|
||||
end
|
||||
|
||||
@ -668,7 +732,7 @@ module OneProvision
|
||||
|
||||
Utils.exception(host.info(h['id']))
|
||||
|
||||
next unless host.one['HOST_SHARE/RUNNING_VMS'].to_i > 0
|
||||
next unless Integer(host.one['HOST_SHARE/RUNNING_VMS']) > 0
|
||||
|
||||
d_hosts << host.one
|
||||
end
|
@ -28,7 +28,7 @@ module OneProvision
|
||||
end
|
||||
|
||||
def factory(element_xml)
|
||||
provision = OpenNebula::Provision.new(element_xml, @client)
|
||||
provision = OneProvision::Provision.new(element_xml, @client)
|
||||
provision.load_body
|
||||
provision
|
||||
end
|
@ -14,9 +14,9 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'resources/resource'
|
||||
require 'resources/physical'
|
||||
require 'resources/virtual'
|
||||
require 'provision/resources/resource'
|
||||
require 'provision/resources/physical'
|
||||
require 'provision/resources/virtual'
|
||||
|
||||
# Module OneProvision
|
||||
module OneProvision
|
@ -14,10 +14,10 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'resources/physical/cluster'
|
||||
require 'resources/physical/datastore'
|
||||
require 'resources/physical/host'
|
||||
require 'resources/physical/network'
|
||||
require 'provision/resources/physical/cluster'
|
||||
require 'provision/resources/physical/datastore'
|
||||
require 'provision/resources/physical/host'
|
||||
require 'provision/resources/physical/network'
|
||||
|
||||
# Module OneProvision
|
||||
module OneProvision
|
@ -14,7 +14,7 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'resources/resource'
|
||||
require 'provision/resources/resource'
|
||||
|
||||
module OneProvision
|
||||
|
||||
@ -44,7 +44,7 @@ module OneProvision
|
||||
rc = @one.info
|
||||
Utils.exception(rc)
|
||||
|
||||
@one.id.to_i
|
||||
Integer(@one.id)
|
||||
end
|
||||
|
||||
# Info an specific object
|
@ -14,7 +14,7 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'resources/physical/physical_resource'
|
||||
require 'provision/resources/physical/physical_resource'
|
||||
|
||||
module OneProvision
|
||||
|
@ -14,7 +14,7 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'resources/resource'
|
||||
require 'provision/resources/resource'
|
||||
|
||||
module OneProvision
|
||||
|
||||
@ -28,18 +28,18 @@ module OneProvision
|
||||
|
||||
# Class constructor
|
||||
#
|
||||
# @param driver [String] Host driver
|
||||
def initialize(driver = nil)
|
||||
# @param provider [String] Host provider
|
||||
def initialize(provider = nil)
|
||||
super()
|
||||
|
||||
@pool = OpenNebula::HostPool.new(@client)
|
||||
@type = 'host'
|
||||
@driver = driver
|
||||
@pool = OpenNebula::HostPool.new(@client)
|
||||
@type = 'host'
|
||||
@provider = provider
|
||||
end
|
||||
|
||||
# Checks if there are Running VMs on the HOST
|
||||
def running_vms?
|
||||
@one['HOST_SHARE/RUNNING_VMS'].to_i > 0
|
||||
Integer(@one['HOST_SHARE/RUNNING_VMS']) > 0
|
||||
end
|
||||
|
||||
# Establishes an SSH connection to the HOST
|
||||
@ -130,7 +130,7 @@ module OneProvision
|
||||
|
||||
params = [resume_file.path, @one.name]
|
||||
|
||||
Driver.pm_driver_action(@driver, 'deploy', params, @one)
|
||||
Driver.pm_driver_action(@provider, 'deploy', params, @one)
|
||||
|
||||
OneProvisionLogger.debug("Enabling OpenNebula host: #{@one.id}")
|
||||
|
||||
@ -153,7 +153,7 @@ module OneProvision
|
||||
|
||||
params = [deploy_id, name, 'SHUTDOWN_POWEROFF']
|
||||
|
||||
Driver.pm_driver_action(@driver, 'shutdown', params, @one)
|
||||
Driver.pm_driver_action(@provider, 'shutdown', params, @one)
|
||||
|
||||
OneProvisionLogger.debug("Offlining OpenNebula host: #{@one.id}")
|
||||
|
||||
@ -193,7 +193,7 @@ module OneProvision
|
||||
|
||||
params = [deploy_id, name]
|
||||
|
||||
Driver.pm_driver_action(@driver, 'cancel', params, @one)
|
||||
Driver.pm_driver_action(@provider, 'cancel', params, @one)
|
||||
end
|
||||
|
||||
# delete ONE host
|
||||
@ -214,8 +214,8 @@ module OneProvision
|
||||
|
||||
# Checks that the HOST is a baremetal HOST
|
||||
def check
|
||||
Utils.fail('Not a valid bare metal host') if @driver.nil?
|
||||
Utils.fail('Not a valid bare metal host') if @driver.empty?
|
||||
Utils.fail('Not a valid bare metal host') if @provider.nil?
|
||||
Utils.fail('Not a valid bare metal host') if @provider.empty?
|
||||
end
|
||||
|
||||
# Monitors the HOST
|
||||
@ -234,7 +234,10 @@ module OneProvision
|
||||
|
||||
params = [deploy_id, name]
|
||||
|
||||
pm_ret = Driver.pm_driver_action(@driver, 'poll', params, @one)
|
||||
pm_ret = Driver.pm_driver_action(@provider,
|
||||
'poll',
|
||||
params,
|
||||
@one)
|
||||
|
||||
begin
|
||||
poll = {}
|
||||
@ -281,7 +284,7 @@ module OneProvision
|
||||
@one.offline
|
||||
|
||||
OneProvisionLogger.info("#{message} host: #{@one.id}")
|
||||
Driver.pm_driver_action(@driver, action, [deploy_id, name], @one)
|
||||
Driver.pm_driver_action(@provider, action, [deploy_id, name], @one)
|
||||
|
||||
OneProvisionLogger.debug("Enabling OpenNebula host: #{@one.id}")
|
||||
|
@ -14,7 +14,7 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'resources/physical/physical_resource'
|
||||
require 'provision/resources/physical/physical_resource'
|
||||
|
||||
module OneProvision
|
||||
|
@ -14,7 +14,7 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'resources/resource'
|
||||
require 'provision/resources/resource'
|
||||
|
||||
module OneProvision
|
||||
|
||||
@ -40,7 +40,7 @@ module OneProvision
|
||||
"#{@type} created with ID: #{@one.id}"
|
||||
)
|
||||
|
||||
@one.id.to_i
|
||||
Integer(@one.id)
|
||||
end
|
||||
|
||||
end
|
@ -176,7 +176,7 @@ module OneProvision
|
||||
user ||= 0
|
||||
group ||= 0
|
||||
|
||||
if user == @one['UID'].to_i || group == @one['GID'].to_i
|
||||
if user == Integer(@one['UID']) || group == Integer(@one['GID'])
|
||||
OneProvisionLogger.debug(
|
||||
"Ownership for #{@type} #{@one.id} is already " \
|
||||
"#{user}:#{group}"
|
@ -14,11 +14,11 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'resources/virtual/image'
|
||||
require 'resources/virtual/marketplaceapp'
|
||||
require 'resources/virtual/template'
|
||||
require 'resources/virtual/flowtemplate'
|
||||
require 'resources/virtual/vntemplate'
|
||||
require 'provision/resources/virtual/image'
|
||||
require 'provision/resources/virtual/marketplaceapp'
|
||||
require 'provision/resources/virtual/template'
|
||||
require 'provision/resources/virtual/flowtemplate'
|
||||
require 'provision/resources/virtual/vntemplate'
|
||||
|
||||
# Module OneProvision
|
||||
module OneProvision
|
@ -14,7 +14,7 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'resources/virtual/virtual_resource'
|
||||
require 'provision/resources/virtual/virtual_resource'
|
||||
require 'models'
|
||||
|
||||
require 'json'
|
@ -14,7 +14,7 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'resources/virtual/virtual_sync_resource'
|
||||
require 'provision/resources/virtual/virtual_sync_resource'
|
||||
|
||||
module OneProvision
|
||||
|
||||
@ -49,7 +49,7 @@ module OneProvision
|
||||
new_object
|
||||
|
||||
rc = @one.allocate(format_template(template),
|
||||
template['ds_id'].to_i)
|
||||
Integer(template['ds_id']))
|
||||
Utils.exception(rc)
|
||||
rc = @one.info
|
||||
Utils.exception(rc)
|
||||
@ -58,7 +58,7 @@ module OneProvision
|
||||
"#{@type} created with ID: #{@one.id}"
|
||||
)
|
||||
|
||||
return @one.id.to_i unless wait
|
||||
return Integer(@one.id) unless wait
|
||||
|
||||
ready?(template)
|
||||
end
|
||||
@ -99,7 +99,7 @@ module OneProvision
|
||||
raise OneProvisionLoopException
|
||||
else
|
||||
# if everything is ready, return the ID
|
||||
@one.id.to_i
|
||||
Integer(@one.id)
|
||||
end
|
||||
end
|
||||
end
|
@ -14,7 +14,7 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'resources/virtual/virtual_sync_resource'
|
||||
require 'provision/resources/virtual/virtual_sync_resource'
|
||||
|
||||
module OneProvision
|
||||
|
||||
@ -55,11 +55,16 @@ module OneProvision
|
||||
|
||||
Utils.exception(rc)
|
||||
app.extend(MarketPlaceAppExt)
|
||||
url_args = "tag=#{template['tag']}" if template['tag']
|
||||
rc = app.info
|
||||
|
||||
Utils.exception(rc)
|
||||
|
||||
rc = app.export(
|
||||
:dsid => template['dsid'].to_i,
|
||||
:dsid => Integer(template['dsid']),
|
||||
:name => template['name'],
|
||||
:vmtemplate_name => template['vmname']
|
||||
:vmtemplate_name => template['vmname'],
|
||||
:url_args => url_args
|
||||
)
|
||||
Utils.exception(rc[:image].first) if rc[:image]
|
||||
Utils.exception(rc[:vmtemplate].first) if rc[:vmtemplate]
|
@ -14,7 +14,7 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'resources/virtual/virtual_resource'
|
||||
require 'provision/resources/virtual/virtual_resource'
|
||||
|
||||
module OneProvision
|
||||
|
@ -14,7 +14,7 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'resources/resource'
|
||||
require 'provision/resources/resource'
|
||||
|
||||
module OneProvision
|
||||
|
||||
@ -39,7 +39,7 @@ module OneProvision
|
||||
"#{@type} created with ID: #{@one.id}"
|
||||
)
|
||||
|
||||
@one.id.to_i
|
||||
Integer(@one.id)
|
||||
end
|
||||
|
||||
end
|
@ -14,7 +14,7 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'resources/resource'
|
||||
require 'provision/resources/resource'
|
||||
|
||||
module OneProvision
|
||||
|
@ -14,7 +14,7 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'resources/virtual/virtual_resource'
|
||||
require 'provision/resources/virtual/virtual_resource'
|
||||
|
||||
module OneProvision
|
||||
|
@ -351,7 +351,7 @@ module OneProvision
|
||||
xml.VM_MAD host['vm_mad']
|
||||
xml.PROVISION do
|
||||
host['provision'].each do |key, value|
|
||||
if key != 'driver'
|
||||
if key != 'provider'
|
||||
xml.send(key.upcase, value)
|
||||
end
|
||||
end
|
64
src/oneprovision/lib/provision_element.rb
Normal file
64
src/oneprovision/lib/provision_element.rb
Normal file
@ -0,0 +1,64 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2020, OpenNebula Project, OpenNebula Systems #
|
||||
# #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'opennebula/document_json'
|
||||
|
||||
# OneProvision module
|
||||
module OneProvision
|
||||
|
||||
# Provision element
|
||||
class ProvisionElement < DocumentJSON
|
||||
|
||||
TEMPLATE_TAG = 'PROVISION_BODY'
|
||||
|
||||
# Body tag
|
||||
attr_reader :tag
|
||||
|
||||
# Body
|
||||
attr_reader :body
|
||||
|
||||
# Class constructor
|
||||
def initialize(xml, client)
|
||||
super
|
||||
|
||||
@tag = TEMPLATE_TAG
|
||||
end
|
||||
|
||||
# Replaces the template contents
|
||||
#
|
||||
# @param template_json [String] New template contents
|
||||
#
|
||||
# @return [nil, OpenNebula::Error] nil in case of success, Error
|
||||
# otherwise
|
||||
def update(template_json)
|
||||
template_json = JSON.parse(template_json)
|
||||
|
||||
if template_json.keys != @body.keys
|
||||
return OpenNebula::Error.new('Keys can not be changed')
|
||||
end
|
||||
|
||||
self.class::UNMUTABLE_ATTRS.each do |attr|
|
||||
next if template_json[attr] == @body[attr]
|
||||
|
||||
return OpenNebula::Error.new("`#{attr}` can not be changed")
|
||||
end
|
||||
|
||||
super(template_json.to_json)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
161
src/oneprovision/lib/provision_template/provision_template.rb
Normal file
161
src/oneprovision/lib/provision_template/provision_template.rb
Normal file
@ -0,0 +1,161 @@
|
||||
# #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'base64'
|
||||
require 'tempfile'
|
||||
|
||||
module OneProvision
|
||||
|
||||
# Provision Template class as wrapper of DocumentJSON
|
||||
class ProvisionTemplate < ProvisionElement
|
||||
|
||||
DOCUMENT_TYPE = 104
|
||||
|
||||
# These attributes can not be changed when updating the template
|
||||
UNMUTABLE_ATTRS = %w[name provider registration_time]
|
||||
|
||||
# Allocates a new document
|
||||
#
|
||||
# @param template [Hash] Document information
|
||||
def allocate(template)
|
||||
pool = ProvisionTemplatePool.new(@client)
|
||||
rc = pool.info_group
|
||||
|
||||
return rc if OpenNebula.is_error?(rc)
|
||||
|
||||
rc = pool.find do |p|
|
||||
p['NAME'] == template['name']
|
||||
end
|
||||
|
||||
if rc
|
||||
return OpenNebula::Error.new(
|
||||
"Provision template #{template['name']} already exists"
|
||||
)
|
||||
end
|
||||
|
||||
rc = nil
|
||||
|
||||
begin
|
||||
rc = to_json(template)
|
||||
|
||||
return rc if OpenNebula.is_error?(rc)
|
||||
rescue StandardError => e
|
||||
return OpenNebula::Error.new(e)
|
||||
end
|
||||
|
||||
super(rc, template['name'], TEMPLATE_TAG)
|
||||
end
|
||||
|
||||
# Instantiate the template
|
||||
#
|
||||
# @param cleanup [Boolean] True to cleanup everything
|
||||
# @param timeout [Integer] Timeout in seconds to connect to hosts
|
||||
# @param skip [Symbol] Skip provision, configuration or anything
|
||||
# @param provider [String] Provider ID or name
|
||||
# @param extra [String] Path to extra template information
|
||||
#
|
||||
# @param [Intenger] New provision ID
|
||||
def instantiate(cleanup, timeout, skip, provider, extra)
|
||||
rc = info(true)
|
||||
|
||||
return rc if OpenNebula.is_error?(rc)
|
||||
|
||||
# If provider option is provided, respect it and ignore provision
|
||||
# template provider information
|
||||
if provider
|
||||
provider = Provider.by_name(@client, provider)
|
||||
else
|
||||
if @body['provider']
|
||||
provider = Provider.new_with_id(@body['provider'], @client)
|
||||
rc = provider.info(true)
|
||||
|
||||
return rc if OpenNebula.is_error?(rc)
|
||||
|
||||
@body['defaults']['provision'] = provider.connection
|
||||
end
|
||||
end
|
||||
|
||||
# Merge extra information supplied by the user with the current
|
||||
# information stored in the template
|
||||
if extra
|
||||
begin
|
||||
extra = YAML.load_file(extra)
|
||||
@body = @body.merge(extra)
|
||||
rescue StandardError => e
|
||||
return OpenNebula::Error.new(e)
|
||||
end
|
||||
end
|
||||
|
||||
tempfile = Tempfile.new('provision-template')
|
||||
tempfile << @body.to_yaml
|
||||
tempfile.close
|
||||
|
||||
xml = OneProvision::Provision.build_xml
|
||||
provision = OneProvision::Provision.new(xml, @client)
|
||||
|
||||
provision.deploy(tempfile.path, cleanup, timeout, skip, provider)
|
||||
ensure
|
||||
tempfile.unlink if tempfile
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Generates document JSON information
|
||||
#
|
||||
# @param template [Hash] Provision information
|
||||
#
|
||||
# @return [JSON] Document information in JSON format
|
||||
def to_json(template)
|
||||
document = {}
|
||||
provider = Provision.read_provider(template)
|
||||
provider = Provider.by_name(@client, provider)
|
||||
|
||||
return provider if OpenNebula.is_error?(provider)
|
||||
|
||||
return OpenNebula::Error.new('Provider not found') unless provider
|
||||
|
||||
# Remove provider information as it has been converted to ID
|
||||
if template['defaults']['provision']['provider']
|
||||
template['defaults']['provision'].delete('provider')
|
||||
end
|
||||
|
||||
if template['hosts']
|
||||
template['hosts'].each do |host|
|
||||
next unless host['provision']['provider']
|
||||
|
||||
host['provision'].delete('provider')
|
||||
end
|
||||
end
|
||||
|
||||
# Create document JSON
|
||||
document['name'] = template['name']
|
||||
document['provider'] = provider['ID']
|
||||
document['registration_time'] = Time.now.to_i
|
||||
document['playbooks'] = template['playbook']
|
||||
document['defaults'] = template['defaults']
|
||||
|
||||
(Provision::RESOURCES + Provision::FULL_CLUSTER).each do |resource|
|
||||
next unless template[resource]
|
||||
|
||||
document[resource] = template[resource]
|
||||
end
|
||||
|
||||
document['cluster'] = template['cluster'] if template['cluster']
|
||||
|
||||
document.to_json
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
@ -0,0 +1,39 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2020, OpenNebula Project, OpenNebula Systems #
|
||||
# #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'opennebula/document_pool_json'
|
||||
|
||||
module OneProvision
|
||||
|
||||
# Provision Template Pool class
|
||||
class ProvisionTemplatePool < DocumentPoolJSON
|
||||
|
||||
DOCUMENT_TYPE = 104
|
||||
|
||||
def initialize(client, user_id = -2)
|
||||
super(client, user_id)
|
||||
end
|
||||
|
||||
def factory(element_xml)
|
||||
template = OneProvision::ProvisionTemplate.new(element_xml, @client)
|
||||
template.info(true)
|
||||
template.load_body
|
||||
template
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue
Block a user