r80079 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r80078‎ | r80079 | r80080 >
Date:04:09, 12 January 2011
Author:laner
Status:deferred
Tags:
Comment:
Adding initial support for managing public DNS via SpecialNovaAddress
Modified paths:
  • /trunk/extensions/OpenStackManager/OpenStackManager.i18n.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaController.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaDomain.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaHost.php (modified) (history)
  • /trunk/extensions/OpenStackManager/special/SpecialNovaAddress.php (modified) (history)
  • /trunk/extensions/OpenStackManager/special/SpecialNovaInstance.php (modified) (history)

Diff [purge]

Index: trunk/extensions/OpenStackManager/OpenStackNovaHost.php
@@ -40,7 +40,7 @@
4141 }
4242
4343 function getHostName() {
44 - return $this->hostInfo[0]['associateddomain'][0];
 44+ return $this->hostInfo[0]['dc'][0];
4545 }
4646
4747 function getDomain() {
@@ -48,7 +48,7 @@
4949 }
5050
5151 function getFullyQualifiedHostName() {
52 - return $this->getHostName();
 52+ return $this->getHostName() . '.' . $this->domain->getFullyQualifiedDomainName();
5353 }
5454
5555 function getPuppetConfiguration() {
@@ -81,6 +81,16 @@
8282 return $arecords;
8383 }
8484
 85+ function getAssociatedDomains() {
 86+ $associateddomain = array();
 87+ if ( isset( $this->hostInfo[0]['associateddomain'] ) ) {
 88+ $associateddomain = $this->hostInfo[0]['associateddomain'];
 89+ $associateddomain = array_shift( $associateddomain );
 90+ }
 91+
 92+ return $associateddomain;
 93+ }
 94+
8595 function getCNAMERecords() {
8696 $cnamerecords = array();
8797 if ( isset( $this->hostInfo[0]['cnamerecord'] ) ) {
@@ -127,6 +137,38 @@
128138 }
129139 }
130140
 141+ function deleteAssociatedDomain( $fqdn ) {
 142+ global $wgAuth;
 143+
 144+ if ( isset( $this->hostInfo[0]['associateddomain'] ) ) {
 145+ $associateddomains = $this->hostInfo[0]['associateddomain'];
 146+ array_shift( $associateddomains );
 147+ $index = array_search( $fqdn, $associateddomains );
 148+ if ( $index === false ) {
 149+ $wgAuth->printDebug( "Failed to find ip address in arecords list", NONSENSITIVE );
 150+ return false;
 151+ }
 152+ unset( $associateddomains[$index] );
 153+ $values['associateddomain'] = array();
 154+ foreach ( $associateddomains as $associateddomain ) {
 155+ $values['associateddomain'][] = $associateddomain;
 156+ }
 157+ wfSuppressWarnings();
 158+ $success = ldap_modify( $wgAuth->ldapconn, $this->hostDN, $values );
 159+ wfRestoreWarnings();
 160+ if ( $success ) {
 161+ $wgAuth->printDebug( "Successfully removed $fqdn from $this->hostDN", NONSENSITIVE );
 162+ $this->domain->updateSOA();
 163+ return true;
 164+ } else {
 165+ $wgAuth->printDebug( "Failed to remove $fqdn from $this->hostDN", NONSENSITIVE );
 166+ return false;
 167+ }
 168+ } else {
 169+ return false;
 170+ }
 171+ }
 172+
131173 function deleteARecord( $ip ) {
132174 global $wgAuth;
133175
@@ -159,6 +201,29 @@
160202 }
161203 }
162204
 205+ function addAssociatedDomain( $fqdn ) {
 206+ global $wgAuth;
 207+
 208+ $associatedomains = array();
 209+ if ( isset( $this->hostInfo[0]['associateddomain'] ) ) {
 210+ $associatedomains = $this->hostInfo[0]['associateddomain'];
 211+ array_shift( $associatedomains );
 212+ }
 213+ $associatedomains[] = $fqdn;
 214+ $values['associateddomain'] = $associatedomains;
 215+ wfSuppressWarnings();
 216+ $success = ldap_modify( $wgAuth->ldapconn, $this->hostDN, $values );
 217+ wfRestoreWarnings();
 218+ if ( $success ) {
 219+ $wgAuth->printDebug( "Successfully added $fqdn to $this->hostDN", NONSENSITIVE );
 220+ $this->domain->updateSOA();
 221+ return true;
 222+ } else {
 223+ $wgAuth->printDebug( "Failed to add $fqdn to $this->hostDN", NONSENSITIVE );
 224+ return false;
 225+ }
 226+ }
 227+
163228 function addARecord( $ip ) {
164229 global $wgAuth;
165230
@@ -213,6 +278,54 @@
214279 return self::getHostByName( $instanceid, $domain );
215280 }
216281
 282+ static function getHostByIP( $ip, $domain ) {
 283+ global $wgAuth;
 284+ global $wgOpenStackManagerLDAPUser, $wgOpenStackManagerLDAPUserPassword;
 285+ global $wgOpenStackManagerLDAPInstanceBaseDN;
 286+
 287+ $domain = OpenStackNovaDomain::getDomainByHostIP( $ip );
 288+ if ( ! $domain ) {
 289+ return array();
 290+ }
 291+ wfSuppressWarnings();
 292+ $result = ldap_search( $wgAuth->ldapconn, $wgOpenStackManagerLDAPInstanceBaseDN, '(arecord=' . $ip . ')' );
 293+ $hostInfo = ldap_get_entries( $wgAuth->ldapconn, $result );
 294+ wfRestoreWarnings();
 295+ if ( $hostInfo["count"] == "0" ) {
 296+ return array();
 297+ } else {
 298+ array_shift( $hostsInfo );
 299+ $hostname = $hostInfo[0]['dc'][0];
 300+ $host = OpenStackNovaHost::getHostByName( $hostname, $domain );
 301+ return $host;
 302+ }
 303+ }
 304+
 305+ static function getHostsByIP( $ip ) {
 306+ global $wgAuth;
 307+ global $wgOpenStackManagerLDAPUser, $wgOpenStackManagerLDAPUserPassword;
 308+ global $wgOpenStackManagerLDAPInstanceBaseDN;
 309+
 310+ wfSuppressWarnings();
 311+ $result = ldap_search( $wgAuth->ldapconn, $wgOpenStackManagerLDAPInstanceBaseDN, '(arecord=' . $ip . ')' );
 312+ $hostsInfo = ldap_get_entries( $wgAuth->ldapconn, $result );
 313+ wfRestoreWarnings();
 314+ if ( $hostsInfo["count"] == "0" ) {
 315+ return array();
 316+ } else {
 317+ $hosts = array();
 318+ array_shift( $hostsInfo );
 319+ foreach ( $hostsInfo as $host ) {
 320+ $hostname = $host['dc'][0];
 321+ $domainname = explode( '.', $host['associateddomain'][0] );
 322+ $domainname = $domainname[1];
 323+ $domain = OpenStackNovaDomain::getDomainByName( $domainname );
 324+ $hosts[] = OpenStackNovaHost::getHostByName( $hostname, $domain );
 325+ }
 326+ return $hosts;
 327+ }
 328+ }
 329+
217330 static function getAllHosts( $domain ) {
218331 global $wgAuth;
219332 global $wgOpenStackManagerLDAPUser, $wgOpenStackManagerLDAPUserPassword;
@@ -324,7 +437,6 @@
325438 $wgAuth->printDebug( "Failed to add host $hostname as the DNS entry already exists", NONSENSITIVE );
326439 return false;
327440 }
328 - $hostEntry = OpenStackNovaHost::getLDAPArray( $hostname, $ip, $domainname );
329441 $hostEntry['objectclass'][] = 'dcobject';
330442 $hostEntry['objectclass'][] = 'dnsdomain';
331443 $hostEntry['objectclass'][] = 'domainrelatedobject';
@@ -367,7 +479,40 @@
368480 }
369481 }
370482
371 - static function getLDAPArray( $hostname, $ip, $domainname ) {
 483+ static function addPublicHost( $hostname, $ip, $domain ) {
 484+ global $wgAuth;
 485+ global $wgOpenStackManagerLDAPUser, $wgOpenStackManagerLDAPUserPassword;
 486+ global $wgOpenStackManagerLDAPInstanceBaseDN;
 487+ global $wgOpenStackManagerLDAPDomain;
 488+
 489+ $wgAuth->connect( $wgOpenStackManagerLDAPDomain );
 490+ $wgAuth->bindAs( $wgOpenStackManagerLDAPUser, $wgOpenStackManagerLDAPUserPassword );
 491+
 492+ $domainname = $domain->getFullyQualifiedDomainName();
 493+ $host = OpenStackNovaHost::getHostByName( $hostname, $domain );
 494+ if ( $host ) {
 495+ $wgAuth->printDebug( "Failed to add public host $hostname as the DNS entry already exists", NONSENSITIVE );
 496+ return false;
 497+ }
 498+ $hostEntry['objectclass'][] = 'dcobject';
 499+ $hostEntry['objectclass'][] = 'dnsdomain';
 500+ $hostEntry['objectclass'][] = 'domainrelatedobject';
 501+ $hostEntry['dc'] = $hostname;
 502+ $hostEntry['arecord'] = $ip;
 503+ $hostEntry['associateddomain'][] = $hostname . '.' . $domainname;
 504+ $dn = 'dc=' . $hostname . ',dc=' . $domain->getDomainName() . ',' . $wgOpenStackManagerLDAPInstanceBaseDN;
 505+
 506+ wfSuppressWarnings();
 507+ $success = ldap_add( $wgAuth->ldapconn, $dn, $hostEntry );
 508+ wfRestoreWarnings();
 509+ if ( $success ) {
 510+ $domain->updateSOA();
 511+ $wgAuth->printDebug( "Successfully added public host $hostname", NONSENSITIVE );
 512+ return new OpenStackNovaHost( $hostname, $domain );
 513+ } else {
 514+ $wgAuth->printDebug( "Failed to add public host $hostname", NONSENSITIVE );
 515+ return null;
 516+ }
372517 }
373518
374519 }
Index: trunk/extensions/OpenStackManager/special/SpecialNovaInstance.php
@@ -135,7 +135,7 @@
136136 # 'label-message' => 'keypair',
137137 # );
138138
139 - $domains = OpenStackNovaDomain::getAllDomains( true );
 139+ $domains = OpenStackNovaDomain::getAllDomains( 'local' );
140140 $domain_keys = array();
141141 foreach ( $domains as $domain ) {
142142 $domainname = $domain->getDomainName();
Index: trunk/extensions/OpenStackManager/special/SpecialNovaAddress.php
@@ -34,6 +34,10 @@
3535 $this->associateAddress();
3636 } else if ( $action == "disassociate" ) {
3737 $this->disassociateAddress();
 38+ } else if ( $action == "addhost" ) {
 39+ $this->addHost();
 40+ } else if ( $action == "removehost" ) {
 41+ $this->removehost();
3842 } else {
3943 $this->listAddresses();
4044 }
@@ -163,6 +167,7 @@
164168 $addressForm->setSubmitCallback( array( $this, 'tryAssociateSubmit' ) );
165169 $addressForm->show();
166170
 171+ return true;
167172 }
168173
169174 function disassociateAddress() {
@@ -203,8 +208,63 @@
204209 $addressForm->setSubmitText( 'confirm' );
205210 $addressForm->show();
206211
 212+ return true;
207213 }
208214
 215+ function addHost() {
 216+ global $wgOut, $wgRequest;
 217+
 218+ $this->setHeaders();
 219+ $wgOut->setPagetitle( wfMsg( 'openstackmanager-addhost' ) );
 220+
 221+ $project = $wgRequest->getText( 'project' );
 222+ if ( ! $this->userLDAP->inRole( 'netadmin', $project ) ) {
 223+ $this->notInRole( 'netadmin' );
 224+ return false;
 225+ }
 226+ $ip = $wgRequest->getText( 'ip' );
 227+ $addressInfo = Array();
 228+ $addressInfo['project'] = array(
 229+ 'type' => 'hidden',
 230+ 'default' => $project,
 231+ );
 232+ $addressInfo['ip'] = array(
 233+ 'type' => 'hidden',
 234+ 'default' => $ip,
 235+ );
 236+ $addressInfo['hostname'] = array(
 237+ 'type' => 'text',
 238+ 'default' => '',
 239+ 'validation-callback' => array( $this, 'validateHostName' ),
 240+ 'label-message' => 'openstackmanager-hostname',
 241+ );
 242+ $domains = OpenStackNovaDomain::getAllDomains( 'public' );
 243+ $domain_keys = array();
 244+ foreach ( $domains as $domain ) {
 245+ $domainname = $domain->getDomainName();
 246+ $domain_keys["$domainname"] = $domainname;
 247+ }
 248+ $addressInfo['domain'] = array(
 249+ 'type' => 'select',
 250+ 'options' => $domain_keys,
 251+ 'label-message' => 'openstackmanager-dnsdomain',
 252+ );
 253+ $addressInfo['action'] = array(
 254+ 'type' => 'hidden',
 255+ 'default' => 'addhost',
 256+ );
 257+ $addressForm = new SpecialNovaAddressForm( $addressInfo, 'openstackmanager-novaaddress' );
 258+ $addressForm->setTitle( SpecialPage::getTitleFor( 'NovaAddress' ) );
 259+ $addressForm->setSubmitID( 'novaaddress-form-disassociateaddresssubmit' );
 260+ $addressForm->setSubmitCallback( array( $this, 'tryAddHostSubmit' ) );
 261+ $addressForm->show();
 262+
 263+ return true;
 264+ }
 265+
 266+ function removeHost() {
 267+ }
 268+
209269 function listAddresses() {
210270 global $wgOut, $wgUser;
211271
@@ -217,6 +277,7 @@
218278 $header = Html::element( 'th', array(), wfMsg( 'openstackmanager-address' ) );
219279 $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-instanceid' ) );
220280 $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-instancename' ) );
 281+ $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-hostnames' ) );
221282 $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-actions' ) );
222283 $addresses = $this->adminNova->getAddresses();
223284 $projectArr = array();
@@ -234,6 +295,22 @@
235296 $addressOut .= Html::element( 'td', array(), '' );
236297 $addressOut .= Html::element( 'td', array(), '' );
237298 }
 299+ $hosts = OpenStackNovaHost::getHostsByIP( $ip );
 300+ if ( $hosts ) {
 301+ $hostsOut = '';
 302+ $msg = wfMsg( 'openstackmanager-removehost' );
 303+ foreach ( $hosts as $host ) {
 304+ $domain = $host->getDomain();
 305+ $link = $sk->link( $this->getTitle(), $msg, array(),
 306+ array( 'action' => 'removehost', 'ip' => $ip, 'project' => $project, 'domain' => $domain->getDomainName() ), array() );
 307+ $hostOut = $host->getFullyQualifiedHostName() . ' ' . $link;
 308+ $hostsOut .= Html::rawElement( 'li', array(), $hostOut );
 309+ }
 310+ $hostsOut = Html::rawElement( 'ul', array(), $hostsOut );
 311+ $addressOut .= Html::rawElement( 'td', array(), $hostsOut );
 312+ } else {
 313+ $addressOut .= Html::element( 'td', array(), '' );
 314+ }
238315 if ( $instanceid ) {
239316 $msg = wfMsg( 'openstackmanager-reassociateaddress' );
240317 } else {
@@ -252,6 +329,10 @@
253330 array( 'action' => 'disassociate', 'ip' => $ip, 'project' => $project ), array() );
254331 $actions .= Html::rawElement( 'li', array(), $link );
255332 }
 333+ $msg = wfMsg( 'openstackmanager-addhost' );
 334+ $link = $sk->link( $this->getTitle(), $msg, array(),
 335+ array( 'action' => 'addhost', 'ip' => $ip, 'project' => $project ), array() );
 336+ $actions .= Html::rawElement( 'li', array(), $link );
256337 $actions = Html::rawElement( 'ul', array(), $actions );
257338 $addressOut .= Html::rawElement( 'td', array(), $actions );
258339 $projectArr["$project"] = Html::rawElement( 'tr', array(), $addressOut );
@@ -267,6 +348,8 @@
268349 }
269350 }
270351 $wgOut->addHTML( $out );
 352+
 353+ return true;
271354 }
272355
273356 function tryAllocateSubmit( $formData, $entryPoint = 'internal' ) {
@@ -343,6 +426,66 @@
344427 return true;
345428 }
346429
 430+ function tryAddHostSubmit( $formData, $entryPoint = 'internal' ) {
 431+ global $wgOut, $wgUser;
 432+
 433+ $ip = $formData['ip'];
 434+ $project = $formData['project'];
 435+ $address = $this->adminNova->getAddress( $ip );
 436+ if ( ! $address ) {
 437+ $out = Html::element( 'p', array(), wfMsgExt( 'openstackmanager-invalidaddress', array(), $ip ) );
 438+ $wgOut->addHTML( $out );
 439+ return false;
 440+ }
 441+ if ( $address->getProject() != $project ) {
 442+ $out = Html::element( 'p', array(), wfMsgExt( 'openstackmanager-invalidaddressforproject', array(), $ip ) );
 443+ $wgOut->addHTML( $out );
 444+ return false;
 445+ }
 446+ $hostname = $formData['hostname'];
 447+ $domain = $formData['domain'];
 448+ $domain = OpenStackNovaDomain::getDomainByName( $domain );
 449+ $hostbyname = OpenStackNovaHost::getHostByName( $hostname, $domain );
 450+ $hostbyip = OpenStackNovaHost::getHostByIP( $ip, $domain );
 451+ if ( $hostbyname ) {
 452+ # We need to add an arecord, if the arecord doesn't already exist
 453+ $success = $host->addARecord( $ip );
 454+ if ( $success ) {
 455+ $out = Html::element( 'p', array(), wfMsgExt( 'openstackmanager-addedhost', array(), $hostname, $ip ) );
 456+ } else {
 457+ $out = Html::element( 'p', array(), wfMsgExt( 'openstackmanager-addhostfailed', array(), $ip, $instanceid ) );
 458+ }
 459+ } else if ( $hostbyip ) {
 460+ # We need to add an associateddomain, if the associateddomain doesn't already exist
 461+ $success = $host->addAssociatedDomain( $hostname . '.' . $domain->getFullyQualifiedHostname() );
 462+ if ( $success ) {
 463+ $out = Html::element( 'p', array(), wfMsgExt( 'openstackmanager-addedhost', array(), $hostname, $ip ) );
 464+ } else {
 465+ $out = Html::element( 'p', array(), wfMsgExt( 'openstackmanager-addhostfailed', array(), $ip, $instanceid ) );
 466+ }
 467+ } else {
 468+ # This is a new host entry
 469+ $host = OpenStackNovaHost::addPublicHost( $hostname, $ip, $domain );
 470+ if ( $host ) {
 471+ $out = Html::element( 'p', array(), wfMsgExt( 'openstackmanager-addedhost', array(), $hostname, $ip ) );
 472+ } else {
 473+ $out = Html::element( 'p', array(), wfMsgExt( 'openstackmanager-addhostfailed', array(), $ip, $instanceid ) );
 474+ }
 475+ }
 476+ $out .= '<br />';
 477+ $sk = $wgUser->getSkin();
 478+ $out .= $sk->link( $this->getTitle(), wfMsg( 'openstackmanager-backaddresslist' ), array(), array(), array() );
 479+ $wgOut->addHTML( $out );
 480+ return true;
 481+ }
 482+
 483+ function validateHostName( $hostname, $alldata ) {
 484+ if ( ! preg_match( "/^[a-z][a-z0-9\-]*$/", $hostname ) ) {
 485+ return Xml::element( 'span', array( 'class' => 'error' ), wfMsg( 'openstackmanager-badinstancename' ) );
 486+ } else {
 487+ return true;
 488+ }
 489+ }
347490 }
348491
349492 class SpecialNovaAddressForm extends HTMLForm {
Index: trunk/extensions/OpenStackManager/OpenStackNovaController.php
@@ -22,6 +22,15 @@
2323 $this->instances = array();
2424 }
2525
 26+ function getAddress( $ip ) {
 27+ $this->getAddresses();
 28+ if ( isset( $this->addresses["$ip"] ) ) {
 29+ return $this->addresses["$ip"];
 30+ } else {
 31+ return null;
 32+ }
 33+ }
 34+
2635 function getAddresses() {
2736 $this->addresses = array();
2837 $response = $this->novaConnection->describe_addresses();
Index: trunk/extensions/OpenStackManager/OpenStackManager.i18n.php
@@ -154,6 +154,14 @@
155155 'openstackmanager-disassociateaddressfailed' => 'Failed to disassociate $1',
156156 'openstackmanager-disassociateaddress-confirm' => 'Are you sure you would like to disassociate $1?',
157157 'openstackmanager-releaseaddress-confirm' => 'Are you sure you would like to release $1?',
 158+ 'openstackmanager-invalidaddress' => '$1 is not a valid allocated IP address.',
 159+ 'openstackmanager-invalidaddressforproject' => '$1 is not in the project requested.',
 160+ 'openstackmanager-addedhost' => 'Successfully added $1 entry for IP $2',
 161+ 'openstackmanager-addhostfailed' => 'Failed to add $1 entry for IP $2',
 162+ 'openstackmanager-hostname' => 'Host Name',
 163+ 'openstackmanager-hostnames' => 'Host Names',
 164+ 'openstackmanager-addhost' => 'Add host name',
 165+ 'openstackmanager-removehost' => '(Remove host name)',
158166
159167 'openstackmanager-needsysadminrole' => 'Sysadmin Role Required',
160168 'openstackmanager-needsysadminrole2' => 'You must be a member of the sysadmin role to perform this action.',
Index: trunk/extensions/OpenStackManager/OpenStackNovaDomain.php
@@ -69,7 +69,7 @@
7070 }
7171 }
7272
73 - static function getAllDomains( $bylocation = false ) {
 73+ static function getAllDomains( $type='all' ) {
7474 global $wgAuth;
7575 global $wgOpenStackManagerLDAPUser, $wgOpenStackManagerLDAPUserPassword;
7676 global $wgOpenStackManagerLDAPInstanceBaseDN;
@@ -79,13 +79,15 @@
8080 $wgAuth->bindAs( $wgOpenStackManagerLDAPUser, $wgOpenStackManagerLDAPUserPassword );
8181
8282 $domains = array();
83 - if ( $bylocation ) {
 83+ if ( $type == 'local' ) {
8484 $query = '(&(soarecord=*)(l=*))';
 85+ } else if ( $type == 'public' ) {
 86+ $query = '(&(soarecord=*)(!(l=*)))';
8587 } else {
8688 $query = '(soarecord=*)';
8789 }
8890 wfSuppressWarnings();
89 - $result = ldap_search( $wgAuth->ldapconn, $wgOpenStackManagerLDAPInstanceBaseDN, '(soarecord=*)' );
 91+ $result = ldap_search( $wgAuth->ldapconn, $wgOpenStackManagerLDAPInstanceBaseDN, $query );
9092 wfRestoreWarnings();
9193 if ( $result ) {
9294 wfSuppressWarnings();

Status & tagging log