components/ruby/puppet/files/solaris/lib/puppet/provider/evs_properties/solaris.rb
changeset 4794 be62c55aa235
child 4801 c249904bb056
equal deleted inserted replaced
4793:24053a14d972 4794:be62c55aa235
       
     1 #
       
     2 # CDDL HEADER START
       
     3 #
       
     4 # The contents of this file are subject to the terms of the
       
     5 # Common Development and Distribution License (the "License").
       
     6 # You may not use this file except in compliance with the License.
       
     7 #
       
     8 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
       
     9 # or http://www.opensolaris.org/os/licensing.
       
    10 # See the License for the specific language governing permissions
       
    11 # and limitations under the License.
       
    12 #
       
    13 # When distributing Covered Code, include this CDDL HEADER in each
       
    14 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
       
    15 # If applicable, add the following below this CDDL HEADER, with the
       
    16 # fields enclosed by brackets "[]" replaced with your own identifying
       
    17 # information: Portions Copyright [yyyy] [name of copyright owner]
       
    18 #
       
    19 # CDDL HEADER END
       
    20 #
       
    21 
       
    22 #
       
    23 # Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
       
    24 #
       
    25 
       
    26 
       
    27 Puppet::Type.type(:evs_properties).provide(:evs_properties) do
       
    28     desc "Provider for managing Oracle Solaris EVS properties"
       
    29     confine :operatingsystem => [:solaris]
       
    30     defaultfor :osfamily => :solaris, :kernelrelease => ["5.11", "5.12"]
       
    31     commands :evsadm => "/usr/sbin/evsadm"
       
    32 
       
    33     mk_resource_methods
       
    34 
       
    35     def initialize(value={})
       
    36         super(value)
       
    37         @property_flush = {}
       
    38     end
       
    39 
       
    40     def self.get_client_property
       
    41         client_property = {}
       
    42         begin
       
    43             p = evsadm("show-prop", "-c", "-o", "property,value")
       
    44         rescue Puppet::ExecutionFailure => e
       
    45             raise Puppet::Error, "Failed to prefetch client property: \n" \
       
    46                 "#{e.inspect}"
       
    47         end
       
    48 
       
    49         property, value = p.strip.split(":", 2)
       
    50         value.gsub! "\\:", ":" 
       
    51         client_property[:name] = "client_property"
       
    52         client_property[:controller] = value
       
    53         
       
    54         Puppet.debug "Client Property: #{client_property.inspect}"
       
    55         client_property
       
    56 
       
    57     end
       
    58 
       
    59     def self.get_control_properties
       
    60         control_props = {}
       
    61         uplink_ports = []
       
    62         uri_templates = []
       
    63         vxlan_addrs = []
       
    64         begin
       
    65             evsadm("show-controlprop", "-c", "-o", 
       
    66                 "property,value,vlan_range,vxlan_range,host,flat").\
       
    67                 split("\n").collect do |each_prop|
       
    68                 each_prop.gsub! "\\:", "\\"
       
    69                 property, value, vlan_range, vxlan_range, host, flat = \
       
    70                     each_prop.strip().split(":")
       
    71                 case property
       
    72                 when "l2-type"
       
    73                     control_props[:l2_type] = value
       
    74                 when "uplink-port"
       
    75                     next if value.empty?
       
    76                     host = "" if host == nil
       
    77                     val = "#{value};#{vlan_range};#{vxlan_range};#{host};"\
       
    78                         "#{flat}"
       
    79                     uplink_ports << val
       
    80                 when "uri-template"
       
    81                     value.gsub! "\\", ":"
       
    82                     host = "" if host == nil
       
    83                     val = "#{value};#{host}"
       
    84                     uri_templates << val
       
    85                 when "vlan-range"
       
    86                     control_props[:vlan_range] = value
       
    87                 when "vxlan-addr"
       
    88                     host = "" if host == nil
       
    89                     val = "#{value};#{vxlan_range};#{host}"
       
    90                     vxlan_addrs << val
       
    91                 when "vxlan-ipvers"
       
    92                     control_props[:vxlan_ipvers] = value
       
    93                 when "vxlan-mgroup"
       
    94                     control_props[:vxlan_mgroup] = value
       
    95                 when "vxlan-range"
       
    96                     control_props[:vxlan_range] = value
       
    97                 end
       
    98             end
       
    99         rescue Puppet::ExecutionFailure => e
       
   100             # EVS controller is not set or valid
       
   101             # Handle the exception at upper level
       
   102             raise
       
   103         end
       
   104         control_props[:name] = "controller_property"
       
   105         control_props[:uplink_port] = uplink_ports
       
   106         control_props[:uri_template] = uri_templates
       
   107         control_props[:vxlan_addr] = vxlan_addrs
       
   108         Puppet.debug "Control Properties: #{control_props.inspect}"
       
   109         control_props
       
   110     end
       
   111 
       
   112     def self.instances
       
   113         prop_instance = []
       
   114         client_property = get_client_property
       
   115         prop_instance << new(client_property)
       
   116         
       
   117         begin
       
   118             controller_property = get_control_properties
       
   119         rescue Puppet::ExecutionFailure => e
       
   120             # EVS controller is not set or invalid
       
   121             prop_instance << new({:name => "controller_property"})
       
   122         else
       
   123             # controller_property values are fetched
       
   124             prop_instance << new(controller_property)
       
   125         end
       
   126         prop_instance
       
   127     end
       
   128 
       
   129     def self.prefetch(resources)
       
   130         instances.each do |inst|
       
   131             if resource = resources[inst.name]
       
   132                 resource.provider = inst
       
   133             end
       
   134         end
       
   135     end
       
   136     
       
   137     ### Define Setters ###
       
   138     ## Controller side property setup ##
       
   139     
       
   140     def l2_type=(value)
       
   141         @property_flush[:l2_type] = value
       
   142     end
       
   143     
       
   144     def uplink_port=(value)
       
   145         @property_flush[:uplink_port] = value
       
   146     end
       
   147     
       
   148     def uri_template=(value)
       
   149         @property_flush[:uri_template] = value
       
   150     end
       
   151 
       
   152     def vlan_range=(value)
       
   153         @property_flush[:vlan_range] = value
       
   154     end
       
   155     
       
   156     def vxlan_addr=(value)
       
   157         @property_flush[:vxlan_addr] = value
       
   158     end
       
   159 
       
   160     def vxlan_ipvers=(value)
       
   161         @property_flush[:vxlan_ipvers] = value
       
   162     end
       
   163     
       
   164     def vxlan_mgroup=(value)
       
   165         @property_flush[:vxlan_mgroup] = value
       
   166     end
       
   167 
       
   168     def vxlan_range=(value)
       
   169         @property_flush[:vxlan_range] = value
       
   170     end
       
   171     
       
   172     ## Client side property setup: the pointer to the EVS controller ##
       
   173     def controller=(value)
       
   174         @property_flush[:controller] = value
       
   175     end
       
   176 
       
   177     def set_controller_property(host, property)
       
   178         begin
       
   179             evsadm("set-controlprop", host, property)
       
   180         rescue Puppet::ExecutionFailure => e
       
   181             # Pass up the exception to upper level
       
   182             raise
       
   183         end
       
   184     end
       
   185 
       
   186     def set_client_property(property)
       
   187         begin
       
   188             evsadm("set-prop", "-p", property)
       
   189         rescue Puppet::ExecutionFailure => e
       
   190             # Pass up the exception to upper level
       
   191             raise
       
   192         end
       
   193     end
       
   194 
       
   195     def flush
       
   196         case @resource[:name]
       
   197         when "controller_property"
       
   198             if @property_flush.has_key?(:controller)
       
   199                 puts "foo"
       
   200                 raise Puppet::Error, "controller_property does not have "\
       
   201                     "'controller' property. Try client_property"
       
   202                 puts "bar"
       
   203             end
       
   204             
       
   205             props = []
       
   206             @property_flush.each do |key, value|
       
   207                 # Change symbol to string
       
   208                 k = key.to_s.gsub! "_", "-"
       
   209                 case k
       
   210                 # uplink-port property takes up to five values:
       
   211                 # link, [vlan-range], [vxlan-range], [host] and [flat]
       
   212                 when "uplink-port"
       
   213                     link, vlan, vxlan, host, flat = \
       
   214                         value.strip().split(";", -1)
       
   215 
       
   216                     # store host parameter if exists
       
   217                     host = host != "" ? ["-h", host] : []
       
   218 
       
   219                     # Concatenate the parameters of uplink-port
       
   220                     link = "uplink-port=#{link}"
       
   221                     vlan = vlan != "" ? ",vlan-range=#{vlan}" : ""
       
   222                     vxlan = vxlan != "" ? ",vxlan-range=#{vxlan}" : ""
       
   223                     flat = flat != "" ? ",flat=#{flat}" : ""
       
   224 
       
   225                     p = ["-p", "#{link}#{vlan}#{vxlan}#{flat}"]
       
   226 
       
   227                     props << [host, p]
       
   228 
       
   229                 # uri-template property takes up to two values:
       
   230                 # uri and [host]
       
   231                 when "uri-template"
       
   232                     uri, host = value.strip().split(";", -1)
       
   233                     
       
   234                     # store host parameter if exists
       
   235                     host = host != "" ? ["-h", host] : []
       
   236                     uri = ["-p", "uri-template=#{uri}"]
       
   237                     
       
   238                     props << [host, uri]
       
   239 
       
   240                 # vxlan_addr property takes up to three values:
       
   241                 # vxlan-addr, [vxlan-range] and [host]
       
   242                 when "vxlan-addr"
       
   243                     addr, range, host = value.strip().split(";", -1)
       
   244                     
       
   245                     # store host parameter if exists
       
   246                     host = host != "" ? ["-h", host] : []
       
   247                     addr = "vxlan-addr=#{addr}"
       
   248                     range = range != "" ? ",vxlan-range=#{range}" : ""
       
   249                     
       
   250                     p = ["-p", "#{addr}#{range}"]
       
   251                     
       
   252                     props << [host, p]
       
   253 
       
   254                 # l2-type, vlan-range, vxlan-range, vxlan-ipvers
       
   255                 # and vxlan-mgroup properties just need values
       
   256                 else
       
   257                     host = []
       
   258                     p = ["-p", "#{k}=#{value}"]
       
   259                     props << [host, p]
       
   260                 end
       
   261             end
       
   262 
       
   263             # Reverse the array so that l2-type, vlan-range, vxlan-range
       
   264             # vxlan-ipvers and vxlan-mgroups are set before the others
       
   265             props.reverse!
       
   266             # iteratively set controller property
       
   267             props.each do |p|
       
   268                 begin
       
   269                     set_controller_property(p[0], p[1])
       
   270                 # Do not terminate the script even if there is an error
       
   271                 # Just continue to next script
       
   272                 rescue Puppet::ExecutionFailure => e
       
   273                     Puppet.err "Cannot apply the property: \n#{e.inspect}"
       
   274                 end
       
   275             end
       
   276 
       
   277         when "client_property"
       
   278             unless @property_flush.has_key?(:controller)
       
   279                 raise Puppet::Error,
       
   280                     "'controller' property must be specified"
       
   281             end
       
   282             prop = "controller=#{@property_flush[:controller]}"
       
   283             begin
       
   284                 set_client_property(prop) 
       
   285             rescue Puppet::ExecutionFailure => e
       
   286                 raise Puppet::Error, "Cannot apply the property:\n #{e.inspect}"
       
   287             end
       
   288         end
       
   289         
       
   290         # Synchronize all the SHOULD values to IS values
       
   291         @property_hash = resource.to_hash
       
   292     end
       
   293 end
       
   294