--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/ruby/puppet/files/solaris/lib/puppet/provider/evs_properties/solaris.rb Tue Aug 18 15:07:30 2015 -0700
@@ -0,0 +1,294 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+#
+
+
+Puppet::Type.type(:evs_properties).provide(:evs_properties) do
+ desc "Provider for managing Oracle Solaris EVS properties"
+ confine :operatingsystem => [:solaris]
+ defaultfor :osfamily => :solaris, :kernelrelease => ["5.11", "5.12"]
+ commands :evsadm => "/usr/sbin/evsadm"
+
+ mk_resource_methods
+
+ def initialize(value={})
+ super(value)
+ @property_flush = {}
+ end
+
+ def self.get_client_property
+ client_property = {}
+ begin
+ p = evsadm("show-prop", "-c", "-o", "property,value")
+ rescue Puppet::ExecutionFailure => e
+ raise Puppet::Error, "Failed to prefetch client property: \n" \
+ "#{e.inspect}"
+ end
+
+ property, value = p.strip.split(":", 2)
+ value.gsub! "\\:", ":"
+ client_property[:name] = "client_property"
+ client_property[:controller] = value
+
+ Puppet.debug "Client Property: #{client_property.inspect}"
+ client_property
+
+ end
+
+ def self.get_control_properties
+ control_props = {}
+ uplink_ports = []
+ uri_templates = []
+ vxlan_addrs = []
+ begin
+ evsadm("show-controlprop", "-c", "-o",
+ "property,value,vlan_range,vxlan_range,host,flat").\
+ split("\n").collect do |each_prop|
+ each_prop.gsub! "\\:", "\\"
+ property, value, vlan_range, vxlan_range, host, flat = \
+ each_prop.strip().split(":")
+ case property
+ when "l2-type"
+ control_props[:l2_type] = value
+ when "uplink-port"
+ next if value.empty?
+ host = "" if host == nil
+ val = "#{value};#{vlan_range};#{vxlan_range};#{host};"\
+ "#{flat}"
+ uplink_ports << val
+ when "uri-template"
+ value.gsub! "\\", ":"
+ host = "" if host == nil
+ val = "#{value};#{host}"
+ uri_templates << val
+ when "vlan-range"
+ control_props[:vlan_range] = value
+ when "vxlan-addr"
+ host = "" if host == nil
+ val = "#{value};#{vxlan_range};#{host}"
+ vxlan_addrs << val
+ when "vxlan-ipvers"
+ control_props[:vxlan_ipvers] = value
+ when "vxlan-mgroup"
+ control_props[:vxlan_mgroup] = value
+ when "vxlan-range"
+ control_props[:vxlan_range] = value
+ end
+ end
+ rescue Puppet::ExecutionFailure => e
+ # EVS controller is not set or valid
+ # Handle the exception at upper level
+ raise
+ end
+ control_props[:name] = "controller_property"
+ control_props[:uplink_port] = uplink_ports
+ control_props[:uri_template] = uri_templates
+ control_props[:vxlan_addr] = vxlan_addrs
+ Puppet.debug "Control Properties: #{control_props.inspect}"
+ control_props
+ end
+
+ def self.instances
+ prop_instance = []
+ client_property = get_client_property
+ prop_instance << new(client_property)
+
+ begin
+ controller_property = get_control_properties
+ rescue Puppet::ExecutionFailure => e
+ # EVS controller is not set or invalid
+ prop_instance << new({:name => "controller_property"})
+ else
+ # controller_property values are fetched
+ prop_instance << new(controller_property)
+ end
+ prop_instance
+ end
+
+ def self.prefetch(resources)
+ instances.each do |inst|
+ if resource = resources[inst.name]
+ resource.provider = inst
+ end
+ end
+ end
+
+ ### Define Setters ###
+ ## Controller side property setup ##
+
+ def l2_type=(value)
+ @property_flush[:l2_type] = value
+ end
+
+ def uplink_port=(value)
+ @property_flush[:uplink_port] = value
+ end
+
+ def uri_template=(value)
+ @property_flush[:uri_template] = value
+ end
+
+ def vlan_range=(value)
+ @property_flush[:vlan_range] = value
+ end
+
+ def vxlan_addr=(value)
+ @property_flush[:vxlan_addr] = value
+ end
+
+ def vxlan_ipvers=(value)
+ @property_flush[:vxlan_ipvers] = value
+ end
+
+ def vxlan_mgroup=(value)
+ @property_flush[:vxlan_mgroup] = value
+ end
+
+ def vxlan_range=(value)
+ @property_flush[:vxlan_range] = value
+ end
+
+ ## Client side property setup: the pointer to the EVS controller ##
+ def controller=(value)
+ @property_flush[:controller] = value
+ end
+
+ def set_controller_property(host, property)
+ begin
+ evsadm("set-controlprop", host, property)
+ rescue Puppet::ExecutionFailure => e
+ # Pass up the exception to upper level
+ raise
+ end
+ end
+
+ def set_client_property(property)
+ begin
+ evsadm("set-prop", "-p", property)
+ rescue Puppet::ExecutionFailure => e
+ # Pass up the exception to upper level
+ raise
+ end
+ end
+
+ def flush
+ case @resource[:name]
+ when "controller_property"
+ if @property_flush.has_key?(:controller)
+ puts "foo"
+ raise Puppet::Error, "controller_property does not have "\
+ "'controller' property. Try client_property"
+ puts "bar"
+ end
+
+ props = []
+ @property_flush.each do |key, value|
+ # Change symbol to string
+ k = key.to_s.gsub! "_", "-"
+ case k
+ # uplink-port property takes up to five values:
+ # link, [vlan-range], [vxlan-range], [host] and [flat]
+ when "uplink-port"
+ link, vlan, vxlan, host, flat = \
+ value.strip().split(";", -1)
+
+ # store host parameter if exists
+ host = host != "" ? ["-h", host] : []
+
+ # Concatenate the parameters of uplink-port
+ link = "uplink-port=#{link}"
+ vlan = vlan != "" ? ",vlan-range=#{vlan}" : ""
+ vxlan = vxlan != "" ? ",vxlan-range=#{vxlan}" : ""
+ flat = flat != "" ? ",flat=#{flat}" : ""
+
+ p = ["-p", "#{link}#{vlan}#{vxlan}#{flat}"]
+
+ props << [host, p]
+
+ # uri-template property takes up to two values:
+ # uri and [host]
+ when "uri-template"
+ uri, host = value.strip().split(";", -1)
+
+ # store host parameter if exists
+ host = host != "" ? ["-h", host] : []
+ uri = ["-p", "uri-template=#{uri}"]
+
+ props << [host, uri]
+
+ # vxlan_addr property takes up to three values:
+ # vxlan-addr, [vxlan-range] and [host]
+ when "vxlan-addr"
+ addr, range, host = value.strip().split(";", -1)
+
+ # store host parameter if exists
+ host = host != "" ? ["-h", host] : []
+ addr = "vxlan-addr=#{addr}"
+ range = range != "" ? ",vxlan-range=#{range}" : ""
+
+ p = ["-p", "#{addr}#{range}"]
+
+ props << [host, p]
+
+ # l2-type, vlan-range, vxlan-range, vxlan-ipvers
+ # and vxlan-mgroup properties just need values
+ else
+ host = []
+ p = ["-p", "#{k}=#{value}"]
+ props << [host, p]
+ end
+ end
+
+ # Reverse the array so that l2-type, vlan-range, vxlan-range
+ # vxlan-ipvers and vxlan-mgroups are set before the others
+ props.reverse!
+ # iteratively set controller property
+ props.each do |p|
+ begin
+ set_controller_property(p[0], p[1])
+ # Do not terminate the script even if there is an error
+ # Just continue to next script
+ rescue Puppet::ExecutionFailure => e
+ Puppet.err "Cannot apply the property: \n#{e.inspect}"
+ end
+ end
+
+ when "client_property"
+ unless @property_flush.has_key?(:controller)
+ raise Puppet::Error,
+ "'controller' property must be specified"
+ end
+ prop = "controller=#{@property_flush[:controller]}"
+ begin
+ set_client_property(prop)
+ rescue Puppet::ExecutionFailure => e
+ raise Puppet::Error, "Cannot apply the property:\n #{e.inspect}"
+ end
+ end
+
+ # Synchronize all the SHOULD values to IS values
+ @property_hash = resource.to_hash
+ end
+end
+