8a17774d936d6b820ade66e0838afae9c50e991d
[plewww.git] / planetlab / nodes / node_add.php
1 <?php
2
3 // Require login
4 require_once 'plc_login.php';
5
6 // Get session and API handles
7 require_once 'plc_session.php';
8 global $plc, $api;
9
10 // Common functions
11 require_once 'plc_functions.php';
12 require_once 'toggle.php';
13 require_once 'details.php';
14 require_once 'form.php';
15   
16 // if not a admin, pi, or tech then redirect to node index
17 // xxx does not take site into account
18 $has_privileges=plc_is_admin();
19 $is_pi_or_tech=plc_is_pi() || plc_is_tech();
20 if( ! $has_privileges) {
21   if ( $is_pi_or_tech) {
22     drupal_goto(l_register_node());
23     return 0;
24   }
25   drupal_set_error ("Insufficient privileges to add a node");
26   header( "index.php" );
27   return 0;
28 }
29
30 //plc_debug('POST',$_POST);
31
32 // if submitted validate and add
33 // could go in actions.php but OTOH when things fail it's more convenient 
34 // to show the current values again
35 if ( $_POST['add-node'] )  {
36
37   $errors= array();
38
39   $site_id = trim($_POST['site_id']);
40   $hostname = trim($_POST['hostname']);
41   $model= trim($_POST['model']);
42   $node_type = trim ($_POST['node_type']);
43   $method = trim($_POST['method']);
44   $ip = trim($_POST['ip']);
45   $netmask = trim($_POST['netmask']);
46   $network = trim($_POST['network']);
47   $broadcast = trim($_POST['broadcast']);
48   $gateway = trim($_POST['gateway']);
49   $dns1 = trim($_POST['dns1']);
50   $dns2 = trim($_POST['dns2']);
51   $bwlimit = trim($_POST['bwlimit']);
52
53   // used to generate error strings for static fields only
54   $static_fields= array();
55   $static_fields['netmask']= "Netmask address";
56   $static_fields['network']= "Network address";
57   $static_fields['gateway']= "Gateway address";
58   $static_fields['broadcast']= "Broadcast address";
59   $static_fields['dns1']= "Primary DNS address";
60   
61   if( $method == 'static' ) {
62     foreach( $static_fields as $field => $desc ) {
63       if( trim($_POST[$field]) == "" ) {
64         $errors[] = "$desc is required";
65       } elseif( !is_valid_ip(trim($_POST[$field])) ) {
66         $errors[] = "$desc is not a valid address";
67       }
68     }
69     
70     if( !is_valid_network_addr($network,$netmask) ) {
71       $errors[] = "The network address does not match the netmask";
72     }
73   }
74   
75   if( $hostname == "" ) {
76     $errors[] = "Hostname is required";
77   }
78   if( $ip == "" ) {
79     $errors[] = "IP is required";
80   } else if ( ! is_valid_ip ($ip)) {
81     $errors []= "Invalid IP $ip";
82   }
83   
84   if( !empty($errors) ) {
85     drupal_set_error(plc_itemize($errors));
86   } else {
87     // add new node and its interface
88     $node_fields= array( "hostname"=>$hostname, "model"=>$model , "node_type" => $node_type);
89     $node_id= $api->AddNode( intval( $site_id ), $node_fields );
90
91     if ( empty($node_id) || ($node_id < 0) ) {
92       drupal_set_error ("AddNode failed - hostname already present, or not valid ?");
93     } else {
94       // now, try to add the network.
95       $interface_fields= array();
96       $interface_fields['is_primary']= true;
97       $interface_fields['ip']= $ip;
98       $interface_fields['type']= $_POST['type'];
99       $interface_fields['method']= $method;
100       if (!empty($bwlimit)) 
101         $interface_fields['bwlimit']=$bwlimit;
102     
103       if ( $method == 'static' ) {
104         $interface_fields['netmask']= $netmask;
105         $interface_fields['network']= $network;
106         $interface_fields['broadcast']= $broadcast;
107         $interface_fields['gateway']= $gateway;
108         $interface_fields['dns1']= $dns1;
109         if (!empty($dns2)) 
110           $interface_fields['dns2']= $dns2;
111       }
112
113       $interface_id= $api->AddInterface( $node_id, $interface_fields);
114       if ($interface_id > 0) {
115         drupal_set_message ("Node successfully created");
116         drupal_set_message ("Download a boot image in the 'Download' drop down below");
117         plc_redirect (l_node($node_id));
118       } else {
119         // if AddInterface fails, we have the node created,
120         // but no primary interface is present.
121         // The primary interface can be added later,
122         // but take a look at the possible Methods,
123         // if we specify TUN/TAP Method we will have
124         // an error on download of the configuration file
125         drupal_set_message ("Node created");
126         drupal_set_error ("But without an interface");
127         drupal_set_error ("Please review manually");
128         plc_redirect (l_node($node_id));
129       }
130     }
131   }
132 }
133
134 // Print header
135 require_once 'plc_drupal.php';
136 include 'plc_header.php';
137
138 // include javacsript helpers
139 require_once 'prototype.php';
140 drupal_set_html_head ('
141 <script type="text/javascript" src="/planetlab/nodes/interface.js"></script>
142 ');
143
144 drupal_set_title('Add a new node to site');
145
146 // defaults
147 $model = $_POST['model'];
148 if( ! $model ) $model= "Custom";
149
150 $node_type = $_POST['node_type'];
151 if ( ! $node_type ) $node_type= "regular";
152
153 $method = $_POST['method'];
154 if( ! $method ) $method= "static";
155
156 print <<< EOF
157 <p class='node_add'>
158 This page lets you declare a new machine to a site.
159 <br/>
160 This must be done before the machine is turned on, 
161 as it will allow you to download a boot image when complete for this node.
162 <br/>
163 It is now reserved to admins, as regular users are supposed to use the register wizard, that among other things enforces PCU deployment.
164 <br/>
165 An IP address is required even if you use DHCP.
166 </p>
167 EOF;
168
169 $toggle = new PlekitToggle ('add-node',"Add Node",
170                             array('bubble'=>'Add a node - does not enforce PCU - for admins only !',
171                                   'visible'=>get_arg('show_details',true)));
172 $toggle->start();
173
174 $details=new PlekitDetails($has_privileges);
175
176 // xxx hardwire network type for now
177 $form_variables = array('type'=>"ipv4");
178 //$form=$details->form_start(l_actions(),$form_variables);
179 $form=$details->form_start('/db/nodes/node_add.php',$form_variables,
180                            array('onSubmit'=>'return interfaceSubmit()'));
181
182 $details->start();
183
184 $site_columns=array( "site_id", "name", "login_base" );
185 $local_sites= $api->GetSites( array("peer_id"=>NULL, '-SORT'=>'name'), $site_columns );
186 function site_selector($site) { return array('display'=>$site['name'],"value"=>$site['site_id']); }
187 $site_selector = array_map ("site_selector",$local_sites);
188 $site_select = $form->select_html("site_id", $site_selector, array('id'=>'site_id'));
189 $details->th_td("Site",
190                 $site_select,
191                 "site_id",
192                 array('input_type'=>'select','value'=>$interface['site_id']));
193
194 $details->th_td("Hostname",$hostname,"hostname");
195 $details->th_td("Model",$model,"model");
196 $node_type_select = $form->select_html ("node_type",
197                                        node_type_selectors($api,$node_type),
198                                        array('id'=>'node_type'));
199 $details->th_td("Reservation",$node_type_select,"node_type",
200                 array('input_type'=>'select','value'=>$node_type));
201 $method_select = $form->select_html ("method",
202                                      interface_method_selectors($api,$method,true),
203                                      array('id'=>'method',
204                                            'onChange'=>'updateMethodFields()'));
205 $details->th_td("Method",$method_select,"method",
206                 array('input_type'=>'select','value'=>$interface['method']));
207
208 // dont display the 'type' selector as it contains only ipv4
209 //>>> GetNetworkTypes()
210 //[u'ipv4']
211
212 $details->th_td("IP address",$ip,"ip",array('width'=>15,
213                                             'onKeyup'=>'networkHelper()',
214                                             'onChange'=>'networkHelper()'));
215 $details->th_td("Netmask",$netmask,"netmask",array('width'=>15,
216                                                    'onKeyup'=>'networkHelper()',
217                                                    'onChange'=>'networkHelper()'));
218 $details->th_td("Network",$network,"network",array('width'=>15));
219 $details->th_td("Broadcast",$broadcast,"broadcast",array('width'=>15));
220 $details->th_td("Gateway",$gateway,"gateway",array('width'=>15,
221                                                    'onChange'=>'subnetChecker("gateway",false)'));
222 $details->th_td("DNS 1",$dns1,"dns1",array('width'=>15,
223                                            'onChange'=>'subnetChecker("dns1",false)'));
224 $details->th_td("DNS 2",$dns2,"dns2",array('width'=>15,
225                                            'onChange'=>'subnetChecker("dns2",true)'));
226 $details->space();
227 $details->th_td("BW limit (bps)",$bwlimit,"bwlimit",array('width'=>11));
228
229 // the buttons
230 $add_button = $form->submit_html ("add-node","Add New Node");
231 $details->tr($add_button,"right");
232
233 $form->end();
234 $details->end();
235 $toggle->end();
236
237 // Print footer
238 include 'plc_footer.php';
239
240 ?>