co-authored-by: Alejandro Huertas <ahuertas@opennebula.io> co-authored-by: Juan Antonio <jescobar@opennebula.io> co-authored-by: Sergio Betanzos <sbetanzos@opennebula.io>
@ -597,6 +597,14 @@ private:
|
||||
/* NIC setup functions */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Writes EXTERNAL_PORT_RANGE and INTERNAL_PORT_RANGE to allocate Forward
|
||||
* ports to an address lease.
|
||||
* @param addr_index internal index for the lease
|
||||
* @param nic attribute of a VMTemplate
|
||||
*/
|
||||
void set_port_ranges(unsigned int addr_index, VectorAttribute * nic) const;
|
||||
|
||||
/**
|
||||
* Writes MAC address to the given NIC attribute
|
||||
* @param addr_index internal index for the lease
|
||||
@ -782,6 +790,16 @@ private:
|
||||
*/
|
||||
unsigned int ip6[4] = {0};
|
||||
|
||||
/**
|
||||
* Port range definition parameters. First port available in the range
|
||||
*/
|
||||
unsigned int port_start = 0;
|
||||
|
||||
/**
|
||||
* Port block size, each lease will have a block of port_size ports
|
||||
*/
|
||||
unsigned int port_size = 0;
|
||||
|
||||
/**
|
||||
* Security Group IDs for this Address Range
|
||||
*/
|
||||
|
27
install.sh
@ -296,6 +296,8 @@ LIB_DIRS="$LIB_LOCATION/ruby \
|
||||
$LIB_LOCATION/oneprovision/lib/terraform/providers \
|
||||
$LIB_LOCATION/oneprovision/lib/terraform/providers/templates \
|
||||
$LIB_LOCATION/oneprovision/lib/terraform/providers/templates/aws \
|
||||
$LIB_LOCATION/oneprovision/lib/terraform/providers/templates/google \
|
||||
$LIB_LOCATION/oneprovision/lib/terraform/providers/templates/digitalocean \
|
||||
$LIB_LOCATION/oneprovision/lib/terraform/providers/templates/packet \
|
||||
$LIB_LOCATION/oneprovision/lib/provision \
|
||||
$LIB_LOCATION/oneprovision/lib/provision_template \
|
||||
@ -453,6 +455,7 @@ VAR_DIRS="$VAR_LOCATION/remotes \
|
||||
$VAR_LOCATION/remotes/vnm/vcenter/post.d \
|
||||
$VAR_LOCATION/remotes/vnm/vcenter/clean.d \
|
||||
$VAR_LOCATION/remotes/vnm/elastic \
|
||||
$VAR_LOCATION/remotes/vnm/nodeport\
|
||||
$VAR_LOCATION/remotes/vnm/hooks/pre \
|
||||
$VAR_LOCATION/remotes/vnm/hooks/post \
|
||||
$VAR_LOCATION/remotes/vnm/hooks/clean \
|
||||
@ -720,6 +723,7 @@ INSTALL_FILES=(
|
||||
NETWORK_OVSWITCH_VXLAN_FILES:$VAR_LOCATION/remotes/vnm/ovswitch_vxlan
|
||||
NETWORK_VCENTER_FILES:$VAR_LOCATION/remotes/vnm/vcenter
|
||||
NETWORK_ELASTIC_FILES:$VAR_LOCATION/remotes/vnm/elastic
|
||||
NETWORK_NODEPORT_FILES:$VAR_LOCATION/remotes/vnm/nodeport
|
||||
EXAMPLE_SHARE_FILES:$SHARE_LOCATION/examples
|
||||
EXAMPLE_HOST_HOOKS_SHARE_FILES:$SHARE_LOCATION/examples/host_hooks
|
||||
LXD_NETWORK_HOOKS:$SHARE_LOCATION/examples/network_hooks
|
||||
@ -775,6 +779,8 @@ INSTALL_ONEPROVISION_FILES=(
|
||||
ONEPROVISION_LIB_TF_FILES:$LIB_LOCATION/oneprovision/lib/terraform
|
||||
ONEPROVISION_LIB_PROVIDERS_FILES:$LIB_LOCATION/oneprovision/lib/terraform/providers
|
||||
ONEPROVISION_LIB_AWS_ERB_FILES:$LIB_LOCATION/oneprovision/lib/terraform/providers/templates/aws
|
||||
ONEPROVISION_LIB_GOOGLE_ERB_FILES:$LIB_LOCATION/oneprovision/lib/terraform/providers/templates/google
|
||||
ONEPROVISION_LIB_DIGITALOCEAN_ERB_FILES:$LIB_LOCATION/oneprovision/lib/terraform/providers/templates/digitalocean
|
||||
ONEPROVISION_LIB_PACKET_ERB_FILES:$LIB_LOCATION/oneprovision/lib/terraform/providers/templates/packet
|
||||
ONEPROVISION_LIB_PROVISION_FILES:$LIB_LOCATION/oneprovision/lib/provision
|
||||
ONEPROVISION_LIB_RESOURCES_FILES:$LIB_LOCATION/oneprovision/lib/provision/resources
|
||||
@ -1740,6 +1746,12 @@ NETWORK_ELASTIC_FILES="src/vnm_mad/remotes/elastic/elastic.rb \
|
||||
src/vnm_mad/remotes/elastic/pre \
|
||||
src/vnm_mad/remotes/elastic/update_sg"
|
||||
|
||||
NETWORK_NODEPORT_FILES="src/vnm_mad/remotes/nodeport/nodeport.rb \
|
||||
src/vnm_mad/remotes/nodeport/clean \
|
||||
src/vnm_mad/remotes/nodeport/post \
|
||||
src/vnm_mad/remotes/nodeport/pre \
|
||||
src/vnm_mad/remotes/nodeport/update_sg"
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Virtual Network Manager drivers configuration to be installed under $REMOTES_LOCATION/etc/vnm
|
||||
#-------------------------------------------------------------------------------
|
||||
@ -1763,6 +1775,7 @@ IPAM_DRIVER_PACKET_SCRIPTS="src/ipamm_mad/remotes/packet/register_address_range
|
||||
src/ipamm_mad/remotes/packet/allocate_address \
|
||||
src/ipamm_mad/remotes/packet/get_address \
|
||||
src/ipamm_mad/remotes/packet/free_address"
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# IPAM EC2 drivers to be installed under $REMOTES_LOCATION/ipam
|
||||
#-------------------------------------------------------------------------------
|
||||
@ -2472,6 +2485,8 @@ ONEPROVISION_LIB_TF_FILES="src/oneprovision/lib/terraform/terraform.rb \
|
||||
src/oneprovision/lib/terraform/providers.rb"
|
||||
|
||||
ONEPROVISION_LIB_PROVIDERS_FILES="src/oneprovision/lib/terraform/providers/aws.rb \
|
||||
src/oneprovision/lib/terraform/providers/google.rb \
|
||||
src/oneprovision/lib/terraform/providers/digitalocean.rb \
|
||||
src/oneprovision/lib/terraform/providers/dummy.rb \
|
||||
src/oneprovision/lib/terraform/providers/packet.rb"
|
||||
|
||||
@ -2481,6 +2496,18 @@ ONEPROVISION_LIB_AWS_ERB_FILES="src/oneprovision/lib/terraform/providers/templat
|
||||
src/oneprovision/lib/terraform/providers/templates/aws/network.erb \
|
||||
src/oneprovision/lib/terraform/providers/templates/aws/provider.erb"
|
||||
|
||||
ONEPROVISION_LIB_GOOGLE_ERB_FILES="src/oneprovision/lib/terraform/providers/templates/google/cluster.erb \
|
||||
src/oneprovision/lib/terraform/providers/templates/google/datastore.erb \
|
||||
src/oneprovision/lib/terraform/providers/templates/google/host.erb \
|
||||
src/oneprovision/lib/terraform/providers/templates/google/network.erb \
|
||||
src/oneprovision/lib/terraform/providers/templates/google/provider.erb"
|
||||
|
||||
ONEPROVISION_LIB_DIGITALOCEAN_ERB_FILES="src/oneprovision/lib/terraform/providers/templates/digitalocean/cluster.erb \
|
||||
src/oneprovision/lib/terraform/providers/templates/digitalocean/datastore.erb \
|
||||
src/oneprovision/lib/terraform/providers/templates/digitalocean/host.erb \
|
||||
src/oneprovision/lib/terraform/providers/templates/digitalocean/network.erb \
|
||||
src/oneprovision/lib/terraform/providers/templates/digitalocean/provider.erb"
|
||||
|
||||
ONEPROVISION_LIB_PACKET_ERB_FILES="src/oneprovision/lib/terraform/providers/templates/packet/cluster.erb \
|
||||
src/oneprovision/lib/terraform/providers/templates/packet/datastore.erb \
|
||||
src/oneprovision/lib/terraform/providers/templates/packet/host.erb \
|
||||
|
@ -103,6 +103,8 @@
|
||||
<xs:element name="IP6_GLOBAL_END" type="xs:string" minOccurs="0"/>
|
||||
<xs:element name="IP6" type="xs:string" minOccurs="0"/>
|
||||
<xs:element name="IP6_END" type="xs:string" minOccurs="0"/>
|
||||
<xs:element name="PORT_START" type="xs:string" minOccurs="0"/>
|
||||
<xs:element name="PORT_SIZE" type="xs:string" minOccurs="0"/>
|
||||
<xs:element name="USED_LEASES" type="xs:string"/>
|
||||
<xs:element name="LEASES" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
|
@ -309,7 +309,6 @@ AllCops:
|
||||
- src/cli/one_helper/onequota_helper.rb
|
||||
- src/cli/one_helper/oneuser_helper.rb
|
||||
- src/cli/one_helper/onegroup_helper.rb
|
||||
- src/cli/one_helper/onevnet_helper.rb
|
||||
- src/cli/one_helper/onecluster_helper.rb
|
||||
- src/cli/one_helper/onevntemplate_helper.rb
|
||||
- src/cli/one_helper/onevrouter_helper.rb
|
||||
|
27
share/oneprovision/ansible/digitalocean.yml
Normal file
@ -0,0 +1,27 @@
|
||||
---
|
||||
|
||||
- hosts: all
|
||||
gather_facts: false
|
||||
roles:
|
||||
- python
|
||||
|
||||
- hosts: nodes
|
||||
roles:
|
||||
- ddc
|
||||
- opennebula-repository
|
||||
- { role: opennebula-node-kvm, when: oneprovision_hypervisor == 'kvm' or oneprovision_hypervisor == 'qemu' }
|
||||
- { role: opennebula-node-firecracker, when: oneprovision_hypervisor == 'firecracker' }
|
||||
- opennebula-ssh
|
||||
- role: iptables
|
||||
iptables_base_rules_services:
|
||||
- { protocol: 'tcp', port: 22 }
|
||||
# TCP/179 bgpd (TODO: only needed on Route Refector(s))
|
||||
- { protocol: 'tcp', port: 179 }
|
||||
# TCP/8742 default VXLAN port on Linux (UDP/4789 default IANA)
|
||||
- { protocol: 'udp', port: 8472 }
|
||||
- update-replica
|
||||
- role: frr
|
||||
frr_iface: 'eth1'
|
||||
# Use /20 for the internal management network address
|
||||
frr_prefix_length: 20
|
||||
|
29
share/oneprovision/ansible/google.yml
Normal file
@ -0,0 +1,29 @@
|
||||
---
|
||||
|
||||
- hosts: all
|
||||
gather_facts: false
|
||||
roles:
|
||||
- python
|
||||
|
||||
- hosts: nodes
|
||||
roles:
|
||||
- ddc
|
||||
- opennebula-repository
|
||||
- { role: opennebula-node-kvm, when: oneprovision_hypervisor == 'kvm' or oneprovision_hypervisor == 'qemu' }
|
||||
- { role: opennebula-node-firecracker, when: oneprovision_hypervisor == 'firecracker' }
|
||||
- { role: opennebula-node-lxc, when: oneprovision_hypervisor == 'lxc' }
|
||||
- opennebula-ssh
|
||||
- role: iptables
|
||||
iptables_base_rules_services:
|
||||
- { protocol: 'tcp', port: 22 }
|
||||
# TCP/179 bgpd (TODO: only needed on Route Refector(s))
|
||||
- { protocol: 'tcp', port: 179 }
|
||||
# TCP/8742 default VXLAN port on Linux (UDP/4789 default IANA)
|
||||
- { protocol: 'udp', port: 8472 }
|
||||
- update-replica
|
||||
- role: frr
|
||||
frr_iface: 'eth0'
|
||||
# Use /16 for the internal management network address
|
||||
frr_prefix_length: 16
|
||||
frr_zebra: true
|
||||
frr_ipcalc: true
|
@ -15,3 +15,11 @@ frr_as: 65000
|
||||
# Prefix length for the BGP network
|
||||
frr_prefix_length: 16
|
||||
|
||||
# Configure Zebra
|
||||
frr_zebra: false
|
||||
|
||||
# Install and configure with ipcalc
|
||||
frr_ipcalc: false
|
||||
|
||||
# Default netmask for ipcalc
|
||||
frr_net_mask: 20
|
||||
|
@ -24,6 +24,21 @@
|
||||
retries: 3
|
||||
delay: 10
|
||||
|
||||
- name: Install ipcalc
|
||||
package:
|
||||
name: ipcalc
|
||||
state: latest
|
||||
register: pkg_result
|
||||
until: pkg_result is succeeded
|
||||
retries: 3
|
||||
delay: 10
|
||||
when: frr_ipcalc == true
|
||||
|
||||
- name: Get network address
|
||||
shell: ipcalc -bn "{{ ansible_default_ipv4.network }}/{{ frr_net_mask }}" | grep NETWORK | cut -d '=' -f2
|
||||
register: frr_net
|
||||
when: frr_ipcalc == true
|
||||
|
||||
- name: Configure BGP (RR)
|
||||
template:
|
||||
src: bgpd_rr.conf.j2
|
||||
@ -36,6 +51,18 @@
|
||||
dest: /etc/frr/bgpd.conf
|
||||
when: not vars['ansible_' + frr_iface].ipv4.address in rr_servers
|
||||
|
||||
- name: Configure Zebra
|
||||
template:
|
||||
src: zebra.conf.j2
|
||||
dest: /etc/frr/zebra.conf
|
||||
when: frr_zebra == true
|
||||
|
||||
- name: Configure Staticd
|
||||
template:
|
||||
src: staticd.conf.j2
|
||||
dest: /etc/frr/staticd.conf
|
||||
when: frr_zebra == true
|
||||
|
||||
- name: Enable BGP daemon
|
||||
replace:
|
||||
path: /etc/frr/daemons
|
||||
|
@ -0,0 +1,2 @@
|
||||
hostname {{ ansible_nodename }}
|
||||
ip route {{ frr_net.stdout }}/{{ frr_net_mask }} {{ ansible_default_ipv4.gateway }}
|
@ -0,0 +1,2 @@
|
||||
hostname {{ ansible_nodename }}
|
||||
ip nht resolve-via-default
|
@ -0,0 +1,19 @@
|
||||
name: 'digitalocean-nyc3'
|
||||
|
||||
description: 'cluster on DigitalOcean in Amsterdam 3'
|
||||
provider: 'digitalocean'
|
||||
|
||||
plain:
|
||||
image: 'DIGITALOCEAN'
|
||||
location_key: 'region'
|
||||
provision_type: 'virtual'
|
||||
|
||||
connection:
|
||||
token: 'DigitalOcean token'
|
||||
region: 'ams3'
|
||||
|
||||
inputs:
|
||||
- name: 'digitalocean_droplet'
|
||||
type: 'list'
|
||||
options:
|
||||
- 'centos-7-x64'
|
@ -0,0 +1,19 @@
|
||||
name: 'digitalocean-nyc3'
|
||||
|
||||
description: 'cluster on DigitalOcean in London'
|
||||
provider: 'digitalocean'
|
||||
|
||||
plain:
|
||||
image: 'DIGITALOCEAN'
|
||||
location_key: 'region'
|
||||
provision_type: 'virtual'
|
||||
|
||||
connection:
|
||||
token: 'DigitalOcean token'
|
||||
region: 'lon1'
|
||||
|
||||
inputs:
|
||||
- name: 'digitalocean_droplet'
|
||||
type: 'list'
|
||||
options:
|
||||
- 'centos-7-x64'
|
@ -0,0 +1,19 @@
|
||||
name: 'digitalocean-nyc3'
|
||||
|
||||
description: 'cluster on DigitalOcean in New York 3'
|
||||
provider: 'digitalocean'
|
||||
|
||||
plain:
|
||||
image: 'DIGITALOCEAN'
|
||||
location_key: 'region'
|
||||
provision_type: 'virtual'
|
||||
|
||||
connection:
|
||||
token: 'DigitalOcean token'
|
||||
region: 'nyc3'
|
||||
|
||||
inputs:
|
||||
- name: 'digitalocean_droplet'
|
||||
type: 'list'
|
||||
options:
|
||||
- 'centos-7-x64'
|
@ -0,0 +1,19 @@
|
||||
name: 'digitalocean-nyc3'
|
||||
|
||||
description: 'cluster on DigitalOcean in San Franciso 3'
|
||||
provider: 'digitalocean'
|
||||
|
||||
plain:
|
||||
image: 'DIGITALOCEAN'
|
||||
location_key: 'region'
|
||||
provision_type: 'virtual'
|
||||
|
||||
connection:
|
||||
token: 'DigitalOcean token'
|
||||
region: 'sfo3'
|
||||
|
||||
inputs:
|
||||
- name: 'digitalocean_droplet'
|
||||
type: 'list'
|
||||
options:
|
||||
- 'centos-7-x64'
|
@ -0,0 +1,19 @@
|
||||
name: 'digitalocean-nyc3'
|
||||
|
||||
description: 'cluster on DigitalOcean in Singapore'
|
||||
provider: 'digitalocean'
|
||||
|
||||
plain:
|
||||
image: 'DIGITALOCEAN'
|
||||
location_key: 'region'
|
||||
provision_type: 'virtual'
|
||||
|
||||
connection:
|
||||
token: 'DigitalOcean token'
|
||||
region: 'sgp1'
|
||||
|
||||
inputs:
|
||||
- name: 'digitalocean_droplet'
|
||||
type: 'list'
|
||||
options:
|
||||
- 'centos-7-x64'
|
@ -0,0 +1,27 @@
|
||||
name: 'google-belgium'
|
||||
|
||||
description: 'Elastic cluster on Google in Belgium'
|
||||
provider: 'google'
|
||||
|
||||
plain:
|
||||
image: 'GOOGLE'
|
||||
location_key: 'zone'
|
||||
provision_type: 'virtual'
|
||||
|
||||
connection:
|
||||
credentials: 'JSON credentials file'
|
||||
project: 'Google Cloud Plataform project ID'
|
||||
region: 'europe-west1'
|
||||
zone: 'europe-west1-b'
|
||||
|
||||
inputs:
|
||||
- name: 'google_image'
|
||||
type: 'list'
|
||||
options:
|
||||
- 'centos-8-v20210316'
|
||||
- name: 'google_machine_type'
|
||||
type: 'list'
|
||||
options:
|
||||
- 'e2-standard-2'
|
||||
- 'e2-standard-4'
|
||||
- 'e2-standard-8'
|
@ -0,0 +1,27 @@
|
||||
name: 'google-london'
|
||||
|
||||
description: 'Elastic cluster on Google in London'
|
||||
provider: 'google'
|
||||
|
||||
plain:
|
||||
image: 'GOOGLE'
|
||||
location_key: 'zone'
|
||||
provision_type: 'virtual'
|
||||
|
||||
connection:
|
||||
credentials: 'JSON credentials file'
|
||||
project: 'Google Cloud Plataform project ID'
|
||||
region: 'europe-west2'
|
||||
zone: 'europe-west2-b'
|
||||
|
||||
inputs:
|
||||
- name: 'google_image'
|
||||
type: 'list'
|
||||
options:
|
||||
- 'centos-8-v20210316'
|
||||
- name: 'google_machine_type'
|
||||
type: 'list'
|
||||
options:
|
||||
- 'e2-standard-2'
|
||||
- 'e2-standard-4'
|
||||
- 'e2-standard-8'
|
@ -0,0 +1,27 @@
|
||||
name: 'google-moncks'
|
||||
|
||||
description: 'Elastic cluster on Google in Moncks'
|
||||
provider: 'google'
|
||||
|
||||
plain:
|
||||
image: 'GOOGLE'
|
||||
location_key: 'zone'
|
||||
provision_type: 'virtual'
|
||||
|
||||
connection:
|
||||
credentials: 'JSON credentials file'
|
||||
project: 'Google Cloud Plataform project ID'
|
||||
region: 'us-east1'
|
||||
zone: 'us-east1-b'
|
||||
|
||||
inputs:
|
||||
- name: 'google_image'
|
||||
type: 'list'
|
||||
options:
|
||||
- 'centos-8-v20210316'
|
||||
- name: 'google_machine_type'
|
||||
type: 'list'
|
||||
options:
|
||||
- 'e2-standard-2'
|
||||
- 'e2-standard-4'
|
||||
- 'e2-standard-8'
|
@ -0,0 +1,27 @@
|
||||
name: 'google-oregon'
|
||||
|
||||
description: 'Elastic cluster on Google in Oregon'
|
||||
provider: 'google'
|
||||
|
||||
plain:
|
||||
image: 'GOOGLE'
|
||||
location_key: 'zone'
|
||||
provision_type: 'virtual'
|
||||
|
||||
connection:
|
||||
credentials: 'JSON credentials file'
|
||||
project: 'Google Cloud Plataform project ID'
|
||||
region: 'us-west1'
|
||||
zone: 'us-west1-b'
|
||||
|
||||
inputs:
|
||||
- name: 'google_image'
|
||||
type: 'list'
|
||||
options:
|
||||
- 'centos-8-v20210316'
|
||||
- name: 'google_machine_type'
|
||||
type: 'list'
|
||||
options:
|
||||
- 'e2-standard-2'
|
||||
- 'e2-standard-4'
|
||||
- 'e2-standard-8'
|
@ -16,7 +16,7 @@
|
||||
# ---------------------------------------------------------------------------- #
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# hosts: Packet or AWS metal servers
|
||||
# hosts: AWS, Digital Ocean or Google servers
|
||||
# provision:
|
||||
# - count: Number of servers to create
|
||||
# - hostname: kvm-host1, kvm-host2 .... of the server
|
||||
|
@ -0,0 +1,39 @@
|
||||
---
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2021, 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. #
|
||||
# ---------------------------------------------------------------------------- #
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# datastores: Defines the storage area for the cluster using the SSH replication
|
||||
# drivers. It creates the following datastores, using Replica driver:
|
||||
# 1. Image datastore, ${cluster_name}-image
|
||||
# 2. System datastore, ${cluster_name}-system
|
||||
#
|
||||
# Configuration/Input attributes:
|
||||
# - replica_host: The host that will hold the cluster replicas and snapshots.
|
||||
#-------------------------------------------------------------------------------
|
||||
datastores:
|
||||
|
||||
- name: "${provision}-image"
|
||||
type: 'image_ds'
|
||||
ds_mad: 'fs'
|
||||
tm_mad: 'ssh'
|
||||
safe_dirs: "/var/tmp /tmp"
|
||||
|
||||
- name: "${provision}-system"
|
||||
type: 'system_ds'
|
||||
tm_mad: 'ssh'
|
||||
safe_dirs: "/var/tmp /tmp"
|
||||
replica_host: "use-first-host"
|
@ -0,0 +1,24 @@
|
||||
---
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2021, 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. #
|
||||
# ---------------------------------------------------------------------------- #
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# defaults: Common configuration attributes for provision objects
|
||||
#--------------------------------------------------------------------------------
|
||||
# configuration: Ansible role parameters.
|
||||
#--------------------------------------------------------------------------------
|
||||
# Check defaults/main.yml in each role for the available variables
|
||||
#-------------------------------------------------------------------------------
|
@ -0,0 +1,20 @@
|
||||
---
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2021, 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. #
|
||||
# ---------------------------------------------------------------------------- #
|
||||
|
||||
image: 'OPENNEBULA-DIGITALOCEAN'
|
||||
provider: 'digitalocean'
|
||||
provision_type: 'virtual'
|
@ -0,0 +1,45 @@
|
||||
---
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2021, 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. #
|
||||
# ---------------------------------------------------------------------------- #
|
||||
|
||||
inputs:
|
||||
- name: 'number_hosts'
|
||||
type: text
|
||||
description: "Number of metal servers to create"
|
||||
default: '1'
|
||||
|
||||
- name: 'number_public_ips'
|
||||
type: text
|
||||
description: 'Number of public IPs to get'
|
||||
default: '1'
|
||||
|
||||
- name: 'digitalocean_image'
|
||||
type: text
|
||||
description: "digitalocean host operating system"
|
||||
default: 'centos-8-x64'
|
||||
|
||||
- name: 'digitalocean_size'
|
||||
type: text
|
||||
description: "digitalocean host size"
|
||||
default: 's-1vcpu-1gb'
|
||||
|
||||
- name: 'one_hypervisor'
|
||||
type: list
|
||||
description: "Virtualization technology for the cluster hosts"
|
||||
options:
|
||||
- 'qemu'
|
||||
- 'lxc'
|
||||
...
|
@ -0,0 +1,40 @@
|
||||
---
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2021, 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. #
|
||||
# ---------------------------------------------------------------------------- #
|
||||
|
||||
networks:
|
||||
- name: "${provision}-public"
|
||||
vn_mad: 'nodeport'
|
||||
bridge: 'br0'
|
||||
netrole: 'public'
|
||||
ar:
|
||||
- type: 'IP4'
|
||||
ip: "192.168.23.2"
|
||||
size: 250
|
||||
port_start: 9000
|
||||
port_size: 100
|
||||
gateway: "192.168.23.1"
|
||||
|
||||
vntemplates:
|
||||
- name: "${provision}-private"
|
||||
vn_mad: 'vxlan'
|
||||
phydev: 'eth1'
|
||||
automatic_vlan_id: 'yes'
|
||||
netrole: 'private'
|
||||
vxlan_mode: 'evpn'
|
||||
vxlan_tep: 'dev'
|
||||
ip_link_conf: 'nolearning='
|
||||
cluster_ids: "${cluster.0.id}"
|
@ -0,0 +1,74 @@
|
||||
---
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2021, 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. #
|
||||
# ---------------------------------------------------------------------------- #
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# This is the canonical description file for a cluster build with 'digitalocean'
|
||||
# resources using the KVM hypervisor.
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
name: 'digitalocean-cluster'
|
||||
|
||||
extends:
|
||||
- common.d/defaults.yml
|
||||
- common.d/resources.yml
|
||||
- common.d/hosts.yml
|
||||
- digitalocean.d/datastores.yml
|
||||
- digitalocean.d/defaults.yml
|
||||
- digitalocean.d/fireedge.yml
|
||||
- digitalocean.d/inputs.yml
|
||||
- digitalocean.d/networks.yml
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# playbook: Ansible playbook used for hosts configuration.The digitalocean playbook
|
||||
# include the following roles:
|
||||
# - ddc
|
||||
# - opennebula-repository
|
||||
# - opennebula-node-kvm
|
||||
# - opennebula-ssh
|
||||
# - tuntap
|
||||
# - bridged-networking
|
||||
# - iptables
|
||||
#-------------------------------------------------------------------------------
|
||||
playbook:
|
||||
- digitalocean
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# defaults: Common configuration attributes for provision objects
|
||||
#--------------------------------------------------------------------------------
|
||||
defaults:
|
||||
provision:
|
||||
provider_name: 'digitalocean'
|
||||
image: "${input.digitalocean_image}"
|
||||
size: "${input.digitalocean_size}"
|
||||
connection:
|
||||
remote_user: 'install'
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# cluster: Parameters for the OpenNebula cluster. Applies to all the Hosts
|
||||
#--------------------------------------------------------------------------------
|
||||
# name: of the cluster
|
||||
# description: Additional information
|
||||
# reserved_cpu: In percentage. It will be subtracted from the TOTAL CPU
|
||||
# reserved_memory: In percentage. It will be subtracted from the TOTAL MEM
|
||||
#--------------------------------------------------------------------------------
|
||||
cluster:
|
||||
name: "${provision}"
|
||||
description: 'digitalocean cluster'
|
||||
datastores:
|
||||
- 1
|
||||
reserved_cpu: '0'
|
||||
reserved_mem: '0'
|
@ -0,0 +1,39 @@
|
||||
---
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2021, 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. #
|
||||
# ---------------------------------------------------------------------------- #
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# datastores: Defines the storage area for the cluster using the SSH replication
|
||||
# drivers. It creates the following datastores, using Replica driver:
|
||||
# 1. Image datastore, ${cluster_name}-image
|
||||
# 2. System datastore, ${cluster_name}-system
|
||||
#
|
||||
# Configuration/Input attributes:
|
||||
# - replica_host: The host that will hold the cluster replicas and snapshots.
|
||||
#-------------------------------------------------------------------------------
|
||||
datastores:
|
||||
|
||||
- name: "${provision}-image"
|
||||
type: 'image_ds'
|
||||
ds_mad: 'fs'
|
||||
tm_mad: 'ssh'
|
||||
safe_dirs: "/var/tmp /tmp"
|
||||
|
||||
- name: "${provision}-system"
|
||||
type: 'system_ds'
|
||||
tm_mad: 'ssh'
|
||||
safe_dirs: "/var/tmp /tmp"
|
||||
replica_host: "use-first-host"
|
@ -0,0 +1,20 @@
|
||||
---
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2021, 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. #
|
||||
# ---------------------------------------------------------------------------- #
|
||||
|
||||
image: 'OPENNEBULA-GOOGLE'
|
||||
provider: 'google'
|
||||
provision_type: 'virtual'
|
@ -0,0 +1,45 @@
|
||||
---
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2021, 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. #
|
||||
# ---------------------------------------------------------------------------- #
|
||||
|
||||
inputs:
|
||||
- name: 'number_hosts'
|
||||
type: text
|
||||
description: 'Number of Google instances to create'
|
||||
default: '1'
|
||||
|
||||
- name: 'number_public_ips'
|
||||
type: text
|
||||
description: 'Number of public IPs to get'
|
||||
default: '1'
|
||||
|
||||
- name: 'google_image'
|
||||
type: text
|
||||
description: "Google image used for host deployments"
|
||||
default: ''
|
||||
|
||||
- name: 'google_machine_type'
|
||||
type: text
|
||||
description: "Google instance type, use virtual instances"
|
||||
default: ''
|
||||
|
||||
- name: 'one_hypervisor'
|
||||
type: list
|
||||
description: "Virtualization technology for the cluster hosts"
|
||||
options:
|
||||
- 'qemu'
|
||||
- 'lxc'
|
||||
...
|
@ -0,0 +1,40 @@
|
||||
---
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2021, 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. #
|
||||
# ---------------------------------------------------------------------------- #
|
||||
|
||||
networks:
|
||||
- name: "${provision}-public"
|
||||
vn_mad: 'nodeport'
|
||||
bridge: 'br0'
|
||||
netrole: 'public'
|
||||
ar:
|
||||
- type: 'IP4'
|
||||
ip: "192.168.23.2"
|
||||
size: 250
|
||||
port_start: 9000
|
||||
port_size: 100
|
||||
gateway: "192.168.23.1"
|
||||
|
||||
vntemplates:
|
||||
- name: "${provision}-private"
|
||||
vn_mad: 'vxlan'
|
||||
phydev: 'eth0'
|
||||
automatic_vlan_id: 'yes'
|
||||
netrole: 'private'
|
||||
vxlan_mode: 'evpn'
|
||||
vxlan_tep: 'dev'
|
||||
ip_link_conf: 'nolearning='
|
||||
cluster_ids: "${cluster.0.id}"
|
@ -0,0 +1,67 @@
|
||||
---
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2021, 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. #
|
||||
# ---------------------------------------------------------------------------- #
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# This is the canonical description file for a cluster build with 'Google'
|
||||
# resources using the KVM hypervisor.
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
name: 'google-cluster'
|
||||
|
||||
extends:
|
||||
- common.d/defaults.yml
|
||||
- common.d/resources.yml
|
||||
- common.d/hosts.yml
|
||||
- google.d/datastores.yml
|
||||
- google.d/fireedge.yml
|
||||
- google.d/inputs.yml
|
||||
- google.d/networks.yml
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# playbook: Ansible playbook used for hosts configuration.
|
||||
# Check ansible/googl.yml for the specific roles applied.
|
||||
#-------------------------------------------------------------------------------
|
||||
playbook:
|
||||
- google
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# defaults: Common configuration attributes for provision objects
|
||||
#-------------------------------------------------------------------------------
|
||||
defaults:
|
||||
provision:
|
||||
provider_name: 'google'
|
||||
image: "${input.google_image}"
|
||||
machinetype: "${input.google_machine_type}"
|
||||
connection:
|
||||
remote_user: 'install'
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# cluster: Parameters for the OpenNebula cluster. Applies to all the Hosts
|
||||
#-------------------------------------------------------------------------------
|
||||
# name: of the cluster
|
||||
# description: Additional information
|
||||
# reserved_cpu: In percentage. It will be subtracted from the TOTAL CPU
|
||||
# reserved_memory: In percentage. It will be subtracted from the TOTAL MEM
|
||||
#-------------------------------------------------------------------------------
|
||||
cluster:
|
||||
name: "${provision}"
|
||||
description: 'Google virtual edge cluster'
|
||||
reserved_cpu: '0'
|
||||
reserved_mem: '0'
|
||||
datastores:
|
||||
- 1
|
||||
- 2
|
@ -723,7 +723,7 @@ _onevm() {
|
||||
rename snapshot-create snapshot-revert snapshot-delete disk-snapshot-create
|
||||
disk-snapshot-revert disk-snapshot-delete disk-snapshot-rename disk-resize
|
||||
list show top resize save updateconf lock unlock create-chart
|
||||
delete-chart update-chart backup restore"
|
||||
delete-chart update-chart backup restore ssh port-forward"
|
||||
cmd=onevm
|
||||
if [ "$COMP_CWORD" == 1 ]; then
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||
@ -735,7 +735,7 @@ _onevm() {
|
||||
unresched|rename|snapshot-create|snapshot-revert|snapshot-delete| \
|
||||
disk-snapshot-create|disk-snapshot-delete|disk-snapshot-revert| \
|
||||
disk-snapshot-rename|disk-resize|save|updateconf|lock|unlock|create-chart| \
|
||||
delete-chart|update-chart|backup|restore)
|
||||
delete-chart|update-chart|backup|restore|ssh|port-forward)
|
||||
_complete $cmd
|
||||
;;
|
||||
undeploy|poweroff|reboot|shutdown|suspend|stop|migrate)
|
||||
|
@ -1086,6 +1086,26 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
||||
end
|
||||
end
|
||||
|
||||
if vm_hash['VM']['TEMPLATE']['NIC']
|
||||
nic = [vm_hash['VM']['TEMPLATE']['NIC']]
|
||||
nic = nic.flatten
|
||||
nic = nic.select {|v| !v['EXTERNAL_PORT_RANGE'].nil? }[0]
|
||||
|
||||
if nic
|
||||
ip = vm_hash['VM']['HISTORY_RECORDS']['HISTORY']
|
||||
ip = [ip].flatten[-1]['HOSTNAME']
|
||||
port = Integer(nic['EXTERNAL_PORT_RANGE'].split(':')[0]) + 21
|
||||
|
||||
puts
|
||||
CLIHelper.print_header(str_h1 % 'PORT FORWARD', false)
|
||||
|
||||
puts "[#{nic['EXTERNAL_PORT_RANGE']}]:" \
|
||||
"[#{nic['INTERNAL_PORT_RANGE'].split('/')[0]}]"
|
||||
|
||||
puts "SSH on #{ip} at port #{port}"
|
||||
end
|
||||
end
|
||||
|
||||
if !options[:all]
|
||||
while vm.has_elements?('/VM/TEMPLATE/NIC')
|
||||
vm.delete_element('/VM/TEMPLATE/NIC')
|
||||
|
@ -16,174 +16,176 @@
|
||||
require 'one_helper'
|
||||
require 'one_helper/onevm_helper'
|
||||
|
||||
# OneVnet Command Helper
|
||||
class OneVNetHelper < OpenNebulaHelper::OneHelper
|
||||
|
||||
AR = {
|
||||
:name => "address_range",
|
||||
:short => "-a ar_id",
|
||||
:large => "--address_range ar_id",
|
||||
:name => 'address_range',
|
||||
:short => '-a ar_id',
|
||||
:large => '--address_range ar_id',
|
||||
:format => Integer,
|
||||
:description => "ID of the address range"
|
||||
:description => 'ID of the address range'
|
||||
}
|
||||
|
||||
SHOW_AR = {
|
||||
:name => "show_ar",
|
||||
:large => "--show-ar",
|
||||
:description => "Show also AR templates"
|
||||
:name => 'show_ar',
|
||||
:large => '--show-ar',
|
||||
:description => 'Show also AR templates'
|
||||
}
|
||||
|
||||
MAC = {
|
||||
:name => "mac",
|
||||
:short => "-m mac",
|
||||
:large => "--mac mac",
|
||||
:name => 'mac',
|
||||
:short => '-m mac',
|
||||
:large => '--mac mac',
|
||||
:format => String,
|
||||
:description => "First MAC address in : notation"
|
||||
:description => 'First MAC address in : notation'
|
||||
}
|
||||
|
||||
IP = {
|
||||
:name => "ip",
|
||||
:short => "-i ip",
|
||||
:large => "--ip ip",
|
||||
:name => 'ip',
|
||||
:short => '-i ip',
|
||||
:large => '--ip ip',
|
||||
:format => String,
|
||||
:description => "First IP address in . notation"
|
||||
:description => 'First IP address in . notation'
|
||||
}
|
||||
|
||||
IP6 = {
|
||||
:name => "ip6",
|
||||
:short => "-6 ip6",
|
||||
:large => "--ip6 ip6",
|
||||
:name => 'ip6',
|
||||
:short => '-6 ip6',
|
||||
:large => '--ip6 ip6',
|
||||
:format => String,
|
||||
:description => "First IPv6 address, in CIDR notation e.g. 2001::1/48"
|
||||
:description => 'First IPv6 address, in CIDR notation e.g. 2001::1/48'
|
||||
}
|
||||
|
||||
SIZE = {
|
||||
:name => "size",
|
||||
:short => "-s size",
|
||||
:large => "--size size",
|
||||
:name => 'size',
|
||||
:short => '-s size',
|
||||
:large => '--size size',
|
||||
:format => String,
|
||||
:description => "Number of addresses"
|
||||
:description => 'Number of addresses'
|
||||
}
|
||||
|
||||
IP6_GLOBAL = {
|
||||
:name => "ip6_global",
|
||||
:short => "-g ip6_pref",
|
||||
:large => "--ip6_global ip6_pref",
|
||||
:name => 'ip6_global',
|
||||
:short => '-g ip6_pref',
|
||||
:large => '--ip6_global ip6_pref',
|
||||
:format => String,
|
||||
:description => "IP6 global prefix"
|
||||
:description => 'IP6 global prefix'
|
||||
}
|
||||
|
||||
IP6_ULA = {
|
||||
:name => "ip6_ula",
|
||||
:short => "-u ip6_pref",
|
||||
:large => "--ip6_ula ip6_pref",
|
||||
:name => 'ip6_ula',
|
||||
:short => '-u ip6_pref',
|
||||
:large => '--ip6_ula ip6_pref',
|
||||
:format => String,
|
||||
:description => "IP6 ula prefix"
|
||||
:description => 'IP6 ula prefix'
|
||||
}
|
||||
|
||||
NAME = {
|
||||
:name => "name",
|
||||
:short => "-n reservation name",
|
||||
:large => "--name reservation name",
|
||||
:name => 'name',
|
||||
:short => '-n reservation name',
|
||||
:large => '--name reservation name',
|
||||
:format => String,
|
||||
:description => "Name of the address reservation"
|
||||
:description => 'Name of the address reservation'
|
||||
}
|
||||
|
||||
# R_SIZE = {
|
||||
# :name => "rsize",
|
||||
# :short => "-s reservation size",
|
||||
# :large => "--size reservation size",
|
||||
# :format => String,
|
||||
# :description => "Number of addresses to reserve"
|
||||
# }
|
||||
# R_SIZE = {
|
||||
# :name => "rsize",
|
||||
# :short => "-s reservation size",
|
||||
# :large => "--size reservation size",
|
||||
# :format => String,
|
||||
# :description => "Number of addresses to reserve"
|
||||
# }
|
||||
|
||||
GATEWAY = {
|
||||
:name => "gateway",
|
||||
:large => "--gateway ip",
|
||||
:name => 'gateway',
|
||||
:large => '--gateway ip',
|
||||
:format => String,
|
||||
:description=> "IP of the gateway"
|
||||
:description=> 'IP of the gateway'
|
||||
}
|
||||
|
||||
NETMASK = {
|
||||
:name => "netmask",
|
||||
:large => "--netmask mask",
|
||||
:name => 'netmask',
|
||||
:large => '--netmask mask',
|
||||
:format => String,
|
||||
:description=> "Netmask in dot notation"
|
||||
:description=> 'Netmask in dot notation'
|
||||
}
|
||||
|
||||
VN_MAD = {
|
||||
:name => "vn_mad",
|
||||
:large => "--vn_mad mad",
|
||||
:name => 'vn_mad',
|
||||
:large => '--vn_mad mad',
|
||||
:format => String,
|
||||
:description=> "Use this driver for the network"
|
||||
:description=> 'Use this driver for the network'
|
||||
}
|
||||
|
||||
VLAN_ID = {
|
||||
:name => "vlanid",
|
||||
:large => "--vlanid id",
|
||||
:name => 'vlanid',
|
||||
:large => '--vlanid id',
|
||||
:format => String,
|
||||
:description=> "VLAN ID assigned"
|
||||
:description=> 'VLAN ID assigned'
|
||||
}
|
||||
|
||||
ADDAR_OPTIONS = [
|
||||
SIZE, MAC, IP, IP6, IP6_GLOBAL, IP6_ULA, GATEWAY, NETMASK, VN_MAD,
|
||||
VLAN_ID ]
|
||||
VLAN_ID
|
||||
]
|
||||
|
||||
def self.rname
|
||||
"VNET"
|
||||
'VNET'
|
||||
end
|
||||
|
||||
def self.conf_file
|
||||
"onevnet.yaml"
|
||||
'onevnet.yaml'
|
||||
end
|
||||
|
||||
def format_pool(options)
|
||||
config_file = self.class.table_conf
|
||||
|
||||
table = CLIHelper::ShowTable.new(config_file, self) do
|
||||
column :ID, "ONE identifier for Virtual Network", :size=>4 do |d|
|
||||
d["ID"]
|
||||
CLIHelper::ShowTable.new(config_file, self) do
|
||||
column :ID, 'ONE identifier for Virtual Network', :size=>4 do |d|
|
||||
d['ID']
|
||||
end
|
||||
|
||||
column :USER, "Username of the Virtual Network owner", :left,
|
||||
column :USER, 'Username of the Virtual Network owner', :left,
|
||||
:size=>15 do |d|
|
||||
helper.user_name(d, options)
|
||||
end
|
||||
|
||||
column :GROUP, "Group of the Virtual Network", :left,
|
||||
column :GROUP, 'Group of the Virtual Network', :left,
|
||||
:size=>12 do |d|
|
||||
helper.group_name(d, options)
|
||||
end
|
||||
|
||||
column :NAME, "Name of the Virtual Network", :left,
|
||||
column :NAME, 'Name of the Virtual Network', :left,
|
||||
:size=>19 do |d|
|
||||
d["NAME"]
|
||||
d['NAME']
|
||||
end
|
||||
|
||||
column :CLUSTERS, "Cluster IDs", :left, :size=>10 do |d|
|
||||
OpenNebulaHelper.clusters_str(d["CLUSTERS"]["ID"]) rescue "-"
|
||||
column :CLUSTERS, 'Cluster IDs', :left, :size=>10 do |d|
|
||||
OpenNebulaHelper.clusters_str(d['CLUSTERS']['ID']) rescue '-'
|
||||
end
|
||||
|
||||
column :BRIDGE, "Bridge associated to the Virtual Network", :left,
|
||||
column :BRIDGE, 'Bridge associated to the Virtual Network', :left,
|
||||
:size=>8 do |d|
|
||||
d["BRIDGE"]
|
||||
d['BRIDGE']
|
||||
end
|
||||
|
||||
column :LEASES, "Number of this Virtual Network's given leases",
|
||||
:size=>6 do |d|
|
||||
d["USED_LEASES"]
|
||||
d['USED_LEASES']
|
||||
end
|
||||
|
||||
default :ID, :USER, :GROUP, :NAME, :CLUSTERS, :BRIDGE, :LEASES
|
||||
end
|
||||
|
||||
table
|
||||
end
|
||||
|
||||
def show_ar(vn, ar_id)
|
||||
CLIHelper.print_header("%-80s" % ["TEMPLATE FOR AR #{ar_id}"], false)
|
||||
CLIHelper.print_header(format('%-80s', "TEMPLATE FOR AR #{ar_id}"),
|
||||
false)
|
||||
|
||||
begin
|
||||
template = vn.template_like_str("AR_POOL/AR[AR_ID=#{ar_id}]")
|
||||
rescue
|
||||
rescue StandardError
|
||||
STDERR.puts "Can not get template for AR #{ar_id}"
|
||||
return
|
||||
end
|
||||
@ -281,7 +283,7 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper
|
||||
|
||||
private
|
||||
|
||||
def factory(id=nil)
|
||||
def factory(id = nil)
|
||||
if id
|
||||
OpenNebula::VirtualNetwork.new_with_id(id, @client)
|
||||
else
|
||||
@ -290,55 +292,63 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper
|
||||
end
|
||||
end
|
||||
|
||||
def factory_pool(user_flag=-2)
|
||||
def factory_pool(user_flag = -2)
|
||||
OpenNebula::VirtualNetworkPool.new(@client, user_flag)
|
||||
end
|
||||
|
||||
def format_resource(vn, options = {})
|
||||
vn_hash = vn.to_hash
|
||||
|
||||
str_h1="%-80s"
|
||||
CLIHelper.print_header(str_h1 %
|
||||
["VIRTUAL NETWORK #{vn.id.to_s} INFORMATION"])
|
||||
str_h1='%-80s'
|
||||
CLIHelper.print_header(format(str_h1,
|
||||
"VIRTUAL NETWORK #{vn.id} INFORMATION"))
|
||||
|
||||
str="%-25s: %-20s"
|
||||
puts str % ["ID", vn.id.to_s]
|
||||
puts str % ["NAME", vn['NAME']]
|
||||
puts str % ["USER", vn['UNAME']]
|
||||
puts str % ["GROUP", vn['GNAME']]
|
||||
puts str % ["LOCK", OpenNebulaHelper.level_lock_to_str(vn['LOCK/LOCKED'])]
|
||||
puts str % ["CLUSTERS",
|
||||
OpenNebulaHelper.clusters_str(vn.retrieve_elements("CLUSTERS/ID"))]
|
||||
puts str % ["BRIDGE", vn["BRIDGE"]]
|
||||
puts str % ["VN_MAD", vn['VN_MAD']] if !vn['VN_MAD'].empty?
|
||||
puts str % ["PHYSICAL DEVICE", vn["PHYDEV"]] if !vn["PHYDEV"].empty?
|
||||
puts str % ["VLAN ID", vn["VLAN_ID"]] if !vn["VLAN_ID"].empty?
|
||||
puts str % ["AUTOMATIC VLAN ID", vn["VLAN_ID_AUTOMATIC"]=="1" ? "YES" : "NO"]
|
||||
puts str % ["OUTER VLAN ID", vn["OUTER_VLAN_ID"]] if !vn["OUTER_VLAN_ID"]
|
||||
puts str % ["AUTOMATIC OUTER VLAN ID", vn["OUTER_VLAN_ID_AUTOMATIC"]=="1" ? "YES" : "NO"]
|
||||
puts str % ["USED LEASES", vn['USED_LEASES']]
|
||||
str='%-25s: %-20s'
|
||||
puts format(str, 'ID', vn.id.to_s)
|
||||
puts format(str, 'NAME', vn['NAME'])
|
||||
puts format(str, 'USER', vn['UNAME'])
|
||||
puts format(str, 'GROUP', vn['GNAME'])
|
||||
puts format(str, 'LOCK',
|
||||
OpenNebulaHelper.level_lock_to_str(vn['LOCK/LOCKED']))
|
||||
puts format(str, 'CLUSTERS',
|
||||
OpenNebulaHelper.clusters_str(
|
||||
vn.retrieve_elements('CLUSTERS/ID')
|
||||
))
|
||||
puts format(str, 'BRIDGE', vn['BRIDGE'])
|
||||
puts format(str, 'VN_MAD', vn['VN_MAD']) unless vn['VN_MAD'].empty?
|
||||
puts format(str, 'PHYSICAL DEVICE',
|
||||
vn['PHYDEV']) unless vn['PHYDEV'].empty?
|
||||
puts format(str, 'VLAN ID', vn['VLAN_ID']) unless vn['VLAN_ID'].empty?
|
||||
puts format(str, 'AUTOMATIC VLAN ID',
|
||||
vn['VLAN_ID_AUTOMATIC']=='1' ? 'YES' : 'NO')
|
||||
puts format(str, 'OUTER VLAN ID',
|
||||
vn['OUTER_VLAN_ID']) unless vn['OUTER_VLAN_ID']
|
||||
puts format(str, 'AUTOMATIC OUTER VLAN ID',
|
||||
vn['OUTER_VLAN_ID_AUTOMATIC']=='1' ? 'YES' : 'NO')
|
||||
puts format(str, 'USED LEASES', vn['USED_LEASES'])
|
||||
puts
|
||||
|
||||
CLIHelper.print_header(str_h1 % "PERMISSIONS",false)
|
||||
CLIHelper.print_header(str_h1 % 'PERMISSIONS', false)
|
||||
|
||||
["OWNER", "GROUP", "OTHER"].each { |e|
|
||||
mask = "---"
|
||||
mask[0] = "u" if vn["PERMISSIONS/#{e}_U"] == "1"
|
||||
mask[1] = "m" if vn["PERMISSIONS/#{e}_M"] == "1"
|
||||
mask[2] = "a" if vn["PERMISSIONS/#{e}_A"] == "1"
|
||||
%w[OWNER GROUP OTHER].each do |e|
|
||||
mask = '---'
|
||||
mask[0] = 'u' if vn["PERMISSIONS/#{e}_U"] == '1'
|
||||
mask[1] = 'm' if vn["PERMISSIONS/#{e}_M"] == '1'
|
||||
mask[2] = 'a' if vn["PERMISSIONS/#{e}_A"] == '1'
|
||||
|
||||
puts str % [e, mask]
|
||||
}
|
||||
puts format(str, e, mask)
|
||||
end
|
||||
|
||||
puts
|
||||
|
||||
CLIHelper.print_header(str_h1 % ["VIRTUAL NETWORK TEMPLATE"], false)
|
||||
CLIHelper.print_header(format(str_h1, 'VIRTUAL NETWORK TEMPLATE'),
|
||||
false)
|
||||
|
||||
puts vn.template_str(false)
|
||||
|
||||
puts
|
||||
|
||||
CLIHelper.print_header(str_h1 % ["ADDRESS RANGE POOL"], false)
|
||||
CLIHelper.print_header(format(str_h1, 'ADDRESS RANGE POOL'), false)
|
||||
|
||||
arlist = []
|
||||
|
||||
@ -347,70 +357,72 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper
|
||||
end
|
||||
|
||||
arlist.each do |ar|
|
||||
CLIHelper.print_header(format('%-80s', "AR #{ar['AR_ID']}"))
|
||||
|
||||
CLIHelper.print_header("%-80s" % "AR #{ar["AR_ID"]}")
|
||||
|
||||
str="%-15s: %-20s"
|
||||
puts str % ["SIZE", ar["SIZE"]]
|
||||
puts str % ["LEASES", ar["USED_LEASES"]]
|
||||
puts str % ["VN_MAD", ar["VN_MAD"]] if ar["VN_MAD"]
|
||||
puts str % ["IPAM_MAD", ar["IPAM_MAD"]] if ar["IPAM_MAD"]
|
||||
str='%-15s: %-20s'
|
||||
puts format(str, 'SIZE', ar['SIZE'])
|
||||
puts format(str, 'LEASES', ar['USED_LEASES'])
|
||||
puts format(str, 'VN_MAD', ar['VN_MAD']) if ar['VN_MAD']
|
||||
puts format(str, 'IPAM_MAD', ar['IPAM_MAD']) if ar['IPAM_MAD']
|
||||
puts
|
||||
|
||||
format = "%-10s %34s %34s"
|
||||
CLIHelper.print_header(format % ["RANGE", "FIRST", "LAST"], false)
|
||||
format = '%-10s %34s %34s'
|
||||
CLIHelper.print_header(
|
||||
format(format, 'RANGE', 'FIRST', 'LAST'), false
|
||||
)
|
||||
|
||||
puts format % ["MAC", ar["MAC"], ar["MAC_END"]]
|
||||
puts format(format, 'MAC', ar['MAC'], ar['MAC_END'])
|
||||
|
||||
if !ar["IP"].nil?
|
||||
puts format % ["IP", ar["IP"], ar["IP_END"]]
|
||||
if !ar['IP'].nil?
|
||||
puts format(format, 'IP', ar['IP'], ar['IP_END'])
|
||||
end
|
||||
|
||||
if !ar["IP6_GLOBAL"].nil?
|
||||
puts format % ["IP6_GLOBAL", ar["IP6_GLOBAL"], ar["IP6_GLOBAL_END"]]
|
||||
if !ar['IP6_GLOBAL'].nil?
|
||||
puts format(format, 'IP6_GLOBAL', ar['IP6_GLOBAL'],
|
||||
ar['IP6_GLOBAL_END'])
|
||||
end
|
||||
|
||||
if !ar["IP6_ULA"].nil?
|
||||
puts format % ["IP6_ULA", ar["IP6_ULA"], ar["IP6_ULA_END"]]
|
||||
if !ar['IP6_ULA'].nil?
|
||||
puts format(format, 'IP6_ULA', ar['IP6_ULA'], ar['IP6_ULA_END'])
|
||||
end
|
||||
|
||||
if !ar["IP6"].nil?
|
||||
puts format % ["IP6", ar["IP6"], ar["IP6_END"]]
|
||||
if !ar['IP6'].nil?
|
||||
puts format(format, 'IP6', ar['IP6'], ar['IP6_END'])
|
||||
end
|
||||
|
||||
puts
|
||||
end
|
||||
|
||||
puts
|
||||
CLIHelper.print_header(str_h1 % ["LEASES"], false)
|
||||
CLIHelper.print_header(format(str_h1, 'LEASES'), false)
|
||||
ar_list = []
|
||||
|
||||
if !vn_hash['VNET']['AR_POOL']['AR'].nil?
|
||||
lease_list = [vn_hash['VNET']['AR_POOL']['AR']].flatten
|
||||
leases = Array.new
|
||||
leases = []
|
||||
|
||||
lease_list.each do |ar|
|
||||
id = ar['AR_ID']
|
||||
ar_list << id
|
||||
|
||||
if ar['LEASES'] && !ar['LEASES']['LEASE'].nil?
|
||||
next unless ar['LEASES'] && !ar['LEASES']['LEASE'].nil?
|
||||
|
||||
lease = [ar['LEASES']['LEASE']].flatten
|
||||
lease.each do |l|
|
||||
l['AR_ID'] = id
|
||||
end
|
||||
leases << lease
|
||||
end
|
||||
end
|
||||
|
||||
leases.flatten!
|
||||
end
|
||||
|
||||
CLIHelper::ShowTable.new(nil, self) do
|
||||
column :AR, "", :left, :size=>3 do |d|
|
||||
column :AR, '', :left, :size=>3 do |d|
|
||||
d['AR_ID']
|
||||
end
|
||||
|
||||
column :OWNER, "", :left, :size=>15 do |d|
|
||||
column :OWNER, '', :left, :size=>10 do |d|
|
||||
if d['VM']
|
||||
"V:#{d['VM']}"
|
||||
elsif d['VNET']
|
||||
@ -420,33 +432,42 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper
|
||||
end
|
||||
end
|
||||
|
||||
column :MAC, "", :size=>17 do |d|
|
||||
d["MAC"]
|
||||
column :MAC, '', :adjust do |d|
|
||||
d['MAC']
|
||||
end
|
||||
|
||||
column :IP, "", :size=>15 do |d|
|
||||
d["IP"]||"-"
|
||||
column :IP, '', :adjust do |d|
|
||||
d['IP'] || '-'
|
||||
end
|
||||
|
||||
column :IP6, "", :adjust, :size=>26 do |d|
|
||||
d["IP6"]||d["IP6_GLOBAL"]||"-"
|
||||
column :PORT_FORWARD, '', :adjust do |d|
|
||||
if d['EXTERNAL_PORT_RANGE']
|
||||
"[#{d['EXTERNAL_PORT_RANGE']}]:" \
|
||||
"[#{d['INTERNAL_PORT_RANGE'].split('/')[0]}]"
|
||||
else
|
||||
'-'
|
||||
end
|
||||
end
|
||||
|
||||
column :IP6, '', :adjust do |d|
|
||||
d['IP6']||d['IP6_GLOBAL']||'-'
|
||||
end
|
||||
end.show(leases, {})
|
||||
|
||||
puts
|
||||
|
||||
CLIHelper.print_header("%-15s" % "VIRTUAL ROUTERS")
|
||||
CLIHelper.print_header(format('%-15s', 'VIRTUAL ROUTERS'))
|
||||
vn.vrouter_ids.each do |id|
|
||||
puts "%-15s" % [id]
|
||||
puts format('%-15s', id)
|
||||
end
|
||||
|
||||
if options[:show_ar]
|
||||
return unless options[:show_ar]
|
||||
|
||||
ar_list.each do |ar_id|
|
||||
puts
|
||||
show_ar(vn, ar_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.add_ar_options_used?(options)
|
||||
# Get the template options names as symbols. options hash
|
||||
@ -459,4 +480,5 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper
|
||||
# in options hash
|
||||
(add_ar_options-options.keys)!=add_ar_options
|
||||
end
|
||||
|
||||
end
|
||||
|
124
src/cli/onevm
@ -207,6 +207,20 @@ CommandParser::CmdParser.new(ARGV) do
|
||||
:description => 'Market to save oneshot'
|
||||
}
|
||||
|
||||
NIC_ID = {
|
||||
:name => 'nic_id',
|
||||
:large => '--nic-id nic_id',
|
||||
:format => String,
|
||||
:description => 'NIC to use when SSH'
|
||||
}
|
||||
|
||||
CMD = {
|
||||
:name => 'cmd',
|
||||
:large => '--cmd cmd',
|
||||
:format => String,
|
||||
:description => 'CMD to run when SSH'
|
||||
}
|
||||
|
||||
########################################################################
|
||||
# Global Options
|
||||
########################################################################
|
||||
@ -1526,6 +1540,116 @@ CommandParser::CmdParser.new(ARGV) do
|
||||
end
|
||||
end
|
||||
|
||||
ssh_desc = <<-EOT.unindent
|
||||
SSH into VM
|
||||
EOT
|
||||
|
||||
command :ssh, ssh_desc, :vmid, [:login, nil], :options => [NIC_ID, CMD] do
|
||||
helper.perform_action(args[0], options, 'SSH') do |vm|
|
||||
rc = vm.info
|
||||
|
||||
if OpenNebula.is_error?(rc)
|
||||
STDERR.puts rc.message
|
||||
exit(-1)
|
||||
end
|
||||
|
||||
# Get user to login
|
||||
args[1].nil? ? login = 'root' : login = args[1]
|
||||
|
||||
# Get CMD to run
|
||||
options[:cmd].nil? ? cmd = '' : cmd = options[:cmd]
|
||||
|
||||
# Get NIC to connect
|
||||
if options[:nic_id]
|
||||
nic = vm.retrieve_xmlelements(
|
||||
"//TEMPLATE/NIC[NIC_ID=\"#{options[:nic_id]}\"]"
|
||||
)[0]
|
||||
else
|
||||
nic = vm.retrieve_xmlelements('//TEMPLATE/NIC[SSH="YES"]')[0]
|
||||
end
|
||||
|
||||
nic = vm.retrieve_xmlelements('//TEMPLATE/NIC[1]')[0] if nic.nil?
|
||||
|
||||
if nic.nil?
|
||||
STDERR.puts 'No NIC found'
|
||||
exit(-1)
|
||||
end
|
||||
|
||||
# If there is node port
|
||||
if nic['EXTERNAL_PORT_RANGE']
|
||||
ip = vm.to_hash['VM']['HISTORY_RECORDS']['HISTORY']
|
||||
ip = [ip].flatten[-1]['HOSTNAME']
|
||||
port = Integer(nic['EXTERNAL_PORT_RANGE'].split(':')[0]) + 21
|
||||
else
|
||||
ip = nic['IP']
|
||||
port = 22
|
||||
end
|
||||
|
||||
system("ssh #{login}@#{ip} -p #{port} #{cmd}")
|
||||
end
|
||||
end
|
||||
|
||||
port_desc = <<-EOT.unindent
|
||||
Get port forwarding from a NIC, e.g:
|
||||
|
||||
1.2.3.4@4000 -> 1, means that to connect to VM port 1, you need to
|
||||
connect to IP 1.2.3.4 in port 4000
|
||||
EOT
|
||||
|
||||
command :'port-forward',
|
||||
port_desc,
|
||||
:vmid,
|
||||
[:port, nil],
|
||||
:options => NIC_ID do
|
||||
helper.perform_action(args[0], options, 'Port Forward') do |vm|
|
||||
rc = vm.info
|
||||
|
||||
if OpenNebula.is_error?(rc)
|
||||
STDERR.puts rc.message
|
||||
exit(-1)
|
||||
end
|
||||
|
||||
if options[:nic_id]
|
||||
nic = vm.retrieve_xmlelements(
|
||||
"//TEMPLATE/NIC[NIC_ID=\"#{options[:nic_id]}\"]"
|
||||
)[0]
|
||||
else
|
||||
nic = vm.retrieve_xmlelements('//TEMPLATE/NIC[SSH="YES"]')[0]
|
||||
end
|
||||
|
||||
nic = vm.retrieve_xmlelements('//TEMPLATE/NIC[1]')[0] if nic.nil?
|
||||
|
||||
if nic.nil?
|
||||
STDERR.puts 'No NIC found'
|
||||
exit(-1)
|
||||
end
|
||||
|
||||
if nic['EXTERNAL_PORT_RANGE'].nil?
|
||||
STDERR.puts 'No PORT_RANGE found'
|
||||
exit(-1)
|
||||
end
|
||||
|
||||
ip = vm.to_hash['VM']['HISTORY_RECORDS']['HISTORY'][-1]['HOSTNAME']
|
||||
|
||||
e_range = nic['EXTERNAL_PORT_RANGE'].split(':')
|
||||
e_start_p = Integer(e_range[0])
|
||||
e_end_p = Integer(e_range[1])
|
||||
|
||||
i_range = nic['INTERNAL_PORT_RANGE'].split('-')
|
||||
i_start_p = Integer(i_range[0])
|
||||
i_end_p = Integer(i_range[1].split('/')[0])
|
||||
|
||||
if args[1].nil?
|
||||
[*e_start_p..e_end_p].zip([*i_start_p..i_end_p]) do |p1, p2|
|
||||
puts "#{ip}@#{p1} -> #{p2}"
|
||||
end
|
||||
else
|
||||
puts "#{ip}@#{e_start_p + Integer(args[1]) - 1} -> #{args[1]}"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Deprecated commands
|
||||
|
||||
deprecated_command(:shutdown, 'terminate')
|
||||
|
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 7.9 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
@ -11,7 +11,7 @@ const useStateStyles = makeStyles(theme => ({
|
||||
content: "''",
|
||||
display: 'inline-flex',
|
||||
marginRight: '0.5rem',
|
||||
backgroundColor: ({ color }) => color,
|
||||
background: ({ color }) => color,
|
||||
height: '0.7rem',
|
||||
width: '0.7rem',
|
||||
borderRadius: '50%'
|
||||
|
@ -21,10 +21,10 @@ const TotalProviders = () => {
|
||||
const chartData = React.useMemo(() => {
|
||||
const groups = groupBy(providers, 'TEMPLATE.PLAIN.provider')
|
||||
|
||||
return PROVIDERS_TYPES?.map(({ name, color }) => ({
|
||||
return PROVIDERS_TYPES?.map(({ id, name, color }) => ({
|
||||
color,
|
||||
title: name,
|
||||
value: groups[name]?.length ?? 0
|
||||
value: groups[id]?.length ?? 0
|
||||
}))
|
||||
}, [totalProviders])
|
||||
|
||||
|
@ -47,10 +47,6 @@ export const LANGUAGES_URL = `${STATIC_FILES_URL}/languages`
|
||||
|
||||
export const ONEADMIN_ID = '0'
|
||||
|
||||
export const REQUEST_ACTIONS = {
|
||||
INSTANTIATE: 'instantiate'
|
||||
}
|
||||
|
||||
export const FILTER_POOL = {
|
||||
PRIMARY_GROUP_RESOURCES: '-4',
|
||||
USER_RESOURCES: '-3',
|
||||
|
@ -36,15 +36,28 @@ export const PROVISIONS_STATES = [
|
||||
|
||||
export const PROVIDERS_TYPES = [
|
||||
{
|
||||
name: 'aws',
|
||||
id: 'aws',
|
||||
name: 'AWS',
|
||||
color: '#ef931f'
|
||||
},
|
||||
{
|
||||
name: 'packet',
|
||||
id: 'packet',
|
||||
name: 'Packet',
|
||||
color: '#364562'
|
||||
},
|
||||
{
|
||||
name: 'dummy',
|
||||
id: 'dummy',
|
||||
name: 'Dummy',
|
||||
color: '#436637'
|
||||
},
|
||||
{
|
||||
id: 'google',
|
||||
name: 'Google Cloud',
|
||||
color: 'linear-gradient(90deg, #fbbc05 0%, #ea4335 33%, #34a853 66%, #4285f4 100%)'
|
||||
},
|
||||
{
|
||||
id: 'digitalocean',
|
||||
name: 'Digital Ocean',
|
||||
color: '#2381f5'
|
||||
}
|
||||
]
|
||||
|
@ -6,7 +6,7 @@ import {
|
||||
} from 'server/routes/api/oneflow/string-routes'
|
||||
|
||||
import { requestData } from 'client/utils'
|
||||
import { REQUEST_ACTIONS } from 'client/constants'
|
||||
|
||||
const { GET, POST, PUT } = httpMethod
|
||||
|
||||
export const getApplication = ({ id }) =>
|
||||
@ -77,7 +77,7 @@ export const instantiateTemplate = ({ id, data = {} }) =>
|
||||
requestData(`/api/${SERVICE_TEMPLATE}/action/${id}`, {
|
||||
data: {
|
||||
action: {
|
||||
perform: REQUEST_ACTIONS.INSTANTIATE,
|
||||
perform: 'instantiate',
|
||||
params: { merge_template: data }
|
||||
}
|
||||
},
|
||||
|
@ -30,7 +30,9 @@ export const UserInput = PropTypes.shape({
|
||||
export const ProviderType = PropTypes.oneOf([
|
||||
'aws',
|
||||
'packet',
|
||||
'dummy'
|
||||
'dummy',
|
||||
'google',
|
||||
'digitalocean'
|
||||
])
|
||||
|
||||
export const ProvisionType = PropTypes.oneOf([
|
||||
|
@ -24,6 +24,9 @@ module OneProvision
|
||||
# These attributes can not be changed when updating the provider
|
||||
IMMUTABLE_ATTRS = %w[provider name]
|
||||
|
||||
# These providers get the credentials via some file
|
||||
CREDENTIALS_FILE = { 'google' => 'credentials' }
|
||||
|
||||
# Allocates a new document
|
||||
#
|
||||
# @param template [Hash] Document information
|
||||
@ -181,6 +184,25 @@ module OneProvision
|
||||
document['connection'] = template['connection']
|
||||
document['registration_time'] = Time.now.to_i
|
||||
|
||||
if CREDENTIALS_FILE.keys.include?(template['provider'])
|
||||
c_key = CREDENTIALS_FILE[template['provider']]
|
||||
c_file = template['connection'][c_key]
|
||||
|
||||
if base64?(c_file)
|
||||
credentials = c_file
|
||||
else
|
||||
unless File.exist?(c_file)
|
||||
return OpenNebula::Error.new(
|
||||
"Credentials file doesn't exist"
|
||||
)
|
||||
end
|
||||
|
||||
credentials = Base64.strict_encode64(File.read(c_file))
|
||||
end
|
||||
|
||||
document['connection'][c_key] = credentials
|
||||
end
|
||||
|
||||
template.each do |key, value|
|
||||
next if skip.include?(key)
|
||||
|
||||
@ -190,6 +212,16 @@ module OneProvision
|
||||
document.to_json
|
||||
end
|
||||
|
||||
# Check if value is in Base64 form
|
||||
#
|
||||
# @param value [Object] Object to check
|
||||
#
|
||||
# @return [Boolean] True if it is in Base64, false otherwise
|
||||
def base64?(value)
|
||||
value.is_a?(String) &&
|
||||
Base64.strict_encode64(Base64.decode64(value)) == value
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -298,7 +298,7 @@ module OneProvision
|
||||
|
||||
check_rules
|
||||
|
||||
@config
|
||||
@config.sort.to_h
|
||||
end
|
||||
|
||||
########################################################################
|
||||
|
@ -15,7 +15,9 @@
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'terraform/providers/aws'
|
||||
require 'terraform/providers/digitalocean'
|
||||
require 'terraform/providers/dummy'
|
||||
require 'terraform/providers/google'
|
||||
require 'terraform/providers/packet'
|
||||
|
||||
# Module OneProvision
|
||||
|
@ -31,6 +31,7 @@ module OneProvision
|
||||
}
|
||||
|
||||
KEYS = %w[access_key secret_key region]
|
||||
|
||||
# Class constructor
|
||||
#
|
||||
# @param provider [Provider]
|
||||
@ -39,12 +40,30 @@ module OneProvision
|
||||
def initialize(provider, state, conf)
|
||||
@dir = "#{PROVIDERS_LOCATION}/templates/aws"
|
||||
|
||||
# User data should be encoded in base64
|
||||
@base64 = true
|
||||
# Credentials are not stored in a file
|
||||
@file_credentials = false
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
# Get user data to add into the VM
|
||||
#
|
||||
# @param ssh_key [String] SSH keys to add
|
||||
def user_data(ssh_key)
|
||||
# Add clod unit information into user_data
|
||||
# This only applies for a set of spported providers
|
||||
user_data = "#cloud-config\n"
|
||||
|
||||
user_data << "ssh_authorized_keys:\n"
|
||||
|
||||
ssh_key.split("\n").each {|key| user_data << "- #{key}\n" }
|
||||
|
||||
# Escape \n to avoid multilines in Terraform deploy file
|
||||
user_data.gsub!("\n", '\\n')
|
||||
|
||||
user_data
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
69
src/oneprovision/lib/terraform/providers/digitalocean.rb
Normal file
@ -0,0 +1,69 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2021, 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 'terraform/terraform'
|
||||
|
||||
# Module OneProvision
|
||||
module OneProvision
|
||||
|
||||
# DigitalOcean Terraform Provider
|
||||
class DigitalOcean < Terraform
|
||||
|
||||
# OpenNebula - Terraform equivalence
|
||||
TYPES = {
|
||||
:cluster => 'digitalocean_vpc',
|
||||
:datastore => 'digitalocean_volume',
|
||||
:host => 'digitalocean_droplet',
|
||||
:network => ''
|
||||
}
|
||||
|
||||
KEYS = %w[token region]
|
||||
|
||||
# Class constructor
|
||||
#
|
||||
# @param provider [Provider]
|
||||
# @param state [String] Terraform state in base64
|
||||
# @param conf [String] Terraform config state in base64
|
||||
def initialize(provider, state, conf)
|
||||
@dir = "#{PROVIDERS_LOCATION}/templates/digitalocean"
|
||||
|
||||
# Credentials are not stored in a file
|
||||
@file_credentials = false
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
# Get user data to add into the VM
|
||||
#
|
||||
# @param ssh_key [String] SSH keys to add
|
||||
def user_data(ssh_key)
|
||||
user_data = "#cloud-config\n"
|
||||
|
||||
user_data << "users:\n"
|
||||
user_data << " - name: install\n"
|
||||
user_data << " groups: sudo\n"
|
||||
user_data << " shell: /bin/bash\n"
|
||||
user_data << " sudo: ['ALL=(ALL) NOPASSWD:ALL']\n"
|
||||
user_data << " ssh_authorized_keys:\n"
|
||||
|
||||
ssh_key.split("\n").each {|key| user_data << " - #{key}\n" }
|
||||
|
||||
user_data = user_data.gsub("\n", '\\n')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
67
src/oneprovision/lib/terraform/providers/google.rb
Normal file
@ -0,0 +1,67 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2021, 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 'terraform/terraform'
|
||||
|
||||
# Module OneProvision
|
||||
module OneProvision
|
||||
|
||||
# Google Terraform Provider
|
||||
class Google < Terraform
|
||||
|
||||
# OpenNebula - Terraform equivalence
|
||||
TYPES = {
|
||||
:cluster => 'google_compute_network',
|
||||
:datastore => '',
|
||||
:host => 'google_compute_instance',
|
||||
:network => ''
|
||||
}
|
||||
|
||||
KEYS = %w[credentials project region zone]
|
||||
|
||||
# Class constructor
|
||||
#
|
||||
# @param provider [Provider]
|
||||
# @param state [String] Terraform state in base64
|
||||
# @param conf [String] Terraform config state in base64
|
||||
def initialize(provider, state, conf)
|
||||
@dir = "#{PROVIDERS_LOCATION}/templates/google"
|
||||
|
||||
# Credentials are stored in a file
|
||||
@file_credentials = true
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
# Get user data to add into the VM
|
||||
#
|
||||
# @param ssh_key [String] SSH keys to add
|
||||
def user_data(ssh_key)
|
||||
# Add clod unit information into user_data
|
||||
# This only applies for a set of spported providers
|
||||
user_data = "#cloud-config\n"
|
||||
|
||||
ssh_key.split("\n").each {|key| user_data << "install:#{key}\n" }
|
||||
|
||||
# Escape \n to avoid multilines in Terraform deploy file
|
||||
user_data.gsub!("\n", '\\n')
|
||||
|
||||
user_data
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
@ -39,12 +39,27 @@ module OneProvision
|
||||
def initialize(provider, state, conf)
|
||||
@dir = "#{PROVIDERS_LOCATION}/templates/packet"
|
||||
|
||||
# User data is in plain text
|
||||
@base64 = false
|
||||
# Credentials are not stored in a file
|
||||
@file_credentials = false
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
# Get user data to add into the VM
|
||||
#
|
||||
# @param ssh_key [String] SSH keys to add
|
||||
def user_data(ssh_key)
|
||||
# Add clod unit information into user_data
|
||||
# This only applies for a set of spported providers
|
||||
user_data = "#cloud-config\n"
|
||||
|
||||
user_data << "ssh_authorized_keys:\n"
|
||||
|
||||
ssh_key.split("\n").each {|key| user_data << "- #{key}\n" }
|
||||
|
||||
Base64.strict_encode64(user_data)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -0,0 +1,5 @@
|
||||
resource "digitalocean_vpc" "device_<%= obj['ID'] %>" {
|
||||
name = "vpc-digitalocean-<%= provision['REGION'] %>"
|
||||
region = "<%= provision['REGION'] %>"
|
||||
ip_range = "10.10.10.0/24"
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
resource "digitalocean_droplet" "device_<%= obj['ID'] %>" {
|
||||
image = "<%= provision['IMAGE'] %>"
|
||||
name = "<%= provision['HOSTNAME'] %>"
|
||||
region = "<%= provision['REGION'] %>"
|
||||
size = "<%= provision['SIZE'] %>"
|
||||
user_data = "<%= obj['user_data'] %>"
|
||||
vpc_uuid = digitalocean_vpc.device_<%= c['ID'] %>.id
|
||||
}
|
||||
|
||||
resource "digitalocean_firewall" "device_<%= obj['ID'] %>" {
|
||||
name = "vnc-device-<%= obj['ID'] %>"
|
||||
|
||||
droplet_ids = [digitalocean_droplet.device_<%= obj['ID'] %>.id]
|
||||
|
||||
inbound_rule {
|
||||
protocol = "tcp"
|
||||
port_range = "22"
|
||||
source_addresses = ["0.0.0.0/0", "::/0"]
|
||||
}
|
||||
|
||||
# BGP traffic from VPC droplets. IP range MUST be consistent with cluster.erb
|
||||
inbound_rule {
|
||||
protocol = "tcp"
|
||||
port_range = "179"
|
||||
source_addresses = ["10.10.10.0/24"]
|
||||
}
|
||||
|
||||
# VXLAN traffic from VPC droplets. IP range MUST be consistent with cluster.erb
|
||||
inbound_rule {
|
||||
protocol = "udp"
|
||||
port_range = "8472"
|
||||
source_addresses = ["10.10.10.0/24"]
|
||||
}
|
||||
|
||||
# Client Ports for VMs. Port range MUST be consistent with VNET definition
|
||||
inbound_rule {
|
||||
protocol = "tcp"
|
||||
port_range = "9000-65535"
|
||||
source_addresses = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
outbound_rule {
|
||||
protocol = "tcp"
|
||||
port_range = "1-65535"
|
||||
destination_addresses = ["0.0.0.0/0", "::/0"]
|
||||
}
|
||||
|
||||
outbound_rule {
|
||||
protocol = "udp"
|
||||
port_range = "1-65535"
|
||||
destination_addresses = ["0.0.0.0/0", "::/0"]
|
||||
}
|
||||
|
||||
outbound_rule {
|
||||
protocol = "icmp"
|
||||
destination_addresses = ["0.0.0.0/0", "::/0"]
|
||||
}
|
||||
}
|
||||
|
||||
output "ip_<%= obj['ID'] %>" {
|
||||
value = digitalocean_droplet.device_<%= obj['ID'] %>.ipv4_address
|
||||
}
|
||||
|
||||
output "device_id_<%= obj['ID'] %>" {
|
||||
value = digitalocean_droplet.device_<%= obj['ID'] %>.id
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
digitalocean = {
|
||||
source = "digitalocean/digitalocean"
|
||||
}
|
||||
}
|
||||
required_version = ">= 0.13"
|
||||
}
|
||||
|
||||
provider "digitalocean" {
|
||||
token = "<%= conn['TOKEN'] %>"
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
resource "google_compute_network" "device_<%= obj['ID'] %>" {
|
||||
name = "<%= obj['NAME'] %>-vpc"
|
||||
}
|
||||
|
||||
resource "google_compute_firewall" "device_<%= obj['ID'] %>" {
|
||||
name = "<%= obj['NAME'] %>-firewall"
|
||||
network = google_compute_network.device_<%= obj['ID'] %>.name
|
||||
|
||||
allow {
|
||||
protocol = "icmp"
|
||||
}
|
||||
|
||||
# Client Ports for VMs. Port range MUST be consistent with VNET definition
|
||||
allow {
|
||||
protocol = "tcp"
|
||||
ports = ["22", "179", "5900-6000", "9000-65535"]
|
||||
}
|
||||
|
||||
allow {
|
||||
protocol = "udp"
|
||||
ports = ["8472"]
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
resource "google_compute_instance" "device_<%= obj['ID'] %>" {
|
||||
name = "<%= provision['HOSTNAME'] %>"
|
||||
machine_type = "<%= provision['MACHINETYPE'] %>"
|
||||
|
||||
boot_disk {
|
||||
initialize_params {
|
||||
image = "<%= provision['IMAGE'] %>"
|
||||
}
|
||||
}
|
||||
|
||||
network_interface {
|
||||
network = google_compute_network.device_<%= c['ID'] %>.name
|
||||
|
||||
access_config {
|
||||
// Ephemeral IP
|
||||
}
|
||||
}
|
||||
|
||||
metadata = {
|
||||
ssh-keys = "<%= obj['user_data'] %>"
|
||||
}
|
||||
}
|
||||
|
||||
output "ip_<%= obj['ID'] %>" {
|
||||
value = google_compute_instance.device_<%= obj['ID'] %>.network_interface[0].access_config[0].nat_ip
|
||||
}
|
||||
|
||||
output "device_id_<%= obj['ID'] %>" {
|
||||
value = google_compute_instance.device_<%= obj['ID'] %>.id
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
provider "google" {
|
||||
credentials = "credentials.json"
|
||||
project = "<%= conn['PROJECT'] %>"
|
||||
region = "<%= conn['REGION'] %>"
|
||||
zone = "<%= conn['ZONE'] %>"
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ module OneProvision
|
||||
class Terraform
|
||||
|
||||
# Providers that are currently available
|
||||
PROVIDERS = %w[aws packet dummy]
|
||||
PROVIDERS = %w[aws digitalocean google packet dummy]
|
||||
|
||||
# Class constructor
|
||||
#
|
||||
@ -71,6 +71,10 @@ module OneProvision
|
||||
tf_class = Packet
|
||||
when 'aws'
|
||||
tf_class = AWS
|
||||
when 'google'
|
||||
tf_class = Google
|
||||
when 'digitalocean'
|
||||
tf_class = DigitalOcean
|
||||
when 'dummy'
|
||||
tf_class = Dummy
|
||||
else
|
||||
@ -91,6 +95,10 @@ module OneProvision
|
||||
keys = Packet::KEYS
|
||||
when 'aws'
|
||||
keys = AWS::KEYS
|
||||
when 'google'
|
||||
keys = Google::KEYS
|
||||
when 'digitalocean'
|
||||
keys = DigitalOcean::KEYS
|
||||
when 'dummy'
|
||||
return true
|
||||
else
|
||||
@ -146,6 +154,15 @@ module OneProvision
|
||||
def deploy(provision)
|
||||
tempdir = init(provision, false, false)
|
||||
|
||||
if @file_credentials
|
||||
c_key = Provider::CREDENTIALS_FILE[@provider.type]
|
||||
credentials = @provider.connection[c_key.upcase]
|
||||
|
||||
File.open("#{tempdir}/credentials.json", 'w') do |file|
|
||||
file.write(Base64.decode64(credentials))
|
||||
end
|
||||
end
|
||||
|
||||
# Apply
|
||||
Driver.retry_loop("Driver action 'tf deploy' failed", provision) do
|
||||
_, e, s = Driver.run(
|
||||
@ -182,7 +199,11 @@ module OneProvision
|
||||
|
||||
info.gsub!(' ', '')
|
||||
info = info.split("\n")
|
||||
info.map! {|ip| ip.split('=')[1] }
|
||||
info.map! {|val| val.split('=')[1] }
|
||||
|
||||
# rubocop:disable Style/StringLiterals
|
||||
info.map! {|val| val.gsub("\"", '') }
|
||||
# rubocop:enable Style/StringLiterals
|
||||
|
||||
# rubocop:disable Style/StringLiterals
|
||||
info.map! {|val| val.gsub("\"", '') }
|
||||
@ -225,6 +246,15 @@ module OneProvision
|
||||
def destroy(provision, target = nil)
|
||||
tempdir = init(provision)
|
||||
|
||||
if @file_credentials
|
||||
c_key = Provider::CREDENTIALS_FILE[@provider.type]
|
||||
credentials = @provider.connection[c_key.upcase]
|
||||
|
||||
File.open("#{tempdir}/credentials.json", 'w') do |file|
|
||||
file.write(Base64.decode64(credentials))
|
||||
end
|
||||
end
|
||||
|
||||
# Destroy
|
||||
Driver.retry_loop("Driver action 'tf destroy' failed", provision) do
|
||||
_, e, s = Driver.run(
|
||||
@ -300,22 +330,7 @@ module OneProvision
|
||||
|
||||
return if !ssh_key || ssh_key.empty?
|
||||
|
||||
# Add clod unit information into user_data
|
||||
# This only applies for a set of spported providers
|
||||
user_data = "#cloud-config\n"
|
||||
|
||||
user_data << "ssh_authorized_keys:\n"
|
||||
|
||||
ssh_key.split("\n").each {|key| user_data << "- #{key}\n" }
|
||||
|
||||
if @base64
|
||||
user_data = Base64.strict_encode64(user_data)
|
||||
else
|
||||
# Escape \n to avoid multilines in Terraform deploy file
|
||||
user_data = user_data.gsub("\n", '\\n')
|
||||
end
|
||||
|
||||
obj['user_data'] = user_data
|
||||
obj['user_data'] = user_data(ssh_key)
|
||||
end
|
||||
end
|
||||
|
||||
@ -425,8 +440,10 @@ module OneProvision
|
||||
|
||||
if version < Gem::Version.new('0.13')
|
||||
cmd = '0.12upgrade'
|
||||
else
|
||||
elsif version < Gem::Version.new('0.15')
|
||||
cmd = '0.13upgrade'
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
# Upgrade
|
||||
|
@ -161,6 +161,8 @@ void OpenNebulaTemplate::set_multiple_conf_default()
|
||||
#vcenter
|
||||
#ovswitch_vxlan
|
||||
#bridge
|
||||
#elastic
|
||||
#nodeport
|
||||
#******
|
||||
*/
|
||||
|
||||
@ -173,6 +175,8 @@ void OpenNebulaTemplate::set_multiple_conf_default()
|
||||
set_conf_vn("vcenter", "vcenter_port_groups");
|
||||
set_conf_vn("ovswitch_vxlan", "openvswitch");
|
||||
set_conf_vn("bridge", "linux");
|
||||
set_conf_vn("elastic", "linux");
|
||||
set_conf_vn("nodeport", "linux");
|
||||
|
||||
register_multiple_conf_default("VN_MAD_CONF");
|
||||
}
|
||||
|
@ -255,6 +255,18 @@ int AddressRange::from_attr(VectorAttribute *vattr, string& error_msg)
|
||||
one_util::split_unique(value, ',', security_groups);
|
||||
}
|
||||
|
||||
/* ---------------------- Port Range Allocation ------------------------- */
|
||||
|
||||
if ( vattr->vector_value("PORT_START", port_start) == -1 )
|
||||
{
|
||||
port_start = 0;
|
||||
}
|
||||
|
||||
if ( vattr->vector_value("PORT_SIZE", port_size) == -1 )
|
||||
{
|
||||
port_size = 0;
|
||||
}
|
||||
|
||||
/* ------------------------ AR Internal Data ---------------------------- */
|
||||
|
||||
vattr->replace("AR_ID", id);
|
||||
@ -358,6 +370,7 @@ int AddressRange::update_attributes(
|
||||
if (keep_restricted && restricted_set)
|
||||
{
|
||||
VectorAttribute va_aux(*attr);
|
||||
|
||||
remove_all_except_restricted(&va_aux);
|
||||
|
||||
vup->merge(&va_aux, true);
|
||||
@ -434,6 +447,18 @@ int AddressRange::update_attributes(
|
||||
one_util::split_unique(value, ',', security_groups);
|
||||
}
|
||||
|
||||
if ( vup->vector_value("PORT_START", port_start) == -1 )
|
||||
{
|
||||
vup->remove("PORT_START");
|
||||
port_start = 0;
|
||||
}
|
||||
|
||||
if ( vup->vector_value("PORT_SIZE", port_size) == -1 )
|
||||
{
|
||||
vup->remove("PORT_SIZE");
|
||||
port_size = 0;
|
||||
}
|
||||
|
||||
/* Replace with the new attributes */
|
||||
|
||||
attr->replace(vup->value());
|
||||
@ -485,6 +510,16 @@ int AddressRange::from_vattr_db(VectorAttribute *vattr)
|
||||
one_util::split_unique(value, ',', security_groups);
|
||||
}
|
||||
|
||||
if ( vattr->vector_value("PORT_START", port_start) == -1 )
|
||||
{
|
||||
port_start = 0;
|
||||
}
|
||||
|
||||
if ( vattr->vector_value("PORT_SIZE", port_size) == -1 )
|
||||
{
|
||||
port_size = 0;
|
||||
}
|
||||
|
||||
if (type == NONE)
|
||||
{
|
||||
rc = -1;
|
||||
@ -772,6 +807,8 @@ void AddressRange::to_xml(ostringstream &oss, const vector<int>& vms,
|
||||
|
||||
set_mac(it->first, &lease);
|
||||
|
||||
set_port_ranges(it->first, &lease);
|
||||
|
||||
if (is_ipv4())
|
||||
{
|
||||
set_ip(it->first, &lease);
|
||||
@ -1152,6 +1189,30 @@ bool AddressRange::is_valid_ip6(unsigned int& index, const string& ip_s,
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void AddressRange::set_port_ranges(unsigned int addr_index,
|
||||
VectorAttribute * nic) const
|
||||
{
|
||||
if ( port_size == 0 || port_start == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int p_ini = port_start + (addr_index * port_size) + 1;
|
||||
unsigned int p_end = p_ini + port_size - 1;
|
||||
|
||||
ostringstream erange;
|
||||
ostringstream irange;
|
||||
|
||||
erange << p_ini << ":" << p_end;
|
||||
irange << "1-" << port_size << "/" << p_ini;
|
||||
|
||||
nic->replace("EXTERNAL_PORT_RANGE", erange.str());
|
||||
nic->replace("INTERNAL_PORT_RANGE", irange.str());
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void AddressRange::set_mac(unsigned int addr_index, VectorAttribute * nic) const
|
||||
{
|
||||
unsigned int new_mac[2];
|
||||
@ -1368,6 +1429,8 @@ void AddressRange::allocate_by_index(unsigned int index,
|
||||
{
|
||||
set_mac(index, nic);
|
||||
|
||||
set_port_ranges(index, nic);
|
||||
|
||||
if (is_ipv4())
|
||||
{
|
||||
set_ip(index, nic);
|
||||
@ -1827,6 +1890,8 @@ int AddressRange::reserve_addr(int vid, unsigned int rsize, AddressRange *rar)
|
||||
|
||||
set_mac(first_index, new_ar);
|
||||
|
||||
set_port_ranges(first_index, new_ar);
|
||||
|
||||
if ( is_ipv4() )
|
||||
{
|
||||
set_ip(first_index, new_ar);
|
||||
@ -1884,6 +1949,8 @@ int AddressRange::reserve_addr_by_index(int vid, unsigned int rsize,
|
||||
|
||||
set_mac(sindex, new_ar);
|
||||
|
||||
set_port_ranges(sindex, new_ar);
|
||||
|
||||
if ( is_ipv4() )
|
||||
{
|
||||
set_ip(sindex, new_ar);
|
||||
|
40
src/vnm_mad/remotes/nodeport/clean
Executable file
@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2021, 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
$LOAD_PATH << File.dirname(__FILE__)
|
||||
$LOAD_PATH << File.join(File.dirname(__FILE__), '..')
|
||||
|
||||
require 'nodeport'
|
||||
|
||||
template64 = STDIN.read
|
||||
deploy_id = nil
|
||||
xpath_filter = NodePortDriver::XPATH_FILTER
|
||||
|
||||
begin
|
||||
drv = NodePortDriver.new(template64)
|
||||
drv.deactivate
|
||||
|
||||
filter_driver = VNMMAD::VNMDriver.filter_driver(template64,
|
||||
xpath_filter,
|
||||
deploy_id)
|
||||
filter_driver.deactivate
|
||||
rescue Exception => e
|
||||
OpenNebula.log_error(e.message)
|
||||
OpenNebula.log_error(e.backtrace)
|
||||
exit 1
|
||||
end
|
3
src/vnm_mad/remotes/nodeport/clean.d/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
# Do not track files in this directory except for .gitignore file
|
||||
*
|
||||
!.gitignore
|
127
src/vnm_mad/remotes/nodeport/nodeport.rb
Normal file
@ -0,0 +1,127 @@
|
||||
# rubocop:disable Naming/FileName
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2021, 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 'vnmmad'
|
||||
|
||||
# Node Port Forwarding Driver
|
||||
class NodePortDriver < VNMMAD::VNMDriver
|
||||
|
||||
# Driver name
|
||||
DRIVER = 'nodeport'
|
||||
|
||||
# Filter to look for NICs managed by this diver
|
||||
XPATH_FILTER = "TEMPLATE/NIC[VN_MAD='nodeport']"
|
||||
|
||||
# Class constructor
|
||||
def initialize(vm)
|
||||
@locking = true
|
||||
|
||||
super(Base64.decode64(vm), XPATH_FILTER, nil)
|
||||
end
|
||||
|
||||
# Adds the following elements:
|
||||
#
|
||||
# - Route to the bridge
|
||||
# - ARP proxy
|
||||
# - PREROUTING rule
|
||||
# - POSTROUTING rule
|
||||
def activate
|
||||
cmds = VNMMAD::VNMNetwork::Commands.new
|
||||
|
||||
attach_nic_id = @vm['TEMPLATE/NIC[ATTACH="YES"]/NIC_ID']
|
||||
attach_nic_id ||= @vm['TEMPLATE/NIC_ALIAS[ATTACH="YES"]/NIC_ID']
|
||||
|
||||
rc = process do |nic|
|
||||
next if attach_nic_id && attach_nic_id != nic[:nic_id]
|
||||
|
||||
unless check_nic(nic)
|
||||
OpenNebula.log_error('NIC information is wrong')
|
||||
break false
|
||||
end
|
||||
|
||||
cmds.add :ip, "route add #{nic[:ip]}/32 dev #{nic[:bridge]}"
|
||||
cmds.add :ip,
|
||||
"neighbour add proxy #{nic[:gateway]} " \
|
||||
"dev #{nic[:bridge]}"
|
||||
cmds.add :iptables, '-t nat -I PREROUTING -p tcp --dport ' \
|
||||
"#{nic[:external_port_range]} -j DNAT --to " \
|
||||
"#{nic[:ip]}:#{nic[:internal_port_range]}"
|
||||
cmds.add :iptables, '-t nat -A POSTROUTING -j MASQUERADE ' \
|
||||
"-s #{nic[:ip]}"
|
||||
end
|
||||
|
||||
if rc != false
|
||||
cmds.run!
|
||||
|
||||
0
|
||||
else
|
||||
-1
|
||||
end
|
||||
end
|
||||
|
||||
# Deletes the following elements:
|
||||
#
|
||||
# - Route to the bridge
|
||||
# - ARP proxy
|
||||
# - PREROUTING rule
|
||||
# - POSTROUTING rule
|
||||
def deactivate
|
||||
cmds = VNMMAD::VNMNetwork::Commands.new
|
||||
|
||||
attach_nic_id = @vm['TEMPLATE/NIC[ATTACH="YES"]/NIC_ID']
|
||||
attach_nic_id ||= @vm['TEMPLATE/NIC_ALIAS[ATTACH="YES"]/NIC_ID']
|
||||
|
||||
rc = process do |nic|
|
||||
next if attach_nic_id && attach_nic_id != nic[:nic_id]
|
||||
|
||||
unless check_nic(nic)
|
||||
OpenNebula.log_error('NIC information is wrong')
|
||||
break false
|
||||
end
|
||||
|
||||
cmds.add :ip,
|
||||
"route del #{nic[:ip]}/32 dev #{nic[:bridge]} | true"
|
||||
cmds.add :ip,
|
||||
"neighbour del proxy #{nic[:gateway]} dev " \
|
||||
"#{nic[:bridge]} | true"
|
||||
cmds.add :iptables, '-t nat -D PREROUTING -p tcp --dport ' \
|
||||
"#{nic[:external_port_range]} -j DNAT --to " \
|
||||
"#{nic[:ip]}:#{nic[:internal_port_range]}"
|
||||
cmds.add :iptables, '-t nat -D POSTROUTING -j MASQUERADE ' \
|
||||
"-s #{nic[:ip]}"
|
||||
end
|
||||
|
||||
if rc != false
|
||||
cmds.run!
|
||||
|
||||
0
|
||||
else
|
||||
-1
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Check if nic has all the port range information
|
||||
#
|
||||
# @param nic[Hash] NIC information
|
||||
def check_nic(nic)
|
||||
!nic[:external_port_range].nil? && !nic[:internal_port_range].nil?
|
||||
end
|
||||
|
||||
end
|
||||
# rubocop:enable Naming/FileName
|
38
src/vnm_mad/remotes/nodeport/post
Executable file
@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2021, 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
$LOAD_PATH << File.dirname(__FILE__)
|
||||
$LOAD_PATH << File.join(File.dirname(__FILE__), '..')
|
||||
|
||||
require 'nodeport'
|
||||
|
||||
template64 = STDIN.read
|
||||
deploy_id = ARGV[0]
|
||||
xpath_filter = NodePortDriver::XPATH_FILTER
|
||||
|
||||
begin
|
||||
drv = NodePortDriver.new(template64)
|
||||
filter_driver = VNMMAD::VNMDriver.filter_driver(template64,
|
||||
xpath_filter,
|
||||
deploy_id)
|
||||
filter_driver.activate(true) if drv.activate == 0
|
||||
rescue Exception => e
|
||||
OpenNebula.log_error(e.message)
|
||||
OpenNebula.log_error(e.backtrace)
|
||||
exit 1
|
||||
end
|
3
src/vnm_mad/remotes/nodeport/post.d/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
# Do not track files in this directory except for .gitignore file
|
||||
*
|
||||
!.gitignore
|
29
src/vnm_mad/remotes/nodeport/pre
Executable file
@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2021, 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
$LOAD_PATH << File.dirname(__FILE__)
|
||||
$LOAD_PATH << File.join(File.dirname(__FILE__), '..')
|
||||
|
||||
require 'vnmmad'
|
||||
|
||||
template64 = STDIN.read
|
||||
deploy_id = ARGV[0]
|
||||
xpath_filter = "TEMPLATE/NIC[VN_MAD='nodeport']"
|
||||
|
||||
drv = VNMMAD::NoVLANDriver.from_base64(template64, xpath_filter, deploy_id)
|
||||
exit drv.run_hooks(ARGV, template64) if drv.activate == 0
|
3
src/vnm_mad/remotes/nodeport/pre.d/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
# Do not track files in this directory except for .gitignore file
|
||||
*
|
||||
!.gitignore
|
38
src/vnm_mad/remotes/nodeport/update_sg
Executable file
@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2021, 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
$: << File.dirname(__FILE__)
|
||||
$: << File.join(File.dirname(__FILE__), "..")
|
||||
|
||||
require 'vnmmad'
|
||||
|
||||
template64 = STDIN.read
|
||||
deploy_id = ARGV[0]
|
||||
xpath_filter = "TEMPLATE/NIC[VN_MAD='nodeport']"
|
||||
|
||||
begin
|
||||
filter_driver = VNMMAD::VNMDriver.filter_driver(template64,
|
||||
xpath_filter,
|
||||
deploy_id,
|
||||
false)
|
||||
filter_driver.activate(true)
|
||||
rescue Exception => e
|
||||
OpenNebula.log_error(e.message)
|
||||
OpenNebula.log_error(e.backtrace)
|
||||
exit 1
|
||||
end
|