1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-23 22:50:09 +03:00

F #5591: Custom role attributes in oneflow added (#2465)

Custom attributes have been added at the role level.
In this way, roles can be individually customized during instantiation.
Added parameters:
- custom_attrs: contains user-defined custom attributes.
- custom_attrs_values: contains the values of the custom_attrs.
  In case of overlapping role and service level attributes, role level attributes will take precedence.

Example:
roles: [
    {
        "name": "role_1",
        ...
        "custom_attrs": {
            "MEMORY": "M|range|memory (mb)|100..500|200",
            "DISK_SIZE": "M|range|disk size (mb)|100..500|250"
        }
    }
]

In order to be used from CLI, the vm_template_contents in the service template must be filled manually.
This commit is contained in:
Victor Palma 2023-02-07 07:41:03 +01:00 committed by GitHub
parent c10d4ea5e5
commit 90aac4b5f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 88 additions and 27 deletions

View File

@ -193,6 +193,35 @@ class OneFlowTemplateHelper < OpenNebulaHelper::OneHelper
ret
end
# Get custom role attributes values from user
#
# @param role [Hash] Service role with custom attributes
#
# @return [Hash] Role with custom attributes values
def custom_role_attrs(roles)
return if roles.nil? || roles.empty?
ret = {}
role_with_custom_attrs = false
roles.each do |role|
next unless role.key?('custom_attrs')
####################################################################
# Display Role Information
####################################################################
header = "> Please insert the user inputs for the role \"#{role['name']}\""
puts header
role.merge!(custom_attrs(role['custom_attrs']))
role_with_custom_attrs = true
end
ret['roles'] = roles if role_with_custom_attrs
ret
end
def networks(vnets)
return unless vnets

View File

@ -61,6 +61,7 @@ require 'command_parser'
require 'opennebula/oneflow_client'
require 'cli_helper'
require 'one_helper/oneflowtemplate_helper'
require 'one_helper/onetemplate_helper'
USER_AGENT = 'CLI'
@ -253,14 +254,18 @@ CommandParser::CmdParser.new(ARGV) do
break
end
params['merge_template'] = {}
body = JSON.parse(response.body)['DOCUMENT']['TEMPLATE']['BODY']
params['merge_template'] = helper.custom_attrs(
body['custom_attrs']
)
# Check global custom attributes
custom_attrs = helper.custom_attrs(body['custom_attrs'])
params['merge_template'].merge!(custom_attrs) unless custom_attrs.nil?
params['merge_template'] = {} unless params['merge_template']
# Check role level custom attributes
custom_role_attrs = helper.custom_role_attrs(body['roles'])
params['merge_template'].merge!(custom_role_attrs) unless custom_role_attrs.nil?
# Check vnets attributes
vnets = helper.networks(body['networks'])
params['merge_template'].merge!(vnets) unless vnets.nil?
end

View File

@ -323,6 +323,9 @@ module OpenNebula
template['start_time'] = Integer(Time.now)
# Replace $attibute by the corresponding value
resolve_attributes(template)
super(template.to_json, template['name'])
end
@ -789,9 +792,17 @@ module OpenNebula
# $CUSTOM1_VAR Any word character
# (letter, number, underscore)
role['vm_template_contents'].scan(/\$(\w+)/).each do |key|
# Check if $ var value is in custom_attrs_values within the role
if !role['custom_attrs_values'].nil? && role['custom_attrs_values'].key?(key[0])
role['vm_template_contents'].gsub!(
'$'+key[0],
role['custom_attrs_values'][key[0]]
)
next
end
# Check if $ var value is in custom_attrs_values
if !template['custom_attrs_values'].nil? &&
template['custom_attrs_values'].key?(key[0])
if !template['custom_attrs_values'].nil? && template['custom_attrs_values'].key?(key[0])
role['vm_template_contents'].gsub!(
'$'+key[0],
template['custom_attrs_values'][key[0]]

View File

@ -186,6 +186,25 @@ def one_error_to_http(error)
end
end
# Check if the custom_attrs and their respective values are correct
#
# @param error_msg [String] Error message
# @param error_code [Integer] Http error code
def check_custom_attrs(custom_attrs, custom_attrs_values)
return if custom_attrs.nil? || custom_attrs.empty?
if !custom_attrs.is_a?(Hash) || !custom_attrs_values.is_a?(Hash)
return internal_error('Wrong custom_attrs or custom_attrs_values format', VALIDATION_EC)
end
return if (custom_attrs.keys - custom_attrs_values.keys).empty?
internal_error(
'Verify that every custom attribute have its corresponding value defined',
VALIDATION_EC
)
end
##############################################################################
# Defaults
##############################################################################
@ -637,28 +656,15 @@ post '/service_template/:id/action' do
custom_attrs_values = merge_template['custom_attrs_values']
end
if custom_attrs && !(custom_attrs.is_a? Hash)
return internal_error('Wrong custom_attrs format',
VALIDATION_EC)
end
check_custom_attrs(custom_attrs, custom_attrs_values)
if custom_attrs_values && !(custom_attrs_values.is_a? Hash)
return internal_error('Wrong custom_attrs_values format',
VALIDATION_EC)
end
# Check role custom_attrs
roles = merge_template['roles']
if custom_attrs && !custom_attrs.empty? && !custom_attrs_values
return internal_error('No custom_attrs_values found',
VALIDATION_EC)
end
if custom_attrs &&
!custom_attrs.empty? &&
custom_attrs_values &&
!(custom_attrs.keys - custom_attrs_values.keys).empty?
return internal_error('Every custom_attrs key must have its ' \
'value defined at custom_attrs_value',
VALIDATION_EC)
roles.each do |role|
role_custom_attrs = role['custom_attrs']
role_custom_attrs_values = role['custom_attrs_values']
check_custom_attrs(role_custom_attrs, role_custom_attrs_values)
end
# Check networks

View File

@ -42,6 +42,16 @@ module OpenNebula
:type => :string,
:required => false
},
'custom_attrs' => {
:type => :object,
:properties => {},
:required => false
},
'custom_attrs_values' => {
:type => :object,
:properties => {},
:required => false
},
'parents' => {
:type => :array,
:items => {
@ -487,7 +497,7 @@ module OpenNebula
instantiate_template = JSON.parse(@body.to_json)
else
instantiate_template = JSON.parse(@body.to_json)
.merge(merge_template)
.deep_merge(merge_template)
end
begin