r3146 - maintenance->trunk sync of changesets 3143~3145
[racktables] / upgrade.php
CommitLineData
6dc745d2 1<?php
fbbb74fb 2
90b96ff6
DO
3$relnotes = array
4(
2c9fde3a
DO
5 '0.17.0' => "LDAP options have been moved to LDAP_options array. This means, that if you were<br>" .
6 "using LDAP authentication for users in version 0.16.x, it will break right after<br>" .
aca5a846 7 "upgrade to 0.17.0. To get things working again, adjust existing secret.php file<br>" .
2c9fde3a 8 "according to secret-sample.php file provided with 0.17.0 release.<br><br>" .
204284ba 9 "Another change is the addition of support for file uploads. Files are stored<br>" .
90b96ff6 10 "in the database. There are several settings in php.ini which you may need to modify:<br>" .
4114697d
DO
11 "<ul><li>file_uploads - needs to be On</li>" .
12 "<li>upload_max_filesize - max size for uploaded files</li>" .
a476909e 13 "<li>post_max_size - max size of all form data submitted via POST (including files)</li></ul><br>" .
b82cce3f 14 "Local user accounts used to have 'enabled' flag, which allowed individual blocking and<br>" .
a476909e
DO
15 "unblocking of each. This flag was dropped in favor of existing mean of access<br>" .
16 "setup (RackCode). An unconditional denying rule is automatically added into RackCode<br>" .
17 "for such blocked account, so the effective security policy remains the same.<br>",
90b96ff6
DO
18);
19
fbbb74fb
DO
20// At the moment we assume, that for any two releases we can
21// sequentally execute all batches, that separate them, and
22// nothing will break. If this changes one day, the function
23// below will have to generate smarter upgrade paths, while
24// the upper layer will remain the same.
25// Returning an empty array means that no upgrade is necessary.
4114697d 26// Returning NULL indicates an error.
fbbb74fb
DO
27function getDBUpgradePath ($v1, $v2)
28{
a6f83a72
DO
29 $versionhistory = array
30 (
b3f866fc 31 '0.16.4',
64347dcf 32 '0.16.5',
90b96ff6 33 '0.16.6',
30d0a2a3 34 '0.17.0',
4563cecb 35 '0.17.1',
7b1a3a72 36 '0.17.2',
9e51318b 37 '0.17.3',
958ac06d 38 '0.17.4',
9f572fb5 39 '0.17.5',
a6f83a72 40 );
120e9ddd
DO
41 if (!in_array ($v1, $versionhistory) or !in_array ($v2, $versionhistory))
42 return NULL;
fbbb74fb 43 $skip = TRUE;
4114697d 44 $path = NULL;
fbbb74fb
DO
45 // Now collect all versions > $v1 and <= $v2
46 foreach ($versionhistory as $v)
47 {
4114697d 48 if ($skip and $v == $v1)
fbbb74fb
DO
49 {
50 $skip = FALSE;
4114697d 51 $path = array();
fbbb74fb
DO
52 continue;
53 }
54 if ($skip)
55 continue;
56 $path[] = $v;
57 if ($v == $v2)
58 break;
59 }
60 return $path;
61}
62
90b96ff6
DO
63// Upgrade batches are named exactly as the release where they first appear.
64// That is simple, but seems sufficient for beginning.
fbbb74fb
DO
65function executeUpgradeBatch ($batchid)
66{
67 $query = array();
ca3d68bd 68 global $dbxlink;
fbbb74fb
DO
69 switch ($batchid)
70 {
64347dcf
DO
71 case '0.16.5':
72 $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, description) VALUES ('IPV4_TREE_SHOW_USAGE','yes','string','no','no','Show address usage in IPv4 tree')";
73 $query[] = "update Config set varvalue = '0.16.5' where varname = 'DB_VERSION'";
74 break;
90b96ff6
DO
75 case '0.16.6':
76 $query[] = "update Config set varvalue = '0.16.6' where varname = 'DB_VERSION'";
77 break;
30d0a2a3 78 case '0.17.0':
e1ae3fb4
AD
79 // create tables for storing files (requires InnoDB support)
80 if (!isInnoDBSupported ())
81 {
5d168fde 82 showFailure ("Cannot upgrade because InnoDB tables are not supported by your MySQL server. See the README for details.", __FILE__);
f3c50166 83 die;
e1ae3fb4 84 }
f76c4197
DY
85
86 $query[] = "alter table Chapter change chapter_no id int(10) unsigned NOT NULL auto_increment";
87 $query[] = "alter table Chapter change chapter_name name char(128) NOT NULL";
88 $query[] = "alter table Chapter drop key chapter_name";
89 $query[] = "alter table Chapter add UNIQUE KEY name (name)";
90 $query[] = "alter table Attribute change attr_id id int(10) unsigned NOT NULL auto_increment";
91 $query[] = "alter table Attribute change attr_type type enum('string','uint','float','dict') default NULL";
92 $query[] = "alter table Attribute change attr_name name char(64) default NULL";
93 $query[] = "alter table Attribute drop key attr_name";
94 $query[] = "alter table Attribute add UNIQUE KEY name (name)";
95 $query[] = "alter table AttributeMap change chapter_no chapter_id int(10) unsigned NOT NULL";
96 $query[] = "alter table Dictionary change chapter_no chapter_id int(10) unsigned NOT NULL";
3fb336f6 97 // Only after the above call it is Ok to use reloadDictionary()
ca3d68bd 98 $query = array_merge ($query, reloadDictionary ($batchid));
f3c50166 99 // schema changes for file management
e1ae3fb4
AD
100 $query[] = "
101CREATE TABLE `File` (
102 `id` int(10) unsigned NOT NULL auto_increment,
103 `name` char(255) NOT NULL,
104 `type` char(255) NOT NULL,
105 `size` int(10) unsigned NOT NULL,
106 `ctime` datetime NOT NULL,
107 `mtime` datetime NOT NULL,
108 `atime` datetime NOT NULL,
109 `contents` longblob NOT NULL,
110 `comment` text,
13edfa1c
AD
111 PRIMARY KEY (`id`),
112 UNIQUE KEY `name` (`name`)
e1ae3fb4
AD
113) ENGINE=InnoDB";
114 $query[] = "
115CREATE TABLE `FileLink` (
116 `id` int(10) unsigned NOT NULL auto_increment,
117 `file_id` int(10) unsigned NOT NULL,
118 `entity_type` enum('ipv4net','ipv4rspool','ipv4vs','object','rack','user') NOT NULL default 'object',
119 `entity_id` int(10) NOT NULL,
120 PRIMARY KEY (`id`),
af721881 121 UNIQUE KEY `FileLink-unique` (`file_id`,`entity_type`,`entity_id`),
e1ae3fb4
AD
122 KEY `FileLink-file_id` (`file_id`),
123 CONSTRAINT `FileLink-File_fkey` FOREIGN KEY (`file_id`) REFERENCES `File` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
124) ENGINE=InnoDB";
125 $query[] = "ALTER TABLE TagStorage MODIFY COLUMN target_realm enum('file','ipv4net','ipv4rspool','ipv4vs','object','rack','user') NOT NULL default 'object'";
f3c50166 126
f76c4197 127 $query[] = "INSERT INTO `Chapter` (`id`, `sticky`, `name`) VALUES (24,'no','network security models')";
9730d09f 128 $query[] = "INSERT INTO `Chapter` (`id`, `sticky`, `name`) VALUES (25,'no','wireless models')";
f76c4197
DY
129 $query[] = "INSERT INTO `AttributeMap` (`objtype_id`, `attr_id`, `chapter_id`) VALUES (798,1,0)";
130 $query[] = "INSERT INTO `AttributeMap` (`objtype_id`, `attr_id`, `chapter_id`) VALUES (798,2,24)";
131 $query[] = "INSERT INTO `AttributeMap` (`objtype_id`, `attr_id`, `chapter_id`) VALUES (798,3,0)";
132 $query[] = "INSERT INTO `AttributeMap` (`objtype_id`, `attr_id`, `chapter_id`) VALUES (798,5,0)";
133 $query[] = "INSERT INTO `AttributeMap` (`objtype_id`, `attr_id`, `chapter_id`) VALUES (798,14,0)";
134 $query[] = "INSERT INTO `AttributeMap` (`objtype_id`, `attr_id`, `chapter_id`) VALUES (798,16,0)";
135 $query[] = "INSERT INTO `AttributeMap` (`objtype_id`, `attr_id`, `chapter_id`) VALUES (798,17,0)";
136 $query[] = "INSERT INTO `AttributeMap` (`objtype_id`, `attr_id`, `chapter_id`) VALUES (798,18,0)";
137 $query[] = "INSERT INTO `AttributeMap` (`objtype_id`, `attr_id`, `chapter_id`) VALUES (798,20,0)";
138 $query[] = "INSERT INTO `AttributeMap` (`objtype_id`, `attr_id`, `chapter_id`) VALUES (798,21,0)";
139 $query[] = "INSERT INTO `AttributeMap` (`objtype_id`, `attr_id`, `chapter_id`) VALUES (798,22,0)";
140 $query[] = "INSERT INTO `AttributeMap` (`objtype_id`, `attr_id`, `chapter_id`) VALUES (798,24,0)";
9730d09f
DO
141 $query[] = "INSERT INTO `AttributeMap` (`objtype_id`, `attr_id`, `chapter_id`) VALUES (965,1,0)";
142 $query[] = "INSERT INTO `AttributeMap` (`objtype_id`, `attr_id`, `chapter_id`) VALUES (965,3,0)";
143 $query[] = "INSERT INTO `AttributeMap` (`objtype_id`, `attr_id`, `chapter_id`) VALUES (965,2,25)";
706ce117
DO
144 $query[] = 'alter table IPBonds rename to IPv4Allocation';
145 $query[] = 'alter table PortForwarding rename to IPv4NAT';
146 $query[] = 'alter table IPRanges rename to IPv4Network';
147 $query[] = 'alter table IPAddress rename to IPv4Address';
148 $query[] = 'alter table IPLoadBalancer rename to IPv4LB';
4114697d 149 $query[] = 'alter table IPRSPool rename to IPv4RSPool';
706ce117 150 $query[] = 'alter table IPRealServer rename to IPv4RS';
4114697d 151 $query[] = 'alter table IPVirtualService rename to IPv4VS';
120e9ddd
DO
152 $query[] = "alter table TagStorage change column target_realm entity_realm enum('file','ipv4net','ipv4vs','ipv4rspool','object','rack','user') NOT NULL default 'object'";
153 $query[] = 'alter table TagStorage change column target_id entity_id int(10) unsigned NOT NULL';
154 $query[] = 'alter table TagStorage drop key entity_tag';
155 $query[] = 'alter table TagStorage drop key target_id';
156 $query[] = 'alter table TagStorage add UNIQUE KEY `entity_tag` (`entity_realm`,`entity_id`,`tag_id`)';
157 $query[] = 'alter table TagStorage add KEY `entity_id` (`entity_id`)';
37e59768
DO
158 $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, description) VALUES ('PREVIEW_TEXT_MAXCHARS','10240','uint','yes','no','Max chars for text file preview')";
159 $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, description) VALUES ('PREVIEW_TEXT_ROWS','25','uint','yes','no','Rows for text file preview')";
160 $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, description) VALUES ('PREVIEW_TEXT_COLS','80','uint','yes','no','Columns for text file preview')";
161 $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, description) VALUES ('PREVIEW_IMAGE_MAXPXS','320','uint','yes','no','Max pixels per axis for image file preview')";
f3d274bf 162 $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, description) VALUES ('VENDOR_SIEVE','','string','yes','no','Vendor sieve configuration')";
073ed463
DO
163 $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, description) VALUES ('IPV4LB_LISTSRC','{\$typeid_4}','string','yes','no','List source: IPv4 load balancers')";
164 $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, description) VALUES ('IPV4OBJ_LISTSRC','{\$typeid_4} or {\$typeid_7} or {\$typeid_8} or {\$typeid_12} or {\$typeid_445} or {\$typeid_447}','string','yes','no','List source: IPv4-enabled objects')";
165 $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, description) VALUES ('IPV4NAT_LISTSRC','{\$typeid_4} or {\$typeid_7} or {\$typeid_8}','string','yes','no','List source: IPv4 NAT performers')";
166 $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, description) VALUES ('ASSETWARN_LISTSRC','{\$typeid_4} or {\$typeid_7} or {\$typeid_8}','string','yes','no','List source: object, for which asset tag should be set')";
167 $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, description) VALUES ('NAMEWARN_LISTSRC','{\$typeid_4} or {\$typeid_7} or {\$typeid_8}','string','yes','no','List source: object, for which common name should be set')";
f5883ec1 168 $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, description) VALUES ('RACKS_PER_ROW','12','unit','yes','no','Racks per row')";
590e1281 169 $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, description) VALUES ('FILTER_PREDICATE_SIEVE','','string','yes','no','Predicate sieve regex(7)')";
5496c89f
DO
170 $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, description) VALUES ('FILTER_DEFAULT_ANDOR','or','string','no','no','Default list filter boolean operation (or/and)')";
171 $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, description) VALUES ('FILTER_SUGGEST_ANDOR','yes','string','no','no','Suggest and/or selector in list filter')";
172 $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, description) VALUES ('FILTER_SUGGEST_TAGS','yes','string','no','no','Suggest tags in list filter')";
173 $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, description) VALUES ('FILTER_SUGGEST_PREDICATES','yes','string','no','no','Suggest predicates in list filter')";
174 $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, description) VALUES ('FILTER_SUGGEST_EXTRA','no','string','no','no','Suggest extra expression in list filter')";
529eac25
DO
175 $query[] = "delete from Config where varname = 'USER_AUTH_SRC'";
176 $query[] = "delete from Config where varname = 'COOKIE_TTL'";
177 $query[] = "delete from Config where varname = 'rtwidth_0'";
178 $query[] = "delete from Config where varname = 'rtwidth_1'";
179 $query[] = "delete from Config where varname = 'rtwidth_2'";
c6bc0ac5
DO
180 $query[] = "delete from Config where varname = 'NAMEFUL_OBJTYPES'";
181 $query[] = "delete from Config where varname = 'REQUIRE_ASSET_TAG_FOR'";
182 $query[] = "delete from Config where varname = 'IPV4_PERFORMERS'";
183 $query[] = "delete from Config where varname = 'NATV4_PERFORMERS'";
dbb33805 184 $query[] = "alter table TagTree add column valid_realm set('file','ipv4net','ipv4vs','ipv4rspool','object','rack','user') not null default 'file,ipv4net,ipv4vs,ipv4rspool,object,rack,user' after parent_id";
a476909e
DO
185 $result = $dbxlink->query ("select user_id, user_name, user_realname from UserAccount where user_enabled = 'no'");
186 while ($row = $result->fetch (PDO::FETCH_ASSOC))
187 $query[] = "update Script set script_text = concat('deny {\$userid_${row['user_id']}} # ${row['user_name']} (${row['user_realname']})\n', script_text) where script_name = 'RackCode'";
188 $query[] = "update Script set script_text = NULL where script_name = 'RackCodeCache'";
189 unset ($result);
79b8ad1e 190 $query[] = "alter table UserAccount drop column user_enabled";
f76c4197 191
10bac82a
DY
192 $query[] = "CREATE TABLE RackRow ( id int(10) unsigned NOT NULL auto_increment, name char(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM";
193
9f14a7ef
DY
194 $result = $dbxlink->query ("select dict_key, dict_value from Dictionary where chapter_no = 3");
195 while($row = $result->fetch(PDO::FETCH_NUM))
10bac82a 196 $query[] = "insert into RackRow set id=${row[0]}, name='${row[1]}'";
ee286837 197 unset ($result);
f76c4197 198 $query[] = "delete from Dictionary where chapter_id = 3";
c4d0dc30 199 $query[] = "delete from Chapter where id = 3";
9133d2c5
DO
200 $query[] = "
201CREATE TABLE `LDAPCache` (
202 `presented_username` char(64) NOT NULL,
203 `successful_hash` char(40) NOT NULL,
204 `first_success` timestamp NOT NULL default CURRENT_TIMESTAMP,
205 `last_retry` timestamp NOT NULL default '0000-00-00 00:00:00',
206 `displayed_name` char(128) default NULL,
207 `memberof` text,
208 UNIQUE KEY `presented_username` (`presented_username`),
209 KEY `scanidx` (`presented_username`,`successful_hash`)
210) ENGINE=InnoDB;";
3827da34 211 $query[] = "alter table UserAccount modify column user_password_hash char(40) NULL";
aa9a0fb4
DO
212 $query[] = 'ALTER TABLE Rack DROP COLUMN deleted';
213 $query[] = 'ALTER TABLE RackHistory DROP COLUMN deleted';
214 $query[] = 'ALTER TABLE RackObject DROP COLUMN deleted';
215 $query[] = 'ALTER TABLE RackObjectHistory DROP COLUMN deleted';
2fb9d280
DO
216 // Can't be added straight due to many duplicates, even in "dictbase" data.
217 $result = $dbxlink->query ('SELECT type1, type2, count(*) - 1 as excess FROM PortCompat GROUP BY type1, type2 HAVING excess > 0');
218 while ($row = $result->fetch (PDO::FETCH_ASSOC))
219 $query[] = "DELETE FROM PortCompat WHERE type1 = ${row['type1']} AND type2 = ${row['type2']} limit ${row['excess']}";
220 unset ($result);
221 $query[] = 'ALTER TABLE PortCompat DROP KEY type1';
67d8a969 222 $query[] = 'ALTER TABLE PortCompat ADD UNIQUE `type1_2` (type1, type2)';
f76c4197
DY
223 $query[] = "UPDATE Config SET varvalue = '0.17.0' WHERE varname = 'DB_VERSION'";
224
b3f866fc 225 break;
4563cecb 226 case '0.17.1':
8b200a9c 227 $query[] = "ALTER TABLE Dictionary DROP KEY `chap_to_key`";
ca3d68bd 228 $query = array_merge ($query, reloadDictionary ($batchid));
4563cecb
DO
229 // Token set has changed, so the cache isn't valid any more.
230 $query[] = "UPDATE Script SET script_text = NULL WHERE script_name = 'RackCodeCache'";
231 $query[] = "UPDATE Config SET varvalue = '0.17.1' WHERE varname = 'DB_VERSION'";
7d4ea62b 232 break;
7b1a3a72 233 case '0.17.2':
7b1a3a72 234 $query[] = "INSERT INTO `Chapter` (`id`, `sticky`, `name`) VALUES (26,'no','fibre channel switch models')";
ca3d68bd 235 $query = array_merge ($query, reloadDictionary ($batchid));
7c537f33 236 $query[] = "INSERT INTO `AttributeMap` (`objtype_id`, `attr_id`, `chapter_id`) VALUES (1055,2,26)";
49b605d9 237 $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, description) VALUES ('DEFAULT_SNMP_COMMUNITY','public','string','no','no','Default SNMP Community string')";
29c3a4d8
DO
238 // wipe irrelevant records (ticket:250)
239 $query[] = "DELETE FROM TagStorage WHERE entity_realm = 'file' AND entity_id NOT IN (SELECT id FROM File)";
f06fe423 240 $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, description) VALUES ('IPV4_ENABLE_KNIGHT','yes','string','no','no','Enable IPv4 knight feature')";
99ab184f 241 $query[] = "ALTER TABLE IPv4Network ADD COLUMN comment text AFTER name";
5163cd3a 242 $query[] = "ALTER TABLE Port ADD INDEX comment (reservation_comment)";
029a14bc
DO
243 $query[] = "ALTER TABLE Port DROP KEY l2address"; // UNIQUE
244 $query[] = "ALTER TABLE Port ADD KEY (l2address)"; // not UNIQUE
948666cc
DO
245 $query[] = "ALTER TABLE Port DROP KEY object_id";
246 $query[] = "ALTER TABLE Port ADD UNIQUE KEY per_object (object_id, name, type)";
74aee2dc
DO
247 $query[] = "INSERT INTO PortCompat (type1, type2) VALUES (20,1083)";
248 $query[] = "INSERT INTO PortCompat (type1, type2) VALUES (21,1083)";
249 $query[] = "INSERT INTO PortCompat (type1, type2) VALUES (1077,1077)";
250 $query[] = "INSERT INTO PortCompat (type1, type2) VALUES (1083,20)";
251 $query[] = "INSERT INTO PortCompat (type1, type2) VALUES (1083,21)";
252 $query[] = "INSERT INTO PortCompat (type1, type2) VALUES (1083,1083)";
1c4830dc 253 $query[] = "INSERT INTO PortCompat (type1, type2) VALUES (1087,1087)";
50e02490
DO
254 $query[] = "INSERT INTO `Chapter` (`id`, `sticky`, `name`) VALUES (27,'no','PDU models')";
255 $query[] = "INSERT INTO `AttributeMap` (`objtype_id`, `attr_id`, `chapter_id`) VALUES (2,2,27)";
7b1a3a72
AD
256 $query[] = "UPDATE Config SET varvalue = '0.17.2' WHERE varname = 'DB_VERSION'";
257 break;
9e51318b
DO
258 case '0.17.3':
259 $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, description) VALUES ('TAGS_TOPLIST_SIZE','50','uint','yes','no','Tags top list size')";
260 $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, description) VALUES ('TAGS_QUICKLIST_SIZE','20','uint','no','no','Tags quick list size')";
261 $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, description) VALUES ('TAGS_QUICKLIST_THRESHOLD','50','uint','yes','no','Tags quick list threshold')";
87601bbc 262 $query[] = "ALTER TABLE AttributeMap MODIFY COLUMN chapter_id int(10) unsigned NULL";
7028a42c 263 $query[] = "UPDATE AttributeMap SET chapter_id = NULL WHERE attr_id IN (SELECT id FROM Attribute WHERE type != 'dict')";
a013838b
DO
264 // ticket:239
265 $query[] = 'UPDATE AttributeValue SET uint_value = 1018 WHERE uint_value = 731 AND attr_id IN (SELECT attr_id FROM AttributeMap WHERE chapter_id = 12)';
266 $query[] = 'DELETE FROM Dictionary WHERE dict_key = 731';
084aca6c
DO
267 $query = array_merge ($query, reloadDictionary ($batchid));
268 $query[] = "UPDATE Config SET vartype='uint' WHERE varname='RACKS_PER_ROW'";
f44fdef9 269 $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, description) VALUES ('ENABLE_MULTIPORT_FORM','no','string','no','no','Enable \"Add/update multiple ports\" form')";
9e51318b
DO
270 $query[] = "UPDATE Config SET varvalue = '0.17.3' WHERE varname = 'DB_VERSION'";
271 break;
958ac06d
DO
272 case '0.17.4':
273 $query[] = "ALTER TABLE Link ENGINE=InnoDB";
274 $query[] = "ALTER TABLE Port ENGINE=InnoDB";
4d87feaf
DO
275 $query[] = "ALTER TABLE IPv4RS ENGINE=InnoDB";
276 $query[] = "ALTER TABLE IPv4RSPool ENGINE=InnoDB";
cafd4cf3
DO
277 $query[] = "ALTER TABLE AttributeValue ENGINE=InnoDB";
278 $query[] = "ALTER TABLE RackObject ENGINE=InnoDB";
279 $query[] = "ALTER TABLE IPv4NAT ENGINE=InnoDB";
280 $query[] = "ALTER TABLE IPv4LB ENGINE=InnoDB";
281 $query[] = "ALTER TABLE IPv4VS ENGINE=InnoDB";
4d87feaf 282 $query[] = "DELETE FROM IPv4RS WHERE rspool_id NOT IN (SELECT id FROM IPv4RSPool)";
958ac06d 283 $query[] = "ALTER TABLE Link ADD CONSTRAINT `Link-FK-b` FOREIGN KEY (portb) REFERENCES Port (id)";
cafd4cf3 284 $query[] = "ALTER TABLE Link ADD CONSTRAINT `Link-FK-a` FOREIGN KEY (porta) REFERENCES Port (id)";
4d87feaf 285 $query[] = "ALTER TABLE IPv4RS ADD CONSTRAINT `IPv4RS-FK` FOREIGN KEY (rspool_id) REFERENCES IPv4RSPool (id) ON DELETE CASCADE";
cafd4cf3
DO
286 $query[] = "ALTER TABLE AttributeValue ADD CONSTRAINT `AttributeValue-FK-object_id` FOREIGN KEY (object_id) REFERENCES RackObject (id)";
287 $query[] = "ALTER TABLE IPv4NAT ADD CONSTRAINT `IPv4NAT-FK-object_id` FOREIGN KEY (object_id) REFERENCES RackObject (id)";
288 $query[] = "ALTER TABLE Port ADD CONSTRAINT `Port-FK-object_id` FOREIGN KEY (object_id) REFERENCES RackObject (id)";
289 $query[] = "ALTER TABLE IPv4LB ADD CONSTRAINT `IPv4LB-FK-rspool_id` FOREIGN KEY (rspool_id) REFERENCES IPv4RSPool (id)";
290 $query[] = "ALTER TABLE IPv4LB ADD CONSTRAINT `IPv4LB-FK-object_id` FOREIGN KEY (object_id) REFERENCES RackObject (id)";
291 $query[] = "ALTER TABLE IPv4LB ADD CONSTRAINT `IPv4LB-FK-vs_id` FOREIGN KEY (vs_id) REFERENCES IPv4VS (id)";
e49d8a77 292 $query = array_merge ($query, reloadDictionary ($batchid));
958ac06d
DO
293 $query[] = "UPDATE Config SET varvalue = '0.17.4' WHERE varname = 'DB_VERSION'";
294 break;
9f572fb5
DO
295 case '0.17.5':
296 $query[] = "ALTER TABLE TagTree ENGINE=InnoDB";
297 $query[] = "ALTER TABLE TagStorage ENGINE=InnoDB";
298 $query[] = "ALTER TABLE TagStorage ADD CONSTRAINT `TagStorage-FK-tag_id` FOREIGN KEY (tag_id) REFERENCES TagTree (id)";
299 $query[] = "ALTER TABLE TagTree ADD CONSTRAINT `TagTree-K-parent_id` FOREIGN KEY (parent_id) REFERENCES TagTree (id)";
2400d7ec
DO
300 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (21,1195)';
301 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (22,1196)';
302 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (23,1196)';
303 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (20,1195)';
304 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (25,1202)';
305 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (26,1202)';
306 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (27,1204)';
307 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (28,1204)';
308 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (1083,1195)';
309 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (1084,1084)';
310 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (1195,20)';
311 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (1195,21)';
312 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (1195,1083)';
313 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (1195,1195)';
314 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (1196,22)';
315 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (1196,23)';
316 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (1196,1196)';
317 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (1197,1197)';
318 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (1198,1199)';
319 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (1199,1198)';
320 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (1200,1200)';
321 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (1201,1201)';
322 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (1202,25)';
323 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (1202,26)';
324 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (1202,1202)';
325 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (1203,1203)';
326 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (1204,27)';
327 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (1204,28)';
328 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (1204,1204)';
329 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (1205,1205)';
330 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (1206,1207)';
331 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (1207,1206)';
93a83f51 332 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (1316,1316)';
bdc91a5c
DO
333 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (16, 1322)';
334 $query[] = 'INSERT INTO PortCompat (type1, type2) VALUES (1322, 16)';
335 $query[] = 'DELETE FROM PortCompat WHERE type1 = 16 AND type2 = 16';
2400d7ec
DO
336 for ($i = 1209; $i <= 1300; $i++)
337 $query[] = "INSERT INTO PortCompat (type1, type2) VALUES (${i}, ${i})";
d9b88ea0 338 $query[] = "
09d6afa4 339CREATE TABLE `PortInnerInterface` (
9173281a 340 `id` int(10) unsigned NOT NULL,
d9b88ea0
DO
341 `iif_name` char(16) NOT NULL,
342 PRIMARY KEY (`id`),
9173281a 343 UNIQUE KEY `iif_name` (`iif_name`)
d9b88ea0 344) ENGINE=InnoDB";
2400d7ec
DO
345 $query[] = "INSERT INTO `PortInnerInterface` VALUES (1,'hardwired')";
346 $query[] = "INSERT INTO `PortInnerInterface` VALUES (2,'SFP-100')";
347 $query[] = "INSERT INTO `PortInnerInterface` VALUES (3,'GBIC')";
348 $query[] = "INSERT INTO `PortInnerInterface` VALUES (4,'SFP-1000')";
349 $query[] = "INSERT INTO `PortInnerInterface` VALUES (5,'XENPAK')";
350 $query[] = "INSERT INTO `PortInnerInterface` VALUES (6,'X2')";
351 $query[] = "INSERT INTO `PortInnerInterface` VALUES (7,'XPAK')";
352 $query[] = "INSERT INTO `PortInnerInterface` VALUES (8,'XFP')";
353 $query[] = "INSERT INTO `PortInnerInterface` VALUES (9,'SFP+')";
d9b88ea0 354 $query[] = "
09d6afa4 355CREATE TABLE `PortInterfaceCompat` (
d9b88ea0
DO
356 `iif_id` int(10) unsigned NOT NULL,
357 `oif_id` int(10) unsigned NOT NULL,
358 UNIQUE KEY `pair` (`iif_id`,`oif_id`),
2400d7ec 359 CONSTRAINT `PortInterfaceCompat-FK-iif_id` FOREIGN KEY (`iif_id`) REFERENCES `PortInnerInterface` (`id`)
d9b88ea0 360) ENGINE=InnoDB";
c76cfa0d
DO
361 $query[] = "ALTER TABLE Port ADD COLUMN iif_id int unsigned NOT NULL AFTER name"; // will set iif_id to 0
362 $query[] = "UPDATE Port SET iif_id = 2 WHERE type = 1208";
363 $query[] = "UPDATE Port SET iif_id = 3 WHERE type = 1078";
364 $query[] = "UPDATE Port SET iif_id = 4 WHERE type = 1077";
365 $query[] = "UPDATE Port SET iif_id = 5 WHERE type = 1079";
366 $query[] = "UPDATE Port SET iif_id = 6 WHERE type = 1080";
367 $query[] = "UPDATE Port SET iif_id = 7 WHERE type = 1081";
368 $query[] = "UPDATE Port SET iif_id = 8 WHERE type = 1082";
369 $query[] = "UPDATE Port SET iif_id = 9 WHERE type = 1084";
370 $query[] = "UPDATE Port SET iif_id = 1 WHERE iif_id = 0";
08aa3467
DO
371 $query[] = 'ALTER TABLE Port ADD UNIQUE `object_iif_oif_name` (object_id, iif_id, type, name)';
372 $query[] = 'ALTER TABLE Port DROP KEY `per_object`';
2400d7ec
DO
373 $base1000 = array (24, 34, 1202, 1203, 1204, 1205, 1206, 1207);
374 $base10000 = array (30, 35, 36, 37, 38, 39, 40);
375 $PICdata = array
376 (
bdc91a5c 377 1 => array (16, 19, 24, 29, 31, 33, 446, 681, 682, 1322),
2400d7ec
DO
378 2 => array (1208, 1195, 1196, 1197, 1198, 1199, 1200, 1201),
379 3 => array_merge (array (1078), $base1000),
380 4 => array_merge (array (1077), $base1000),
381 5 => array_merge (array (1079), $base10000),
382 6 => array_merge (array (1080), $base10000),
383 7 => array_merge (array (1081), $base10000),
384 8 => array_merge (array (1082), $base10000),
385 9 => array_merge (array (1084), $base10000),
386 );
387 // make sure all IIF/OIF pairs referenced from Port exist in PortInterfaceCompat before enabling FK
388 // iif_id doesn't exist at this point
389 $result = $dbxlink->query ('SELECT DISTINCT type FROM Port WHERE type NOT IN (1208, 1078, 1077, 1079, 1080, 1081, 1082, 1084)');
390 while ($row = $result->fetch (PDO::FETCH_ASSOC))
391 if (FALSE === array_search ($row['type'], $PICdata[1]))
392 array_push ($PICdata[1], $row['type']);
393 unset ($result);
394 foreach ($PICdata as $iif_id => $oif_ids)
395 foreach ($oif_ids as $oif_id)
396 $query[] = "INSERT INTO PortInterfaceCompat (iif_id, oif_id) VALUES (${iif_id}, ${oif_id})";
c76cfa0d 397 $query[] = "ALTER TABLE Port ADD CONSTRAINT `Port-FK-iif-oif` FOREIGN KEY (`iif_id`, `type`) REFERENCES `PortInterfaceCompat` (`iif_id`, `oif_id`)";
bdc91a5c 398 $query[] = 'UPDATE Port SET type = 1322 WHERE type = 16 AND (SELECT objtype_id FROM RackObject WHERE id = object_id) IN (2, 12)';
2400d7ec
DO
399 $query = array_merge ($query, reloadDictionary ($batchid));
400 $query[] = "DELETE FROM Config WHERE varname = 'default_port_type'";
401 $query[] = "INSERT INTO Config VALUES ('DEFAULT_PORT_IIF_ID','1','uint','no','no','Default port inner interface ID')";
402 $query[] = "INSERT INTO Config VALUES ('DEFAULT_PORT_OIF_IDS','1=24; 3=1078; 4=1077; 5=1079; 6=1080; 8=1082; 9=1084','string','no','no','Default port outer interface IDs')";
4a47d34b 403 $query[] = "INSERT INTO Config VALUES ('IPV4_TREE_RTR_AS_CELL','yes','string','no','no','Show full router info for each network in IPv4 tree view')";
93a83f51 404 $query[] = "UPDATE Chapter SET name = 'PortOuterInterface' WHERE id = 2";
fbcbb4ee
DO
405 // remap refs to duplicate records, which will be discarded (ticket:286)
406 $query[] = 'UPDATE AttributeValue SET uint_value = 147 WHERE uint_value = 1020 AND attr_id = 2';
407 $query[] = 'UPDATE AttributeValue SET uint_value = 377 WHERE uint_value = 1021 AND attr_id = 2';
e8ab58e8 408 $query[] = 'INSERT INTO AttributeMap (objtype_id, attr_id) VALUES (2, 1), (2, 3), (2, 5)';
9f572fb5
DO
409 $query[] = "UPDATE Config SET varvalue = '0.17.5' WHERE varname = 'DB_VERSION'";
410 break;
fbbb74fb 411 default:
5d168fde 412 showFailure ("executeUpgradeBatch () failed, because batch '${batchid}' isn't defined", __FILE__);
fbbb74fb
DO
413 die;
414 break;
415 }
fbbb74fb 416 $failures = array();
4114697d 417 echo "<tr><th>Executing batch '${batchid}'</th><td>";
fbbb74fb
DO
418 foreach ($query as $q)
419 {
420 $result = $dbxlink->query ($q);
4114697d 421 if ($result == NULL)
758fe24c 422 {
758fe24c
DO
423 $errorInfo = $dbxlink->errorInfo();
424 $failures[] = array ($q, $errorInfo[2]);
425 }
fbbb74fb 426 }
fbbb74fb 427 if (!count ($failures))
4114697d 428 echo "<strong><font color=green>done</font></strong>";
fbbb74fb
DO
429 else
430 {
4114697d 431 echo "<strong><font color=red>The following queries failed:</font></strong><br><pre>";
fbbb74fb
DO
432 foreach ($failures as $f)
433 {
434 list ($q, $i) = $f;
4114697d 435 echo "${q} -- ${i}\n";
fbbb74fb 436 }
4114697d 437 echo "</pre>";
fbbb74fb 438 }
4114697d 439 echo '</td></tr>';
fbbb74fb
DO
440}
441
442// ******************************************************************
443//
444// Execution starts here
445//
446// ******************************************************************
447
5d168fde
DO
448// a clone of showError() to drop dependency on interface.php
449function showFailure ($info = '', $location = 'N/A')
450{
5d168fde
DO
451 if (preg_match ('/\.php$/', $location))
452 $location = basename ($location);
453 elseif ($location != 'N/A')
454 $location = $location . '()';
455 echo "<div class=msg_error>An error has occured in [${location}]. ";
456 if (empty ($info))
457 echo 'No additional information is available.';
458 else
459 echo "Additional information:<br><p>\n<pre>\n${info}\n</pre></p>";
460 echo "This failure is most probably fatal.<br></div>\n";
461}
462
463require_once 'inc/config.php'; // for CODE_VERSION
464require_once 'inc/database.php'; // for getDatabaseVersion()
3fb336f6 465require_once 'inc/dictionary.php';
5d168fde
DO
466// Enforce default value for now, releases prior to 0.17.0 didn't support 'httpd' auth source.
467$user_auth_src = 'database';
fbbb74fb 468
80138748
DO
469if (file_exists ('inc/secret.php'))
470 require_once 'inc/secret.php';
fbbb74fb 471else
80138748
DO
472 die ("Database connection parameters are read from inc/secret.php file, " .
473 "which cannot be found.\nCopy provided inc/secret-sample.php to " .
474 "inc/secret.php and modify to your setup.\n\nThen reload the page.");
fbbb74fb
DO
475
476try
477{
478 $dbxlink = new PDO ($pdo_dsn, $db_username, $db_password);
479}
480catch (PDOException $e)
481{
482 die ("Database connection failed:\n\n" . $e->getMessage());
483}
484
fbbb74fb
DO
485// Now we need to be sure that the current user is the administrator.
486// The rest doesn't matter within this context.
fbbb74fb 487
120e9ddd 488function authenticate_admin ($username, $password)
a1f3710a 489{
43c7895d 490 global $dbxlink;
93bdb7ba 491 $hash = sha1 ($password);
120e9ddd 492 $query = "select count(*) from UserAccount where user_id = 1 and user_name = '${username}' and user_password_hash = '${hash}'";
a1f3710a
DO
493 if (($result = $dbxlink->query ($query)) == NULL)
494 die ('SQL query failed in ' . __FUNCTION__);
120e9ddd 495 $rows = $result->fetchAll (PDO::FETCH_NUM);
43c7895d 496 return $rows[0][0] == 1;
a1f3710a
DO
497}
498
204284ba 499switch ($user_auth_src)
99ee5479 500{
120e9ddd
DO
501 case 'database':
502 case 'ldap': // authenticate against DB as well
503 if
504 (
505 !isset ($_SERVER['PHP_AUTH_USER']) or
506 !strlen ($_SERVER['PHP_AUTH_USER']) or
507 !isset ($_SERVER['PHP_AUTH_PW']) or
508 !strlen ($_SERVER['PHP_AUTH_PW']) or
509 !authenticate_admin (escapeString ($_SERVER['PHP_AUTH_USER']), escapeString ($_SERVER['PHP_AUTH_PW']))
510 )
511 {
512 header ('WWW-Authenticate: Basic realm="RackTables upgrade"');
513 header ('HTTP/1.0 401 Unauthorized');
33bbd712 514 showFailure ('You must be authenticated as an administrator to complete the upgrade.', __FILE__);
120e9ddd
DO
515 die;
516 }
517 break; // cleared
518 case 'httpd':
519 if
520 (
521 !isset ($_SERVER['REMOTE_USER']) or
522 !strlen ($_SERVER['REMOTE_USER'])
523 )
524 {
33bbd712 525 showFailure ('System misconfiguration. The web-server didn\'t authenticate the user, although ought to do.');
120e9ddd
DO
526 die;
527 }
528 break; // cleared
529 default:
33bbd712 530 showFailure ('authentication source misconfiguration', __FILE__);
120e9ddd 531 die;
99ee5479 532}
fbbb74fb
DO
533
534$dbver = getDatabaseVersion();
4114697d
DO
535echo '<table border=1>';
536echo "<tr><th>Current status</th><td>Data version: ${dbver}<br>Code version: " . CODE_VERSION . "</td></tr>\n";
537
538$path = getDBUpgradePath ($dbver, CODE_VERSION);
539if ($path === NULL)
758fe24c 540{
4114697d 541 echo "<tr><th>Upgrade path</th><td><font color=red>not found</font></td></tr>\n";
d74ae24c
DO
542 echo "<tr><th>Summary</th><td>Check README for more information. RackTables releases prior to 0.16.4 ";
543 echo "must be upgraded to 0.16.4 first.</td></tr>\n";
758fe24c 544}
4114697d 545else
5f4027b8 546{
4114697d
DO
547 if (!count ($path))
548 echo "<tr><th>Summary</th><td>Come back later.</td></tr>\n";
549 else
550 {
551 echo "<tr><th>Upgrade path</th><td>${dbver} &rarr; " . implode (' &rarr; ', $path) . "</td></tr>\n";
552 foreach ($path as $batchid)
553 {
554 executeUpgradeBatch ($batchid);
555 if (isset ($relnotes[$batchid]))
556 echo "<tr><th>Release notes for ${batchid}</th><td>" . $relnotes[$batchid] . "</td></tr>\n";
557 }
790a60e8 558 echo "<tr><th>Summary</th><td>Upgrade complete, it is Ok to <a href='index.php'>enter</a> the system.</td></tr>\n";
4114697d 559 }
5f4027b8 560}
4114697d 561echo '</table>';
fbbb74fb
DO
562
563?>