diff --git a/attributes/default.rb b/attributes/default.rb index 4b43674f..897ad091 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -175,7 +175,8 @@ default['openstack']['network']['interface_driver'] = 'neutron.agent.linux.inter default['openstack']['network']['core_plugin_map'] = { 'ovsneutronpluginv2' => 'openvswitch', 'linuxbridgepluginv2' => 'linuxbridge', - 'ml2plugin' => 'ml2' + 'ml2plugin' => 'ml2', + 'nuageplugin' => 'nuage' } # This is used by SUSE to setup the sysconfig neutron initfile @@ -1010,6 +1011,52 @@ default['openstack']['network']['ryu']['firewall_driver'] = 'neutron.agent.linux # Agent's polling interval in seconds default['openstack']['network']['ryu']['polling_interval'] = 2 +# ============================= Nuage Networks Configuration =============== + +# ----------------------------- Nuage VRS configuration -------------------- + +# VRS Active Controller (Active VSC IP Address) +default['openstack']['network']['nuage']['active_controller'] = nil + +# VRS Standby Controller (Stanby VSC IP Address) +default['openstack']['network']['nuage']['standby_controller'] = nil + +# ----------------------------- Nuage Metadata configuration --------------- + +# METADATA_PORT: TCP Port used by Nuage metadata agent +default['openstack']['network']['nuage']['metadata_port'] = '9697' + +# NOVA_CLIENT_VERSION +default['openstack']['network']['nuage']['nova_client_version'] = '2' + +# NUAGE_METADATA_AGENT_START_WITH_OVS: if nuage-metadata-agent needs to be started with nuage-openvswitch-switch +default['openstack']['network']['nuage']['metadata_start_with_vrs'] = 'true' + +# NOVA_API_ENDPOINT_TYPE: one of publicURL, internalURL, adminURL +default['openstack']['network']['nuage']['nova_api_endpoint_type'] = 'internalURL' + +# ----------------------------- Nuage Networks plugin configuration -------- + +# Desired Name of VSD Organization/Enterprise to use +default['openstack']['network']['nuage']['default_net_partition_name'] = 'OpenStack_default' + +# Hostname or IP address and port for connection to VSD server (eg. 10.0.0.10:8443) +default['openstack']['network']['nuage']['server'] = nil + +# VSD Username and password for OpenStack plugin connection +# User must belong to CSP CMS group +default['openstack']['network']['nuage']['serverauth']['username'] = nil +default['openstack']['network']['nuage']['serverauth']['password'] = nil + +# CMS ID generated by Nuage VSD +default['openstack']['network']['nuage']['cms_id'] = nil + +# Default configuration for standard installs +default['openstack']['network']['nuage']['organization'] = 'csp' +default['openstack']['network']['nuage']['auth_resource'] = '/me' +default['openstack']['network']['nuage']['serverssl'] = 'True' +default['openstack']['network']['nuage']['base_uri'] = '/nuage/api/v3_2' + # ============================= ML2 Plugin Configuration =================== # (ListOpt) List of network type driver entrypoints to be loaded from # the neutron.ml2.type_drivers namespace. @@ -1113,6 +1160,8 @@ when 'fedora', 'rhel' # :pragma-foodcritic: ~FC024 - won't fix this 'neutron_server_service' => 'neutron-server', # TODO: networking-hperv has not been included in Fedora or RHEL distribution, need be created by users. 'neutron_hyperv_packages' => ['networking-hyperv'], + 'compute_nuage_packages' => ['nuage-metadata-agent', 'nuage-openvswitch'], + 'neutron_server_nuage_packages' => ['nuage-openstack-neutron', 'nuage-openstack-neutronclient', 'nuagenetlib'], 'package_overrides' => '' } when 'suse' @@ -1148,6 +1197,8 @@ when 'suse' 'neutron_server_service' => 'openstack-neutron', # TODO: networking-hperv has not been included in SUSE distribution, need be created by users. 'neutron_hyperv_packages' => ['networking-hyperv'], + 'compute_nuage_packages' => [], + 'neutron_server_nuage_packages' => [], 'package_overrides' => '' } when 'debian' @@ -1182,6 +1233,8 @@ when 'debian' 'neutron_server_service' => 'neutron-server', # TODO: networking-hperv has not been included in DEBIAN distribution, need be created by users. 'neutron_hyperv_packages' => ['networking-hyperv'], + 'compute_nuage_packages' => ['nuage-metadata-agent', 'nuage-openvswitch'], + 'neutron_server_nuage_packages' => ['nuage-openstack-neutron', 'nuage-openstack-neutronclient', 'nuagenetlib'], 'package_overrides' => "-o Dpkg::Options::='--force-confold' -o Dpkg::Options::='--force-confdef'" } end diff --git a/metadata.rb b/metadata.rb index 6b1044ff..7311b1cb 100644 --- a/metadata.rb +++ b/metadata.rb @@ -5,7 +5,7 @@ maintainer_email 'opscode-chef-openstack@googlegroups.com' license 'Apache 2.0' description 'Installs and configures the OpenStack Network API Service and various agents and plugins' long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version '11.0.0' +version '11.1.0' recipe 'openstack-network::client', 'Install packages required for network client' recipe 'openstack-network::server', 'Installs packages required for a OpenStack Network server' recipe 'openstack-network::openvswitch', 'Installs packages required for OVS' @@ -20,3 +20,4 @@ end depends 'openstack-common', '>= 11.5.0' depends 'openstack-identity', '>= 11.0.0' +depends 'selinux', '>= 0.9.0' diff --git a/recipes/default.rb b/recipes/default.rb index 3acecdab..45578197 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -472,6 +472,19 @@ when 'ryu' notifies :restart, 'service[neutron-server]', :delayed if role_match end +when 'nuage' + + template_file = '/etc/neutron/plugins/nuage/nuage_plugin.ini' + + template template_file do + source 'plugins/nuage/nuage_plugin.ini.erb' + owner node['openstack']['network']['platform']['user'] + group node['openstack']['network']['platform']['group'] + mode 00644 + + notifies :restart, 'service[neutron-server]', :delayed if role_match + end + else Chef::Log.fatal("Main plugin #{main_plugin}is not supported") end diff --git a/recipes/nuage.rb b/recipes/nuage.rb new file mode 100644 index 00000000..74ff8409 --- /dev/null +++ b/recipes/nuage.rb @@ -0,0 +1,104 @@ +# Encoding: utf-8 +# +# Cookbook Name:: openstack-network +# Recipe:: nuage +# +# Copyright 2015, AT&T +# +# 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. +# + +['quantum', 'neutron'].include?(node['openstack']['compute']['network']['service_type']) || return + +require 'uri' + +# Make Openstack object available in Chef::Recipe +class ::Chef::Recipe + include ::Openstack + include ::Utils +end + +platform_options = node['openstack']['network']['platform'] + +if recipe_included? 'openstack-network::server' + # INSTALL PACKAGES + platform_options['neutron_server_nuage_packages'].each do |pkg| + package pkg do + action :upgrade + options platform_options['package_overrides'] + end + end +end + +include_recipe 'openstack-network' + +if recipe_included? 'openstack-compute::compute' + # SELINUX PERMISSIVE + include_recipe 'selinux::permissive' + + # INSTALL PACKAGES + platform_options['compute_nuage_packages'].each do |pkg| + package pkg do + action :upgrade + options platform_options['package_overrides'] + end + end + + # VRS CONFIGURATION /etc/default/openvswitch + ruby_block 'insert_controllers' do + block do + file = Chef::Util::FileEdit.new('/etc/default/openvswitch') + + active_controller_ip = node['openstack']['network']['nuage']['active_controller'] + active_controller = "ACTIVE_CONTROLLER=#{active_controller_ip}" + file.insert_line_if_no_match('/$ACTIVE_CONTROLLER/', active_controller) + + standby_controller_ip = node['openstack']['network']['nuage']['standby_controller'] + unless standby_controller_ip.empty? + standby_controller = "STANDBY_CONTROLLER=#{standby_controller_ip}" + file.insert_line_if_no_match('/$STANDBY_CONTROLLER/', standby_controller) + end + + file.write_file + end + end + + # NUAGE METADATA CONFIGURATION /etc/default/nuage-metadata-agent + identity_endpoint = internal_endpoint 'identity-internal' + service_pass = get_password 'service', 'openstack-network' + metadata_secret = get_password 'token', node['openstack']['network']['metadata']['secret_name'] + compute_metadata_api = internal_endpoint 'compute-metadata-api' + + template_file = '/etc/default/nuage-metadata-agent' + + template template_file do + source 'plugins/nuage/nuage-metadata-agent.erb' + owner node['openstack']['network']['platform']['user'] + group node['openstack']['network']['platform']['group'] + variables( + identity_endpoint: identity_endpoint, + metadata_secret: metadata_secret, + service_pass: service_pass, + compute_metadata_ip: compute_metadata_api.host, + compute_metadata_port: compute_metadata_api.port + ) + mode 00644 + end + + # RESTART openvswitch + service 'openvswitch' do + service_name platform_options['neutron_openvswitch_service'] + supports status: true, restart: true + action :restart + end +end diff --git a/spec/nuage-redhat_spec.rb b/spec/nuage-redhat_spec.rb new file mode 100644 index 00000000..0d7b604a --- /dev/null +++ b/spec/nuage-redhat_spec.rb @@ -0,0 +1,24 @@ +# encoding: UTF-8 +require_relative 'spec_helper' + +describe 'openstack-network::nuage' do + describe 'redhat' do + let(:runner) { ChefSpec::SoloRunner.new(REDHAT_OPTS) } + let(:node) { runner.node } + let(:chef_run) do + node.set['openstack']['compute']['network']['service_type'] = 'neutron' + node.set['openstack']['network']['core_plugin'] = 'neutron.plugins.nuage.plugin.NuagePlugin' + runner.converge(described_recipe) + end + + include_context 'neutron-stubs' + + it 'upgrades nuage neutron plugin' do + allow_any_instance_of(Chef::Recipe).to receive(:recipe_included?).with('openstack-network::server').and_return(true) + allow_any_instance_of(Chef::Recipe).to receive(:recipe_included?).with('openstack-compute::compute').and_return(false) + expect(chef_run).to upgrade_package('nuage-openstack-neutron') + expect(chef_run).to upgrade_package('nuage-openstack-neutronclient') + expect(chef_run).to upgrade_package('nuagenetlib') + end + end +end diff --git a/spec/nuage_spec.rb b/spec/nuage_spec.rb new file mode 100644 index 00000000..e94262dc --- /dev/null +++ b/spec/nuage_spec.rb @@ -0,0 +1,113 @@ +# encoding: UTF-8 +require_relative 'spec_helper' + +describe 'openstack-network::nuage' do + describe 'ubuntu' do + let(:runner) { ChefSpec::SoloRunner.new(UBUNTU_OPTS) } + let(:node) { runner.node } + let(:chef_run) do + node.set['openstack']['compute']['network']['service_type'] = 'neutron' + node.set['openstack']['network']['core_plugin'] = 'neutron.plugins.nuage.plugin.NuagePlugin' + runner.converge(described_recipe) + end + + include_context 'neutron-stubs' + + context "when recipes include 'openstack-compute::compute" do + before do + allow_any_instance_of(Chef::Recipe).to receive(:recipe_included?).with('openstack-compute::compute').and_return(true) + allow_any_instance_of(Chef::Recipe).to receive(:recipe_included?).with('openstack-network::server').and_return(false) + end + + it 'upgarde and configure nuage plugin on compute' do + expect(chef_run).to upgrade_package('nuage-metadata-agent') + expect(chef_run).to upgrade_package('nuage-openvswitch') + end + + it 'verify ruby block execution of insert controllers' do + expect(chef_run).to run_ruby_block('insert_controllers') + end + + describe '/etc/default/nuage-metadata-agent' do + let(:file) { chef_run.template('/etc/default/nuage-metadata-agent') } + + it 'creates nuage-metadata-agent' do + expect(chef_run).to create_template(file.name).with( + user: 'neutron', + group: 'neutron', + mode: 0644 + ) + end + + context 'template contents' do + it_behaves_like 'custom template banner displayer' do + let(:file_name) { file.name } + end + + it 'set the MATADATA_PORT atturbute' do + node.set['openstack']['network']['nuage']['metadata_port'] = '9697' + expect(chef_run).to render_file(file.name).with_content(/^METADATA_PORT=9697$/) + end + + it 'has default NOVA_MATADATE_IP and NOVA_METADATA_PORT options set' do + [/^NOVA_METADATA_IP=127.0.0.1$/, /^NOVA_METADATA_PORT=8775$/].each do |line| + expect(chef_run).to render_file(file.name).with_content(line) + end + end + + it 'set the METADATA_PROXY_SHARED_SECRET attributes' do + node.set['openstack']['network']['metadata']['secret_name'] = 'network_metadata_secret' + allow_any_instance_of(Chef::Recipe).to receive(:get_password) + .with('token', 'network_metadata_secret') + .and_return('network_metadata_secret_value') + expect(chef_run).to render_file(file.name).with_content(/^METADATA_PROXY_SHARED_SECRET=network_metadata_secret_value$/) + end + + it 'set the NOVA_CLIENT_VERSION attributes' do + expect(chef_run).to render_file(file.name).with_content(/^NOVA_CLIENT_VERSION=2$/) + end + + it 'set the NOVA_OS_USERNAME attributes' do + node.set['openstack']['network']['service_user'] = 'neutron' + expect(chef_run).to render_file(file.name).with_content(/^NOVA_OS_USERNAME=neutron$/) + end + + it 'set the NOVA_OS_PASSWORD attributes' do + allow_any_instance_of(Chef::Recipe).to receive(:get_password) + .with('service', 'openstack-network') + .and_return('admin_password_value') + expect(chef_run).to render_file(file.name).with_content(/^NOVA_OS_PASSWORD=admin_password_value$/) + end + + it 'set the NOVA_OS_TENANT_NAME attributes' do + node.set['openstack']['network']['service_tenant_name'] = 'admin' + expect(chef_run).to render_file(file.name).with_content(/^NOVA_OS_TENANT_NAME=admin$/) + end + + it 'sets the NOVA_OS_AUTH_URL attribute' do + expect(chef_run).to render_file(file.name).with_content(%r{^NOVA_OS_AUTH_URL=http://127.0.0.1:5000/v2.0$}) + end + + it 'set the NUAGE_METADATA_AGENT_START_WITH_OVS attributes' do + node.set['openstack']['network']['nuage']['metadata_start_with_vrs'] = true + expect(chef_run).to render_file(file.name).with_content(/^NUAGE_METADATA_AGENT_START_WITH_OVS=true$/) + end + + it 'set the NOVA_API_ENDPOINT_TYPE attributes' do + node.set['openstack']['network']['nuage']['nova_api_endpoint_type'] = 'internalURL' + expect(chef_run).to render_file(file.name).with_content(/^NOVA_API_ENDPOINT_TYPE=internalURL$/) + end + + it 'set the NOVA_REGION_NAME attributes' do + node.set['openstack']['network']['region'] = 'RegionOne' + expect(chef_run).to render_file(file.name).with_content(/^NOVA_REGION_NAME=RegionOne$/) + end + end + end + + it 'start the openvswitch service' do + expect(chef_run).to restart_service('openvswitch') + end + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 99c2372c..9f397e08 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -64,6 +64,7 @@ PLUGIN_MAP = { 'ml2' => 'ml2_conf.ini', 'nec' => 'nec.ini', 'nicira' => 'nvp.ini', + 'nuage' => 'nuage_plugin.ini', 'openvswitch' => 'ovs_neutron_plugin.ini', 'plumgrid' => 'plumgrid.ini', 'ryu' => 'ryu.ini' diff --git a/templates/default/plugins/nuage/nuage-metadata-agent.erb b/templates/default/plugins/nuage/nuage-metadata-agent.erb new file mode 100644 index 00000000..050e8af8 --- /dev/null +++ b/templates/default/plugins/nuage/nuage-metadata-agent.erb @@ -0,0 +1,40 @@ +<%= node["openstack"]["network"]["custom_template_banner"] %> +### Configuration options for nuage-metadata-agent + +# Copyright (C) 2014, Nuage Networks + +# METADATA_PORT: TCP Port used by Nuage metadata agent +METADATA_PORT=<%= node['openstack']['network']['nuage']['metadata_port'] %> + +# NOVA_METADATA_IP: IP address used by Nova metadata server +NOVA_METADATA_IP=<%= @compute_metadata_ip %> + +# NOVA_METADATA_PORT: TCP Port used by Nova metadata server +NOVA_METADATA_PORT=<%= @compute_metadata_port %> + +# METADATA_PROXY_SHARED_SECRET: with which to sign the Instance-ID header +METADATA_PROXY_SHARED_SECRET=<%= @metadata_secret %> + +# NOVA_CLIENT_VERSION: +NOVA_CLIENT_VERSION=<%= node['openstack']['network']['nuage']['nova_client_version'] %> + +# NOVA_OS_USERNAME: +NOVA_OS_USERNAME=<%= node["openstack"]["network"]["service_user"] %> + +# NOVA_OS_PASSWORD: +NOVA_OS_PASSWORD=<%= @service_pass %> + +# NOVA_OS_TENANT_NAME: +NOVA_OS_TENANT_NAME=<%= node["openstack"]["network"]["service_tenant_name"] %> + +# NOVA_OS_AUTH_URL: +NOVA_OS_AUTH_URL=<%= @identity_endpoint.to_s %> + +# NUAGE_METADATA_AGENT_START_WITH_OVS: if nuage-metadata-agent needs to be started with nuage-openvswitch-switch +NUAGE_METADATA_AGENT_START_WITH_OVS=<%= node['openstack']['network']['nuage']['metadata_start_with_vrs'] %> + +# NOVA_API_ENDPOINT_TYPE: one of publicURL, internalURL, adminURL +NOVA_API_ENDPOINT_TYPE=<%= node['openstack']['network']['nuage']['nova_api_endpoint_type'] %> + +# NOVA_REGION_NAME: +NOVA_REGION_NAME=<%= node["openstack"]["network"]["region"] %> \ No newline at end of file diff --git a/templates/default/plugins/nuage/nuage_plugin.ini.erb b/templates/default/plugins/nuage/nuage_plugin.ini.erb new file mode 100644 index 00000000..80f44e9d --- /dev/null +++ b/templates/default/plugins/nuage/nuage_plugin.ini.erb @@ -0,0 +1,17 @@ +<%= node["openstack"]["network"]["custom_template_banner"] %> +[RESTPROXY] +# Desired Name of VSD Organization/Enterprise to use when net-partition +# is not specified +default_net_partition_name = <%= node["openstack"]["network"]["nuage"]["default_net_partition_name"] %> +# Hostname or IP address and port for connection to VSD server +server = <%= node["openstack"]["network"]["nuage"]["server"] %> +# VSD Username and password for OpenStack plugin connection +# User must belong to CSP Root group and CSP CMS group +serverauth = <%= node["openstack"]["network"]["nuage"]["serverauth"]["username"] %>:<%= node["openstack"]["network"]["nuage"]["serverauth"]["password"] %> + +### Do not change the below options for standard installs +organization = <%= node["openstack"]["network"]["nuage"]["organization"] %> +auth_resource = <%= node["openstack"]["network"]["nuage"]["auth_resource"] %> +serverssl = <%= node["openstack"]["network"]["nuage"]["serverssl"] %> +base_uri = <%= node["openstack"]["network"]["nuage"]["base_uri"] %> +cms_id = <%= node["openstack"]["network"]["nuage"]["cms_id"]%> \ No newline at end of file