Promote new Fuel-CLI
Remove cli functions, update README, add new CLI promotion. Closes-Bug: #1258472 Change-Id: Ie247dbddd84b63166087a9caddc5b6ea38f77377
This commit is contained in:
parent
d14e9d2475
commit
ae026938f2
15
README.md
15
README.md
|
@ -17,7 +17,7 @@ Deploy
|
|||
|
||||
OpenStack installation in the desired configuration on the selected nodes.
|
||||
|
||||
Astute uses data about nodes and deployment settings and recalculates parameters needed for deployment. Calculated parameters are passed to the nodes being deployed by use of nailyfact MCollective agent that uploads these attributes to `/etc/naily.facts` file of the node. Then puppet parses this file using Facter plugin and uploads these facts into puppet. These facts are used during catalog compilation phase by puppet master. Finally catalog is executed and Astute orchestrator passes to the next node in deployment sequence. Fuel Library provides puppet modules for Astute.
|
||||
Astute uses data about nodes and deployment settings and recalculates parameters needed for deployment. Calculated parameters are passed to the nodes being deployed by use of nailyfact MCollective agent that uploads these attributes to `/etc/astute.yaml` file of the node. Then puppet parses this file using Facter plugin and uploads these facts into puppet. These facts are used during catalog compilation phase by puppet. Finally catalog is executed and Astute orchestrator passes to the next node in deployment sequence. Fuel Library provides puppet modules for Astute.
|
||||
|
||||
Using as library
|
||||
-----
|
||||
|
@ -46,23 +46,14 @@ orchestrator.watch_provision_progress(reporter, environment['task_uuid'], enviro
|
|||
orchestrator.deploy(reporter, environment['task_uuid'], environment['nodes'])
|
||||
|
||||
```
|
||||
|
||||
More information about expected content of environment you can find here:
|
||||
http://docs.mirantis.com/fuel/3.1/installation-fuel-cli.html#yaml-high-level-structure
|
||||
|
||||
Simple example of using Astute as library: https://github.com/Mirantis/astute/blob/master/bin/astute
|
||||
Example of using Astute as library: https://github.com/stackforge/fuel-web/blob/master/naily/lib/naily/dispatcher.rb
|
||||
|
||||
|
||||
Using as CLI
|
||||
-----
|
||||
|
||||
Provision:
|
||||
|
||||
astute -f simple.yaml -c provision
|
||||
CLI interface in Astute no longer supported. Please use new Fuel-CLI. More details you can get by link: https://github.com/Mirantis/fuel-docs/blob/master/pages/user-guide/cli.rst
|
||||
|
||||
More information about content of `simple.yaml` you can find here: http://docs.mirantis.com/fuel/3.1/installation-fuel-cli.html#yaml-high-level-structure
|
||||
|
||||
Additional materials
|
||||
-----
|
||||
|
||||
- ISO, other materials: http://fuel.mirantis.com/
|
||||
|
|
|
@ -14,7 +14,6 @@ Gem::Specification.new do |s|
|
|||
s.add_dependency 'mcollective-client', '>= 2.3.1'
|
||||
s.add_dependency 'symboltable', '1.0.2'
|
||||
s.add_dependency 'rest-client', '~> 1.6.7'
|
||||
s.add_dependency 'kwalify', '~> 0.7.2'
|
||||
|
||||
s.add_development_dependency 'rake', '10.0.4'
|
||||
s.add_development_dependency 'rspec', '2.13.0'
|
||||
|
|
100
bin/astute
100
bin/astute
|
@ -14,99 +14,9 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
if RUBY_VERSION < "1.9"
|
||||
puts "Astute tested and works only on Ruby 1.9.3 but you use #{RUBY_VERSION}"
|
||||
puts "If you still want to try it on older versions of ruby, try 'ruby -rubygems bin/astute'"
|
||||
end
|
||||
puts <<-EOF
|
||||
CLI interface in Astute no longer supported. Please use new Fuel-CLI.
|
||||
More details you can get by link: https://github.com/Mirantis/fuel-docs/blob/master/pages/user-guide/cli.rst
|
||||
EOF
|
||||
|
||||
require 'optparse'
|
||||
require 'yaml'
|
||||
require 'astute'
|
||||
require 'astute/version'
|
||||
require 'astute/cli/enviroment'
|
||||
|
||||
SUCCESS = 0
|
||||
FAIL = 1
|
||||
ERROR_CODE_COMMAND_USAGE = 64
|
||||
|
||||
class ConsoleReporter
|
||||
def report(msg)
|
||||
puts msg.inspect
|
||||
end
|
||||
end
|
||||
|
||||
def report_and_exit(exception, verbose)
|
||||
$stderr.puts "Error: #{exception.inspect}"
|
||||
unless verbose
|
||||
puts "Hint: use astute with --verbose or check log (#{Astute::LOG_PATH}) for more details"
|
||||
end
|
||||
Astute.logger.error exception.format_backtrace
|
||||
exit FAIL
|
||||
end
|
||||
|
||||
def exit_code(status)
|
||||
status.each { |node| return FAIL if node['status'] == 'error' }
|
||||
SUCCESS
|
||||
end
|
||||
|
||||
opts = {}
|
||||
optparse = OptionParser.new do |o|
|
||||
o.banner = "Usage: bin/astute -c COMMAND -f FILENAME "
|
||||
|
||||
o.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
||||
opts[:verbose] = v
|
||||
end
|
||||
|
||||
o.on("-f FILENAME", "Environment in YAML format. Samples are in examples directory.") do |f|
|
||||
opts[:filename] = f
|
||||
end
|
||||
|
||||
o.on_tail("-h", "--help", "Show this message") { puts o; exit }
|
||||
|
||||
o.on_tail("--version", "Show version") { puts Astute::VERSION; exit }
|
||||
|
||||
o.on("-c", "--command COMMAND", [:provision],
|
||||
"Select operation: provision") do |c|
|
||||
opts[:command] = c
|
||||
end
|
||||
end
|
||||
|
||||
optparse.parse!(ARGV)
|
||||
|
||||
if opts[:filename].nil?
|
||||
puts optparse
|
||||
exit ERROR_CODE_COMMAND_USAGE
|
||||
end
|
||||
|
||||
reporter = ConsoleReporter.new
|
||||
Astute.logger = Logger.new(STDOUT) if opts[:verbose]
|
||||
|
||||
begin
|
||||
environment = Astute::Cli::Enviroment.new(opts[:filename], opts[:command])
|
||||
rescue Errno::ENOENT, Psych::SyntaxError, Astute::Cli::Enviroment::ValidationError => e
|
||||
report_and_exit(e, opts[:verbose])
|
||||
end
|
||||
|
||||
if environment['attributes'] && environment['attributes']['deployment_engine']
|
||||
case environment['attributes']['deployment_engine']
|
||||
when 'nailyfact'
|
||||
deploy_engine = Astute::DeploymentEngine::NailyFact
|
||||
end
|
||||
end
|
||||
|
||||
deploy_engine ||= nil
|
||||
orchestrator = Astute::Orchestrator.new(deploy_engine, log_parsing=true)
|
||||
|
||||
def console_provision(orchestrator, reporter, environment)
|
||||
orchestrator.provision(reporter, environment['engine'], environment['nodes'])
|
||||
puts "restarting nodes..."
|
||||
sleep 5
|
||||
puts "start watching progress"
|
||||
exit_code orchestrator.watch_provision_progress(reporter, environment['task_uuid'], environment['nodes'])
|
||||
end
|
||||
|
||||
begin
|
||||
exit console_provision(orchestrator, reporter, environment) if opts[:command] == :provision
|
||||
rescue => e
|
||||
report_and_exit(e, opts[:verbose])
|
||||
end
|
||||
exit 1
|
|
@ -1,117 +0,0 @@
|
|||
---
|
||||
# Base config
|
||||
task_uuid: deployment_task
|
||||
engine:
|
||||
url: http://localhost/cobbler_api
|
||||
username: cobbler
|
||||
password: cobbler
|
||||
|
||||
# These parameters can be overridden in the specification of a particular node
|
||||
common_node_settings:
|
||||
name_servers: "10.20.0.2"
|
||||
profile: centos-x86_64
|
||||
|
||||
# These parameters can be overridden in the specification of a particular node
|
||||
common_power_info:
|
||||
power_type: ssh
|
||||
power_user: root
|
||||
power_pass: /root/.ssh/bootstrap.rsa
|
||||
netboot_enabled: 1
|
||||
|
||||
# These parameters can be overridden in the specification of a particular node
|
||||
common_ks_meta:
|
||||
mco_enable: 1
|
||||
mco_vhost: mcollective
|
||||
mco_pskey: unset
|
||||
mco_user: mcollective
|
||||
puppet_enable: 0
|
||||
install_log_2_syslog: 1
|
||||
mco_password: marionette
|
||||
puppet_auto_setup: 1
|
||||
puppet_master: fuel.domain.tld
|
||||
mco_auto_setup: 1
|
||||
auth_key: '""'
|
||||
puppet_version: 2.7.19
|
||||
mco_connector: rabbitmq
|
||||
mco_host: 10.20.0.2
|
||||
|
||||
# Nodes
|
||||
nodes:
|
||||
- name: controller-8
|
||||
hostname: controller-8.domain.tld
|
||||
|
||||
# Data for provision
|
||||
ks_meta:
|
||||
# ks_spaces: '"[{"type": "disk", "id": "disk/by-path/pci-0000:00:0d.0-scsi-0:0:0:0",
|
||||
# "volumes": [{"type": "boot", "size": 300}, {"mount": "/boot", "type": "raid",
|
||||
# "size": 200}, {"type": "lvm_meta", "name": "os", "size": 64}, {"size": 11264,
|
||||
# "type": "pv", "vg": "os"}, {"type": "lvm_meta", "name": "image", "size": 64},
|
||||
# {"size": 4492, "type": "pv", "vg": "image"}], "size": 16384}]"'
|
||||
ks_disks:
|
||||
# All size should be set in megabytes
|
||||
- type: "disk"
|
||||
id: "disk/by-path/pci-0000:00:0d.0-scsi-0:0:0:0"
|
||||
size: 16384
|
||||
volumes:
|
||||
- type: "boot"
|
||||
size: 300
|
||||
- type: "raid"
|
||||
mount: "/boot"
|
||||
size: 200
|
||||
- type: "lvm_meta"
|
||||
name: "os"
|
||||
size: 64
|
||||
- type: "pv"
|
||||
size: 11264
|
||||
vg: os
|
||||
- type: "pv"
|
||||
vg: "image"
|
||||
size: 4492
|
||||
- type: "vg"
|
||||
id: "os"
|
||||
min_size: 11264
|
||||
label: "Base System"
|
||||
volumes:
|
||||
- type: "lv"
|
||||
mount: "/"
|
||||
name: root
|
||||
size: 10048
|
||||
- type: "lv"
|
||||
mount: "/swap"
|
||||
name: swap
|
||||
size: 1024
|
||||
- type: "vg"
|
||||
id: "image"
|
||||
min_size: 4492
|
||||
label: "Image Storage"
|
||||
volumes:
|
||||
- type: "lv"
|
||||
mount: "/var/lib/glance"
|
||||
name: glance
|
||||
size: 4200
|
||||
|
||||
interfaces:
|
||||
- name: eth2
|
||||
ip_address: 10.20.0.187
|
||||
netmask: 255.255.255.0
|
||||
static: 0
|
||||
mac_address: '08:00:27:31:09:34'
|
||||
onboot: 'no'
|
||||
peerdns: 'no'
|
||||
- name: eth1
|
||||
ip_address: 10.20.0.186
|
||||
netmask: 255.255.255.0
|
||||
static: 0
|
||||
mac_address: 08:00:27:93:54:B0
|
||||
onboot: 'no'
|
||||
peerdns: 'no'
|
||||
- name: eth0
|
||||
#ip_address: 10.20.0.49 # ip, power_address
|
||||
#netmask: 255.255.255.0
|
||||
dns_name: controller-8.domain.tld # fqdn
|
||||
static: 1
|
||||
mac_address: 08:00:27:1D:28:71 # mac
|
||||
onboot: 'yes'
|
||||
peerdns: 'no'
|
||||
use_for_provision: true
|
||||
#End data for provision
|
|
@ -1,317 +0,0 @@
|
|||
# Copyright 2013 Mirantis, Inc.
|
||||
#
|
||||
# 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 'yaml'
|
||||
require 'rest-client'
|
||||
require 'astute/ext/hash'
|
||||
require 'astute/cli/enviroment'
|
||||
require 'astute/cli/yaml_validator'
|
||||
|
||||
module Astute
|
||||
module Cli
|
||||
|
||||
class Enviroment
|
||||
|
||||
POWER_INFO_KEYS = ['power_type', 'power_user', 'power_pass', 'netboot_enabled']
|
||||
ID_KEYS = ['id', 'uid']
|
||||
COMMON_NODE_KEYS = ['name_servers', 'profile']
|
||||
KS_META_KEYS = ['mco_enable', 'mco_vhost', 'mco_pskey', 'mco_user', 'puppet_enable',
|
||||
'install_log_2_syslog', 'mco_password', 'puppet_auto_setup', 'puppet_master',
|
||||
'mco_auto_setup', 'auth_key', 'puppet_version', 'mco_connector', 'mco_host']
|
||||
NETWORK_KEYS = ['ip', 'mac', 'fqdn']
|
||||
PROVISIONING_NET_KEYS = ['power_address']
|
||||
PROVISION_OPERATIONS = [:provision]
|
||||
|
||||
def initialize(file, operation)
|
||||
@config = YAML.load_file(file)
|
||||
validate_enviroment(operation)
|
||||
to_full_config(operation)
|
||||
end
|
||||
|
||||
def [](key)
|
||||
@config[key]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def to_full_config(operation)
|
||||
@config['nodes'].each do |node|
|
||||
|
||||
# Common section
|
||||
define_id_and_uid(node)
|
||||
|
||||
# Provision section
|
||||
if PROVISION_OPERATIONS.include? operation
|
||||
node['meta'] ||= {}
|
||||
define_network_ids(node)
|
||||
define_power_address(node)
|
||||
define_interfaces_and_interfaces_extra(node)
|
||||
define_ks_spaces(node)
|
||||
define_power_info(node)
|
||||
define_ks_meta(node)
|
||||
define_node_settings(node)
|
||||
define_disks_section(node)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def validate_enviroment(operation)
|
||||
validator = YamlValidator.new(operation)
|
||||
errors = validator.validate(@config)
|
||||
|
||||
errors.each do |e|
|
||||
if e.message.include?("is undefined")
|
||||
Astute.logger.warn "[#{e.path}] #{e.message}"
|
||||
else
|
||||
Astute.logger.error "[#{e.path}] #{e.message}"
|
||||
$stderr.puts "[#{e.path}] #{e.message}"
|
||||
end
|
||||
end
|
||||
|
||||
if errors.select {|e| !e.message.include?("is undefined") }.size > 0
|
||||
raise Enviroment::ValidationError, "Environment validation failed"
|
||||
end
|
||||
end
|
||||
|
||||
# Get data about discovered nodes using FuelWeb API
|
||||
def find_node_api_data(node)
|
||||
@api_data ||= begin
|
||||
response = RestClient.get 'http://localhost:8000/api/nodes'
|
||||
@api_data = JSON.parse(response).freeze
|
||||
end
|
||||
if node['mac']
|
||||
api_node = @api_data.find{ |n| n['mac'].upcase == node['mac'].upcase }
|
||||
return api_node if api_node
|
||||
end
|
||||
raise Enviroment::ValidationError, "Node #{node['name']} with mac address #{node['mac']}
|
||||
not find among discovered nodes"
|
||||
end
|
||||
|
||||
# Set uniq id and uid for node from Nailgun using FuelWeb API
|
||||
def define_id_and_uid(node)
|
||||
id = find_node_api_data(node)['id']
|
||||
|
||||
# This params set for node by Nailgun and should not be edit by user
|
||||
node.merge!(
|
||||
'id' => id,
|
||||
'uid' => id
|
||||
)
|
||||
end
|
||||
|
||||
# Set meta/disks section for node. This data used in provision to calculate the percentage
|
||||
# completion of the installation process.
|
||||
# Example result for node['meta']
|
||||
# "disks": [
|
||||
# {
|
||||
# "model": "VBOX HARDDISK",
|
||||
# "disk": "disk/by-path/pci-0000:00:0d.0-scsi-0:0:0:0",
|
||||
# "name": "sda",
|
||||
# "size": 17179869184
|
||||
# }...
|
||||
# ]
|
||||
def define_disks_section(node)
|
||||
node['meta']['disks'] = find_node_api_data(node)['meta']['disks']
|
||||
end
|
||||
|
||||
def define_parameters(node, config_group_name, keys, position=nil)
|
||||
position ||= node
|
||||
if @config[config_group_name]
|
||||
config_group = @config[config_group_name]
|
||||
keys.each do |key|
|
||||
position.reverse_merge!(key => config_group[key])
|
||||
end
|
||||
end
|
||||
|
||||
absent_keys = position.absent_keys(keys)
|
||||
if !absent_keys.empty?
|
||||
raise Enviroment::ValidationError, "Please set #{config_group_name} block or
|
||||
set params for #{node['name']} manually #{absent_keys.each {|k| p k}}"
|
||||
end
|
||||
@config.delete(config_group)
|
||||
end
|
||||
|
||||
# Add common params from common_node_settings to every node. Already certain parameters will not be changed.
|
||||
def define_node_settings(node)
|
||||
define_parameters(node, 'common_node_settings', COMMON_NODE_KEYS)
|
||||
end
|
||||
|
||||
# Add common params from common_power_info to every node. Already certain parameters will not be changed.
|
||||
def define_power_info(node)
|
||||
define_parameters(node, 'common_power_info', POWER_INFO_KEYS)
|
||||
end
|
||||
|
||||
# Add common params from common_ks_meta to every node. Already certain parameters will not be changed.
|
||||
def define_ks_meta(node)
|
||||
define_parameters(node, 'common_ks_meta', KS_META_KEYS, node['ks_meta'])
|
||||
end
|
||||
|
||||
# Add duplicates network params to node: ip, mac, fqdn
|
||||
def define_network_ids(node)
|
||||
network_eth = node['interfaces'].find {|eth| eth['use_for_provision'] } rescue nil
|
||||
|
||||
if network_eth
|
||||
if network_eth['ip_address'].blank?
|
||||
node['mac'] = network_eth['mac_address']
|
||||
api_node = find_node_api_data(node)
|
||||
api_provision_eth = api_node['meta']['interfaces'].find { |n| n['mac'].to_s.upcase == network_eth['mac_address'].to_s.upcase }
|
||||
network_eth['ip_address'] = api_provision_eth['ip']
|
||||
network_eth['netmask'] = api_provision_eth['netmask']
|
||||
end
|
||||
|
||||
node.reverse_merge!(
|
||||
'ip' => network_eth['ip_address'],
|
||||
'mac' => network_eth['mac_address'],
|
||||
'fqdn' => network_eth['dns_name']
|
||||
)
|
||||
network_eth.delete('use_for_provision')
|
||||
end
|
||||
|
||||
absent_keys = node.absent_keys(NETWORK_KEYS)
|
||||
if !absent_keys.empty?
|
||||
raise Enviroment::ValidationError, "Please set 'use_for_provision' parameter
|
||||
for #{node['name']} or set manually #{absent_keys.each {|k| p k}}"
|
||||
end
|
||||
end
|
||||
|
||||
# Add duplicates network params to node: power_address
|
||||
def define_power_address(node)
|
||||
node['power_address'] = node['ip'] or raise Enviroment::ValidationError, "Please
|
||||
set 'power_address' parameter for #{node['name']}"
|
||||
end
|
||||
|
||||
# Extend blocks interfaces and interfaces_extra to old formats:
|
||||
# interfaces:
|
||||
# eth0:
|
||||
# ip_address: 10.20.0.188
|
||||
# netmask: 255.255.255.0
|
||||
# dns_name: controller-22.domain.tld
|
||||
# static: '0'
|
||||
# mac_address: 08:00:27:C2:06:DE
|
||||
# interfaces_extra:
|
||||
# eth0:
|
||||
# onboot: 'yes'
|
||||
# peerdns: 'no'
|
||||
def define_interfaces_and_interfaces_extra(node)
|
||||
return if [node['interfaces'], node['extra_interfaces']].all? {|i| i.is_a?(Hash)}
|
||||
|
||||
formated_interfaces = {}
|
||||
interfaces_extra_interfaces = {}
|
||||
node['interfaces'].each do |eth|
|
||||
formated_interfaces[eth['name']] = eth
|
||||
formated_interfaces[eth['name']].delete('name')
|
||||
interfaces_extra_interfaces[eth['name']] = {
|
||||
'onboot' => eth['onboot'],
|
||||
'peerdns' => eth['onboot']
|
||||
}
|
||||
end
|
||||
node['interfaces'] = formated_interfaces
|
||||
node['extra_interfaces'] = interfaces_extra_interfaces
|
||||
end
|
||||
|
||||
# Add duplicate param 'fqdn' to node if it is not specified
|
||||
def define_fqdn(node)
|
||||
node['fqdn'] ||= find_node_api_data(node)['meta']['system']['fqdn']
|
||||
end
|
||||
|
||||
# Add meta/interfaces section for node:
|
||||
# meta:
|
||||
# interfaces:
|
||||
# - name: eth0
|
||||
# ip: 10.20.0.95
|
||||
# netmask: 255.255.255.0
|
||||
# mac: 08:00:27:C2:06:DE
|
||||
# max_speed: 100
|
||||
# current_speed: 100
|
||||
def define_meta_interfaces(node)
|
||||
node['meta']['interfaces'] = find_node_api_data(node)['meta']['interfaces']
|
||||
end
|
||||
|
||||
# Add network_data section for node:
|
||||
# network_data:
|
||||
# - dev: eth1
|
||||
# ip: 10.108.1.8
|
||||
# name: public
|
||||
# netmask: 255.255.255.0
|
||||
# - dev: eth0
|
||||
# ip: 10.108.0.8
|
||||
# name:
|
||||
# - management
|
||||
# - storage
|
||||
def define_network_data(node)
|
||||
return if node['network_data'].is_a?(Array) && !node['network_data'].empty?
|
||||
|
||||
node['network_data'] = []
|
||||
|
||||
# If define_interfaces_and_interfaces_extra was call or format of config is full
|
||||
if node['interfaces'].is_a?(Hash)
|
||||
node['interfaces'].each do |key, value|
|
||||
node['network_data'] << {
|
||||
'dev' => key,
|
||||
'ip' => value['ip_address'],
|
||||
'name' => value['network_name'],
|
||||
'netmask' => value['netmask']
|
||||
}
|
||||
end
|
||||
else
|
||||
node['interfaces'].each do |eth|
|
||||
node['network_data'] << {
|
||||
'dev' => eth['name'],
|
||||
'ip' => eth['ip_address'],
|
||||
'name' => eth['network_name'],
|
||||
'netmask' => eth['netmask']
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Generate 'ks_spaces' param from 'ks_disks' param in section 'ks_meta'
|
||||
# Example input for 'ks_disks' param:
|
||||
# [{
|
||||
# "type"=>"disk",
|
||||
# "id"=>"disk/by-path/pci-0000:00:0d.0-scsi-0:0:0:0",
|
||||
# "size"=>16384,
|
||||
# "volumes"=>[
|
||||
# {
|
||||
# "type"=>"boot",
|
||||
# "size"=>300
|
||||
# },
|
||||
# {
|
||||
# "type"=>"pv",
|
||||
# "size"=>16174,
|
||||
# "vg"=>"os"
|
||||
# }
|
||||
# ]
|
||||
# }]
|
||||
# Example result for 'ks_spaces' param: "[{"type": "disk", "id": "disk/by-path/pci-0000:00:0d.0-scsi-0:0:0:0", "volumes": [{"type": "boot", "size": 300}, {"mount": "/boot", "type": "raid", "size": 200}, {"type": "lvm_meta", "name": "os", "size": 64}, {"size": 11264, "type": "pv", "vg": "os"}, {"type": "lvm_meta", "name": "image", "size": 64}, {"size": 4492, "type": "pv", "vg": "image"}], "size": 16384}]"
|
||||
def define_ks_spaces(node)
|
||||
if node['ks_meta']['ks_spaces'].present?
|
||||
node['ks_meta'].delete('ks_disks')
|
||||
return
|
||||
end
|
||||
|
||||
if node['ks_meta']['ks_disks'].blank?
|
||||
raise Enviroment::ValidationError, "Please set 'ks_disks' or 'ks_spaces' parameter
|
||||
in section ks_meta for #{node['name']}"
|
||||
end
|
||||
|
||||
node['ks_meta']['ks_spaces'] = '"' + node['ks_meta']['ks_disks'].to_json.gsub("\"", "\\\"") + '"'
|
||||
node['ks_meta'].delete('ks_disks')
|
||||
end
|
||||
|
||||
end # class end
|
||||
|
||||
class Enviroment::ValidationError < StandardError; end
|
||||
|
||||
end # module Cli
|
||||
end
|
|
@ -1,263 +0,0 @@
|
|||
type: map
|
||||
mapping:
|
||||
"task_uuid":
|
||||
type: text
|
||||
"engine":
|
||||
type: map
|
||||
required: true
|
||||
desc: Cobbler engine credentials
|
||||
mapping:
|
||||
"url":
|
||||
type: text
|
||||
required: true
|
||||
"username":
|
||||
type: text
|
||||
required: true
|
||||
"password":
|
||||
type: text
|
||||
required: true
|
||||
"common_power_info":
|
||||
type: map
|
||||
mapping:
|
||||
"power_type":
|
||||
type: text
|
||||
required: true
|
||||
desc: Cobbler power-type. Consult cobbler documentation for available options.
|
||||
"power_user":
|
||||
type: text
|
||||
required: true
|
||||
desc: Username for cobbler to manage power of this machine
|
||||
"power_pass":
|
||||
type: text
|
||||
required: true
|
||||
desc: Password/credentials for cobbler to manage power of this machine
|
||||
"netboot_enabled":
|
||||
type: int
|
||||
required: true
|
||||
desc: Disable/enable netboot for this node.
|
||||
range: { min: 0, max: 1 }
|
||||
"common_node_settings":
|
||||
type: map
|
||||
mapping:
|
||||
"name_servers":
|
||||
type: text
|
||||
required: true
|
||||
"profile":
|
||||
type: text
|
||||
enum: ["centos-x86_64", "ubuntu_1204_x86_64", 'rhel-x86_64']
|
||||
desc: Cobbler profile for the node.
|
||||
"common_ks_meta":
|
||||
type: map
|
||||
mapping:
|
||||
"mco_enable":
|
||||
type: int
|
||||
range: { min: 0, max: 1 }
|
||||
required: true
|
||||
"mco_vhost":
|
||||
type: text
|
||||
required: true
|
||||
"mco_pskey":
|
||||
type: text
|
||||
required: true
|
||||
"mco_user":
|
||||
type: text
|
||||
required: true
|
||||
"mco_password":
|
||||
type: text
|
||||
required: true
|
||||
"puppet_enable":
|
||||
type: int
|
||||
range: { min: 0, max: 1 }
|
||||
required: true
|
||||
"puppet_auto_setup":
|
||||
type: int
|
||||
range: { min: 0, max: 1 }
|
||||
required: true
|
||||
"puppet_master":
|
||||
type: text
|
||||
required: true
|
||||
"mco_auto_setup":
|
||||
type: int
|
||||
range: { min: 0, max: 1 }
|
||||
required: true
|
||||
"auth_key":
|
||||
type: text
|
||||
required: true
|
||||
"puppet_version":
|
||||
type: text
|
||||
"install_log_2_syslog":
|
||||
type: int
|
||||
range: { min: 0, max: 1 }
|
||||
required: true
|
||||
"mco_connector":
|
||||
type: text
|
||||
required: true
|
||||
"mco_host":
|
||||
type: text
|
||||
required: true
|
||||
"nodes":
|
||||
type: seq
|
||||
required: true
|
||||
desc: Array of nodes
|
||||
sequence:
|
||||
- type: map
|
||||
mapping:
|
||||
"id":
|
||||
type: int
|
||||
unique: yes
|
||||
desc: MCollective node id in mcollective server.cfg
|
||||
"uid":
|
||||
type: int
|
||||
unique: yes
|
||||
desc: UID of the node for deployment engine. Should be equal to `id`
|
||||
"name":
|
||||
type: text
|
||||
required: true
|
||||
unique: yes
|
||||
desc: Name of the system in cobbler
|
||||
"hostname":
|
||||
type: text
|
||||
required: true
|
||||
"fqdn":
|
||||
type: text
|
||||
desc: Fully-qualified domain name of the node
|
||||
"profile":
|
||||
type: text
|
||||
enum: ["centos-x86_64", "ubuntu_1204_x86_64", 'rhel-x86_64']
|
||||
desc: Cobbler profile for the node.
|
||||
"ip":
|
||||
type: text
|
||||
"mac":
|
||||
type: text
|
||||
"power_address":
|
||||
type: text
|
||||
desc: IP address of the device managing the node power state
|
||||
"power_type":
|
||||
type: text
|
||||
desc: Cobbler power-type. Consult cobbler documentation for available options.
|
||||
"power_user":
|
||||
type: text
|
||||
desc: Username for cobbler to manage power of this machine
|
||||
"name_servers":
|
||||
type: text
|
||||
"power_pass":
|
||||
type: text
|
||||
desc: Password/credentials for cobbler to manage power of this machine
|
||||
"netboot_enabled":
|
||||
type: int
|
||||
range: { min: 0, max: 1 }
|
||||
desc: Disable/enable netboot for this node.
|
||||
"ks_meta":
|
||||
type: map
|
||||
required: true
|
||||
desc: Kickstart metadata used during provisioning
|
||||
mapping:
|
||||
"mco_enable":
|
||||
type: int
|
||||
range: { min: 0, max: 1 }
|
||||
"mco_vhost":
|
||||
type: text
|
||||
"mco_pskey":
|
||||
type: text
|
||||
"mco_user":
|
||||
type: text
|
||||
"mco_password":
|
||||
type: text
|
||||
"puppet_enable":
|
||||
type: int
|
||||
range: { min: 0, max: 1 }
|
||||
"puppet_auto_setup":
|
||||
type: int
|
||||
range: { min: 0, max: 1 }
|
||||
"puppet_master":
|
||||
type: text
|
||||
"mco_auto_setup":
|
||||
type: int
|
||||
range: { min: 0, max: 1 }
|
||||
"auth_key":
|
||||
type: text
|
||||
"puppet_version":
|
||||
type: text
|
||||
"install_log_2_syslog":
|
||||
type: int
|
||||
range: { min: 0, max: 1 }
|
||||
"mco_connector":
|
||||
type: text
|
||||
"mco_host":
|
||||
type: text
|
||||
"ks_spaces":
|
||||
type: text
|
||||
"ks_disks":
|
||||
type: seq
|
||||
sequence:
|
||||
- type: map
|
||||
required: true
|
||||
mapping:
|
||||
"type":
|
||||
type: str
|
||||
required: true
|
||||
enum: [disk, vg]
|
||||
"id":
|
||||
type: text
|
||||
required: true
|
||||
unique: yes
|
||||
"size":
|
||||
type: int
|
||||
"min_size":
|
||||
type: int
|
||||
"label":
|
||||
type: text
|
||||
"volumes":
|
||||
type: seq
|
||||
sequence:
|
||||
- type: map
|
||||
mapping:
|
||||
"type":
|
||||
type: text
|
||||
required: true
|
||||
enum: [lv, pv, partition, mbr, raid, lvm_meta, boot]
|
||||
"mount":
|
||||
type: text
|
||||
"size":
|
||||
type: int
|
||||
"vg":
|
||||
type: text
|
||||
"name":
|
||||
type: text
|
||||
"interfaces":
|
||||
type: seq
|
||||
required: true
|
||||
sequence:
|
||||
- type: map
|
||||
mapping:
|
||||
"name":
|
||||
type: text
|
||||
required: true
|
||||
unique: yes
|
||||
"ip_address":
|
||||
type: text
|
||||
unique: yes
|
||||
"netmask":
|
||||
type: text
|
||||
"dns_name":
|
||||
type: text
|
||||
unique: yes
|
||||
"static":
|
||||
type: int
|
||||
range: { min: 0, max: 1 }
|
||||
"mac_address":
|
||||
type: text
|
||||
required: true
|
||||
unique: yes
|
||||
"onboot":
|
||||
type: text
|
||||
required: true
|
||||
enum: ['yes', 'no']
|
||||
"peerdns":
|
||||
type: text
|
||||
required: true
|
||||
enum: ['yes', 'no']
|
||||
"use_for_provision":
|
||||
type: bool
|
||||
default: false
|
||||
name: use_for_provision
|
|
@ -1,40 +0,0 @@
|
|||
# Copyright 2013 Mirantis, Inc.
|
||||
#
|
||||
# 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 'kwalify'
|
||||
|
||||
module Astute
|
||||
module Cli
|
||||
class YamlValidator < Kwalify::Validator
|
||||
|
||||
def initialize(operation)
|
||||
[:provision].include?(operation) ? schemas = [operation] : raise("Incorrect scheme for validation")
|
||||
|
||||
schema_hashes = []
|
||||
schema_dir_path = File.expand_path(File.dirname(__FILE__))
|
||||
|
||||
schemas.each do |schema_name|
|
||||
schema_path = File.join(schema_dir_path, "#{schema_name}_schema.yaml")
|
||||
schema_hashes << YAML.load_file(schema_path)
|
||||
end
|
||||
|
||||
#p schema_hashes[0].recursive_merge!(schema_hashes[1])
|
||||
#FIXME: key 'hostname:' is undefined for provision_and_deploy. Why?
|
||||
@schema = schema_hashes.size == 1 ? schema_hashes.first : schema_hashes[0].deep_merge(schema_hashes[1])
|
||||
super(@schema)
|
||||
end
|
||||
|
||||
end # YamlValidator
|
||||
end # Cli
|
||||
end # Astute
|
Loading…
Reference in New Issue