|
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_ipnet).provide(:evs_ipnet) do |
|
28 desc "Provider for managing EVS IPnet setup in the Solaris OS" |
|
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_ipnet_prop_list |
|
41 begin |
|
42 ipnet_list = evsadm("show-ipnet", "-c", "-o", |
|
43 "name,tenant").split("\n") |
|
44 rescue Puppet::ExecutionFailure => e |
|
45 raise Puppet::Error, "Unable to populate IPnet: \n"\ |
|
46 "#{e.inspect}" |
|
47 end |
|
48 ipnet_list |
|
49 end |
|
50 |
|
51 def self.get_ipnet_properties(ipnet_name, tenant, ensure_val) |
|
52 ipnet_properties = {} |
|
53 ipnet_fullname = tenant + "/" + ipnet_name |
|
54 |
|
55 ipnet_properties[:name] = ipnet_fullname |
|
56 ipnet_properties[:ensure] = ensure_val |
|
57 |
|
58 evsadm("show-ipnetprop", "-f", "tenant=#{tenant}", "-c", "-o", |
|
59 "property,value", ipnet_name).split("\n").collect do |each_ipnet| |
|
60 property, value = each_ipnet.split(":") |
|
61 value = "" if value.nil? |
|
62 case property |
|
63 # read-only properties (settable upon creation) |
|
64 when "subnet" |
|
65 ipnet_properties[:subnet] = value |
|
66 when "defrouter" |
|
67 ipnet_properties[:defrouter] = value |
|
68 when "uuid" |
|
69 ipnet_properties[:uuid] = value |
|
70 # read/write property (always updatable) |
|
71 when "pool" |
|
72 ipnet_properties[:pool] = value |
|
73 end |
|
74 end |
|
75 |
|
76 Puppet.debug "IPnet Properties: #{ipnet_properties.inspect}" |
|
77 ipnet_properties |
|
78 end |
|
79 |
|
80 def self.instances |
|
81 get_ipnet_prop_list.collect do |each_ipnet| |
|
82 ipnet, tenant, subnet = each_ipnet.strip.split(":") |
|
83 ipnet_properties = get_ipnet_properties( |
|
84 ipnet, tenant, :present) |
|
85 new(ipnet_properties) # Create a provider instance |
|
86 end |
|
87 end |
|
88 |
|
89 def self.prefetch(resources) |
|
90 instances.each do |inst| |
|
91 if resource = resources[inst.name] |
|
92 resource.provider = inst |
|
93 end |
|
94 end |
|
95 end |
|
96 |
|
97 def exists? |
|
98 @property_hash[:ensure] == :present |
|
99 end |
|
100 |
|
101 def create |
|
102 # Subnet value is required to create an IPnet instance |
|
103 if @resource[:subnet].nil? |
|
104 raise Puppet::Error, "Subnet value is missing" |
|
105 end |
|
106 |
|
107 tenant, ipnet_name = get_tenant_and_ipnet_name |
|
108 begin |
|
109 create_ipnet(tenant, ipnet_name, add_properties(@resource)) |
|
110 rescue Puppet::ExecutionFailure => e |
|
111 raise Puppet::Error, "Cannot add the IPnet: \n #{e.inspect}" |
|
112 end |
|
113 end |
|
114 |
|
115 def destroy |
|
116 tenant, ipnet_name = get_tenant_and_ipnet_name |
|
117 begin |
|
118 delete_ipnet(tenant, ipnet_name) |
|
119 rescue Puppet::ExecutionFailure => e |
|
120 raise Puppet::Error, "Cannot remove the IPnet: \n #{e.inspect}" |
|
121 end |
|
122 end |
|
123 |
|
124 ## read-only properties (settable upon creation) ## |
|
125 def defrouter=(value) |
|
126 raise Puppet::Error, "defrouter property is settable only upon creation" |
|
127 end |
|
128 |
|
129 def subnet=(value) |
|
130 raise Puppet::Error, "subnet property is settable only upon creation" |
|
131 end |
|
132 |
|
133 def uuid=(value) |
|
134 raise Puppet::Error, "uuid property is settable only upon creation" |
|
135 end |
|
136 |
|
137 ## read/write property (always updatable) ## |
|
138 def pool=(value) |
|
139 @property_flush[:pool] = value |
|
140 end |
|
141 |
|
142 ## Create IPnet instance ## |
|
143 def create_ipnet(tenant, ipnet_name, properties) |
|
144 begin |
|
145 evsadm("add-ipnet", "-T", tenant, properties, ipnet_name) |
|
146 rescue Puppet::ExecutionFailure => e |
|
147 # Pass up the exception to upper level |
|
148 raise |
|
149 end |
|
150 end |
|
151 |
|
152 ## Remove IPnet instance ## |
|
153 def delete_ipnet(tenant, ipnet_name) |
|
154 begin |
|
155 evsadm("remove-ipnet", "-T", tenant, ipnet_name) |
|
156 rescue Puppet::ExecutionFailure => e |
|
157 # Pass up the exception to upper level |
|
158 raise |
|
159 end |
|
160 end |
|
161 |
|
162 ## Set IPnet prop (pool property only) ## |
|
163 def set_ipnet(tenant, ipnet_name, property) |
|
164 begin |
|
165 evsadm("set-ipnetprop", "-T", tenant, property, ipnet_name) |
|
166 rescue Puppet::ExecutionFailure => e |
|
167 # Pass up the exception to upper level |
|
168 raise |
|
169 end |
|
170 end |
|
171 |
|
172 ## Parse the "name" value from user and yield tenant and IPnet name ## |
|
173 def get_tenant_and_ipnet_name |
|
174 fullname = @resource[:name] |
|
175 |
|
176 parsed_val = fullname.strip.split("/") |
|
177 if (parsed_val.length != 3) |
|
178 raise Puppet::Error, "Invalid IPnet name" |
|
179 end |
|
180 tenant, evs, ipnet = parsed_val |
|
181 return tenant, evs + "/" + ipnet |
|
182 end |
|
183 |
|
184 ## property setter for IPnet creation ## |
|
185 def add_properties(source) |
|
186 p = [] |
|
187 prop_list = { |
|
188 "defrouter" => source[:defrouter], |
|
189 "pool" => source[:pool], |
|
190 "subnet" => source[:subnet], |
|
191 "uuid" => source[:uuid] |
|
192 } |
|
193 prop_list.each do |key, value| |
|
194 next if (value == nil) || (value == "") |
|
195 p << "#{key}=#{value}" |
|
196 end |
|
197 return [] if p.empty? |
|
198 properties = Array["-p", p.join(",")] |
|
199 end |
|
200 |
|
201 ## Flush when existing property value is updatable ## |
|
202 def flush |
|
203 tenant, ipnet_name = get_tenant_and_ipnet_name |
|
204 |
|
205 unless @property_flush.empty? |
|
206 # Update read/write property (pool) |
|
207 pool_prop = ["-p", "pool=#{@property_flush[:pool]}"] |
|
208 begin |
|
209 set_ipnet(tenant, ipnet_name, pool_prop) |
|
210 rescue Puppet::ExecutionFailure => e |
|
211 raise Puppet::Error, "Cannot update the pool property. \n" \ |
|
212 "#{e.inspect}" |
|
213 end |
|
214 end |
|
215 |
|
216 # Synchronize all the SHOULD values to IS values |
|
217 @property_hash = resource.to_hash |
|
218 end |
|
219 end |