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 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25 package com.sun.dhcpmgr.cli.dhcpconfig;
26
27 import com.sun.dhcpmgr.cli.common.DhcpCliFunction;
28 import com.sun.dhcpmgr.data.DhcpdOptions;
29 import com.sun.dhcpmgr.data.DhcpDatastore;
30 import com.sun.dhcpmgr.data.ValidationException;
31 import com.sun.dhcpmgr.data.StandardOptions;
32 import com.sun.dhcpmgr.bridge.ExistsException;
33 import com.sun.dhcpmgr.bridge.TableExistsException;
34
35 import java.net.InetAddress;
36 import java.lang.IllegalArgumentException;
37
38 /**
39 * The main class for the "configure DHCP server" functionality of dhcpconfig.
40 */
41 public class ConfigureDhcp extends DhcpCfgFunction {
42
43 /**
44 * The valid options associated with configuring a DHCP server.
45 */
46 static final int supportedOptions[] = {
47 DhcpCfg.NON_NEGOTIABLE_LEASE,
48 DhcpCfg.LEASE_LENGTH,
49 DhcpCfg.DNS_ADDRESSES,
50 DhcpCfg.DNS_DOMAIN,
51 DhcpCfg.RESOURCE,
52 DhcpCfg.RESOURCE_CONFIG,
53 DhcpCfg.PATH
54 };
55
56 /**
57 * Constructs a ConfigureDhcp object.
58 */
59 public ConfigureDhcp() {
60
61 validOptions = supportedOptions;
62
63 } // constructor
64
65 /**
66 * Returns the option flag for this function.
67 * @returns the option flag for this function.
68 */
69 public int getFunctionFlag() {
70 return (DhcpCfg.CONFIGURE_DHCP);
71 }
72
73 /**
74 * Executes the "configure DHCP server" functionality.
75 * @return DhcpCfg.SUCCESS or DhcpCfg.FAILURE
76 */
77 public int execute() throws IllegalArgumentException {
78
79 // Check to see if DHCP or BOOTP relay is already configured.
80 //
81 boolean isServer = false;
82 boolean isRelay = false;
83 try {
84 DhcpdOptions opts = getSvcMgr().readDefaults();
85 if (opts.isRelay()) {
86 isRelay = true;
87 } else {
88 isServer = true;
89 }
90 } catch (Throwable e) {
91 // this is to be expected
92 }
93
94 if (isServer) {
95 printErrMessage(getString("config_dhcp_configured_error"));
96 return (DhcpCfg.FAILURE);
97 }
98
99 if (isRelay) {
100 printErrMessage(getString("config_bootp_configured_error"));
101 return (DhcpCfg.FAILURE);
102 }
103
104 // User must define both resource and path.
105 //
106 if (options.valueOf(DhcpCfg.RESOURCE) == null ||
107 options.valueOf(DhcpCfg.PATH) == null) {
108 String msg = getString("config_null_datastore_error");
109 throw new IllegalArgumentException(msg);
110 }
111
112 try {
113 setDhcpDatastore(getSvcMgr().getDataStore(
114 options.valueOf(DhcpCfg.RESOURCE)));
115 getDhcpDatastore().setLocation(options.valueOf(DhcpCfg.PATH));
116 getDhcpDatastore().setConfig(
117 options.valueOf(DhcpCfg.RESOURCE_CONFIG));
118 } catch (Throwable e) {
119 // resource will not be valid
120 }
121
122
123 if (getDhcpDatastore() == null || !getDhcpDatastore().isEnabled()) {
124 Object [] arguments = new Object[1];
125 arguments[0] = getDhcpDatastore().getResource();
126 printErrMessage(getString("config_invalid_resource_error"),
127 arguments);
128 return (DhcpCfg.FAILURE);
129 }
130
131 // Retrieve the leaseLength option and check its validity.
132 // The default (3600*24 = 1 day) should be defined as static somewhere.
133 //
134 Integer leaseLength = new Integer(3600*24);
135 if (options.isSet(DhcpCfg.LEASE_LENGTH)) {
136 try {
137 leaseLength =
138 new Integer(options.valueOf(DhcpCfg.LEASE_LENGTH));
139 } catch (Throwable e) {
140 printErrMessage(getString("config_lease_error"));
141 return (DhcpCfg.FAILURE);
142 }
143
144 if (leaseLength.intValue() == 0) {
145 printErrMessage(getString("config_lease_zero_error"));
146 return (DhcpCfg.FAILURE);
147 }
148 }
149
150 // Are leases negotiable
151 //
152 boolean leaseNegotiable =
153 !options.isSet(DhcpCfg.NON_NEGOTIABLE_LEASE);
154
155 // Get the DNS information.
156 //
157 String dnsDomain = options.valueOf(DhcpCfg.DNS_DOMAIN);
158 String dnsServers = options.valueOf(DhcpCfg.DNS_ADDRESSES);
159 if ((dnsDomain == null) != (dnsServers == null)) {
160 String msg = getString("config_dns_error");
161 throw new IllegalArgumentException(msg);
162 }
163
164 IPAddressList dnsAddresses = null;
165 try {
166 if (dnsDomain == null) {
167 dnsDomain = getSvcMgr().getStringOption(
168 StandardOptions.CD_DNSDOMAIN, "");
169 }
170 if (dnsServers != null) {
171 dnsAddresses = new IPAddressList(dnsServers);
172 } else {
173 dnsAddresses = new IPAddressList(
174 getSvcMgr().getIPOption(StandardOptions.CD_DNSSERV, ""));
175 }
176 } catch (ValidationException e) {
177 Object [] arguments = new Object[1];
178 arguments[0] = getMessage(e);
179 printErrMessage(getString("config_dns_server_error"), arguments);
180 return (DhcpCfg.FAILURE);
181 } catch (Throwable e) {
182 // Ignore, DNS info will not be configured in the server macro.
183 }
184
185 // Create the location if it does not exist.
186 //
187 try {
188 getSvcMgr().makeLocation(getDhcpDatastore());
189 } catch (ExistsException e) {
190 // this is o.k.
191 } catch (Throwable e) {
192 Object [] arguments = new Object[1];
193 arguments[0] = getDhcpDatastore().getLocation();
194 printErrMessage(getString("config_make_location_error"),
195 arguments);
196 return (DhcpCfg.FAILURE);
197 }
198
199 // Create the DHCP configuration file
200 //
201 DhcpdOptions dhcpdOptions = new DhcpdOptions();
202 dhcpdOptions.setDaemonEnabled(true);
203 dhcpdOptions.setDhcpDatastore(getDhcpDatastore());
204 try {
205 getSvcMgr().writeDefaults(dhcpdOptions);
206 printMessage(getString("config_create_conf_progress"));
207 } catch (Throwable e) {
208 Object [] arguments = new Object[1];
209 arguments[0] = getMessage(e);
210 printErrMessage(getString("config_writing_conf_error"), arguments);
211 return (DhcpCfg.FAILURE);
212 }
213
214 // Create the dhcptab
215 //
216 try {
217 getDhcptabMgr().createDhcptab(getDhcpDatastore());
218 printMessage(getString("config_dhcptab_progress"));
219 } catch (TableExistsException e) {
220 // Not an error; some data stores are shared by multiple servers
221 printMessage(getString("config_dhcptab_exists_progress"));
222 } catch (Throwable e) {
223 Object [] arguments = new Object[1];
224 arguments[0] = getMessage(e);
225 printErrMessage(getString("config_dhcptab_error"), arguments);
226 return (DhcpCfg.FAILURE);
227 }
228
229 // Create the locale macro
230 //
231 try {
232 getDhcptabMgr().createLocaleMacro();
233 printMessage(getString("config_locale_progress"));
234 } catch (ExistsException e) {
235 /*
236 * Ignore this error, if one's already there we'll assume
237 * it's correct
238 */
239 } catch (Throwable e) {
240 Object [] arguments = new Object[1];
241 arguments[0] = getMessage(e);
242 printErrMessage(getString("config_locale_error"), arguments);
243 return (DhcpCfg.FAILURE);
244 }
245
246 // Create the Server macro
247 //
248 String svrName = null;
249 try {
250 svrName = getSvcMgr().getShortServerName();
251 InetAddress svrAddress = getSvcMgr().getServerAddress();
252 getDhcptabMgr().createServerMacro(svrName, svrAddress,
253 leaseLength.intValue(), leaseNegotiable, dnsDomain,
254 dnsAddresses);
255 Object [] arguments = new Object[1];
256 arguments[0] = svrName;
257 printMessage(getString("config_server_macro_progress"), arguments);
258 } catch (Throwable e) {
259 // Couldn't create it; inform user because this is serious
260 Object [] arguments = new Object[2];
261 arguments[1] = svrName;
262 arguments[0] = getMessage(e);
263 printErrMessage(getString("config_server_macro_error"), arguments);
264 return (DhcpCfg.FAILURE);
265 }
266
267 // Start it up.
268 //
269 try {
270 getSvcMgr().startup();
271 printMessage(getString("config_startup_progress"));
272 } catch (Throwable e) {
273 Object [] arguments = new Object[1];
274 arguments[0] = getMessage(e);
275 printErrMessage(getString("config_startup_error"), arguments);
276 return (DhcpCfg.FAILURE);
277 }
278
279 return (DhcpCfg.SUCCESS);
280
281 } // execute
282
283 } // ConfigureDhcp