r83692 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r83691‎ | r83692 | r83693 >
Date:02:51, 11 March 2011
Author:laner
Status:deferred
Tags:
Comment:
* Changed all table classes to use sortable
* Changed name of the VM namespace, to instead be Nova Resources. All Nova resources will be placed in this namespace
* Changed SpecialNovaInstance to link to Nova_Resource:<instanceid>
* Added initial support for Nova volume support; currently can only create and delete volumes. May be missing some internationalization support.
* Upped version to 1.2
Modified paths:
  • /trunk/extensions/OpenStackManager/OpenStackManager.i18n.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackManager.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaController.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaVolume.php (added) (history)
  • /trunk/extensions/OpenStackManager/special/SpecialNovaAddress.php (modified) (history)
  • /trunk/extensions/OpenStackManager/special/SpecialNovaDomain.php (modified) (history)
  • /trunk/extensions/OpenStackManager/special/SpecialNovaInstance.php (modified) (history)
  • /trunk/extensions/OpenStackManager/special/SpecialNovaKey.php (modified) (history)
  • /trunk/extensions/OpenStackManager/special/SpecialNovaProject.php (modified) (history)
  • /trunk/extensions/OpenStackManager/special/SpecialNovaRole.php (modified) (history)
  • /trunk/extensions/OpenStackManager/special/SpecialNovaSecurityGroup.php (modified) (history)
  • /trunk/extensions/OpenStackManager/special/SpecialNovaVolume.php (added) (history)

Diff [purge]

Index: trunk/extensions/OpenStackManager/special/SpecialNovaInstance.php
@@ -338,7 +338,7 @@
339339 global $wgOut, $wgRequest;
340340
341341 $this->setHeaders();
342 - $wgOut->setPagetitle( wfMsg( 'openstackmanager-deletedomain' ) );
 342+ $wgOut->setPagetitle( wfMsg( 'openstackmanager-deleteinstance' ) );
343343
344344 $project = $wgRequest->getText( 'project' );
345345 if ( ! $this->userLDAP->inRole( 'sysadmin', $project ) ) {
@@ -427,12 +427,12 @@
428428 if ( ! in_array( $project, $userProjects ) ) {
429429 continue;
430430 }
431 - $instanceName = $instance->getInstanceName();
432 - $instanceName = htmlentities( $instanceName );
433 - $title = Title::newFromText( $instanceName, NS_VM );
434 - $instanceNameLink = $sk->link( $title, $instanceName );
435 - $instanceOut = Html::rawElement( 'td', array(), $instanceNameLink );
436 - $instanceOut .= Html::element( 'td', array(), $instance->getInstanceId() );
 431+ $instanceOut = Html::element( 'td', array(), $instance->getInstanceName() );
 432+ $instanceId = $instance->getInstanceId();
 433+ $instanceId = htmlentities( $instanceId );
 434+ $title = Title::newFromText( $instanceId, NS_NOVA_RESOURCE );
 435+ $instanceIdLink = $sk->link( $title, $instanceId );
 436+ $instanceOut .= Html::rawElement( 'td', array(), $instanceIdLink );
437437 $instanceOut .= Html::element( 'td', array(), $instance->getInstanceState() );
438438 $instanceOut .= Html::element( 'td', array(), $instance->getInstanceType() );
439439 $privateip = $instance->getInstancePrivateIP();
@@ -492,7 +492,7 @@
493493 $projectOut = $header;
494494 $projectOut .= $projectArr["$project"];
495495 $out .= Html::rawElement( 'table',
496 - array( 'id' => 'novainstancelist', 'class' => 'wikitable' ), $projectOut );
 496+ array( 'id' => 'novainstancelist', 'class' => 'wikitable sortable collapsible' ), $projectOut );
497497 }
498498 }
499499
Index: trunk/extensions/OpenStackManager/special/SpecialNovaSecurityGroup.php
@@ -270,7 +270,7 @@
271271 $ruleOut .= Html::rawElement( 'td', array(), $actions );
272272 $rulesOut .= Html::rawElement( 'tr', array(), $ruleOut );
273273 }
274 - $rulesOut = Html::rawElement( 'table', array( 'id' => 'novasecuritygrouplist', 'class' => 'wikitable' ), $rulesOut );
 274+ $rulesOut = Html::rawElement( 'table', array( 'id' => 'novasecuritygrouplist', 'class' => 'wikitable sortable collapsible' ), $rulesOut );
275275 $groupOut .= Html::rawElement( 'td', array(), $rulesOut );
276276 } else {
277277 $groupOut .= Html::rawElement( 'td', array(), '' );
@@ -309,7 +309,7 @@
310310 $projectOut = $groupheader;
311311 $projectOut .= $projectArr["$project"];
312312 $out .= Html::rawElement( 'table',
313 - array( 'id' => 'novainstancelist', 'class' => 'wikitable' ), $projectOut );
 313+ array( 'id' => 'novainstancelist', 'class' => 'wikitable sortable collapsible' ), $projectOut );
314314 }
315315 }
316316
Index: trunk/extensions/OpenStackManager/special/SpecialNovaAddress.php
@@ -438,7 +438,7 @@
439439 $projectOut = $header;
440440 $projectOut .= $projectArr["$project"];
441441 $out .= Html::rawElement( 'table',
442 - array( 'id' => 'novainstancelist', 'class' => 'wikitable' ), $projectOut );
 442+ array( 'id' => 'novainstancelist', 'class' => 'wikitable sortable collapsible' ), $projectOut );
443443 }
444444 }
445445 $wgOut->addHTML( $out );
Index: trunk/extensions/OpenStackManager/special/SpecialNovaProject.php
@@ -259,7 +259,7 @@
260260 $roleOut .= Html::rawElement( 'td', array(), $actions );
261261 $rolesOut .= Html::rawElement( 'tr', array(), $roleOut );
262262 }
263 - $rolesOut = Html::rawElement( 'table', array( 'class' => 'wikitable' ), $rolesOut );
 263+ $rolesOut = Html::rawElement( 'table', array( 'class' => 'wikitable sortable collapsible' ), $rolesOut );
264264 $projectOut .= Html::rawElement( 'td', array(), $rolesOut );
265265 $link = $sk->link( $this->getTitle(), wfMsgHtml( 'openstackmanager-deleteproject' ), array(),
266266 array( 'action' => 'delete', 'projectname' => $projectName ) );
@@ -275,7 +275,7 @@
276276 $projectsOut .= Html::rawElement( 'tr', array(), $projectOut );
277277 }
278278 if ( $projectsOut ) {
279 - $out .= Html::rawElement( 'table', array( 'class' => 'wikitable' ), $projectsOut );
 279+ $out .= Html::rawElement( 'table', array( 'class' => 'wikitable sortable collapsible' ), $projectsOut );
280280 }
281281
282282 $wgOut->addHTML( $out );
Index: trunk/extensions/OpenStackManager/special/SpecialNovaDomain.php
@@ -163,7 +163,7 @@
164164 $domainsOut .= Html::rawElement( 'tr', array(), $domainOut );
165165 }
166166 if ( $domains ) {
167 - $out .= Html::rawElement( 'table', array( 'class' => 'wikitable' ), $domainsOut );
 167+ $out .= Html::rawElement( 'table', array( 'class' => 'wikitable sortable collapsible' ), $domainsOut );
168168 }
169169
170170 $wgOut->addHTML( $out );
Index: trunk/extensions/OpenStackManager/special/SpecialNovaVolume.php
@@ -0,0 +1,336 @@
 2+<?php
 3+class SpecialNovaVolume extends SpecialNova {
 4+
 5+ var $adminNova, $userNova;
 6+ var $userLDAP;
 7+
 8+ function __construct() {
 9+ parent::__construct( 'NovaVolume' );
 10+ }
 11+
 12+ function execute( $par ) {
 13+ global $wgRequest, $wgUser;
 14+ global $wgOpenStackManagerNovaAdminKeys;
 15+
 16+ if ( ! $wgUser->isLoggedIn() ) {
 17+ $this->notLoggedIn();
 18+ return true;
 19+ }
 20+ $this->userLDAP = new OpenStackNovaUser();
 21+ if ( ! $this->userLDAP->exists() ) {
 22+ $this->noCredentials();
 23+ return true;
 24+ }
 25+ $project = $wgRequest->getVal( 'project' );
 26+ $userCredentials = $this->userLDAP->getCredentials( $project );
 27+ $this->userNova = new OpenStackNovaController( $userCredentials );
 28+ $adminCredentials = $wgOpenStackManagerNovaAdminKeys;
 29+ $this->adminNova = new OpenStackNovaController( $adminCredentials );
 30+
 31+ $action = $wgRequest->getVal( 'action' );
 32+
 33+ if ( $action == "create" ) {
 34+ if ( ! $this->userLDAP->inProject( $project ) ) {
 35+ $this->notInProject();
 36+ return true;
 37+ }
 38+ $this->createVolume();
 39+ } else if ( $action == "delete" ) {
 40+ if ( ! $this->userLDAP->inProject( $project ) ) {
 41+ $this->notInProject();
 42+ return true;
 43+ }
 44+ $this->deleteVolume();
 45+ } else if ( $action == "attach" ) {
 46+ if ( ! $this->userLDAP->inProject( $project ) ) {
 47+ $this->notInProject();
 48+ return true;
 49+ }
 50+ $this->attachVolume();
 51+ } else if ( $action == "detach" ) {
 52+ if ( ! $this->userLDAP->inProject( $project ) ) {
 53+ $this->notInProject();
 54+ return true;
 55+ }
 56+ $this->detachVolume();
 57+ } else {
 58+ $this->listVolumes();
 59+ }
 60+ }
 61+
 62+ /**
 63+ * @return bool
 64+ */
 65+ function createVolume() {
 66+ global $wgRequest, $wgOut;
 67+
 68+ $this->setHeaders();
 69+ $wgOut->setPagetitle( wfMsg( 'openstackmanager-createvolume' ) );
 70+
 71+ $project = $wgRequest->getText( 'project' );
 72+ if ( ! $this->userLDAP->inRole( 'sysadmin', $project ) ) {
 73+ $this->notInRole( 'sysadmin' );
 74+ return false;
 75+ }
 76+ $volumeInfo = array();
 77+ $volumeInfo['volumename'] = array(
 78+ 'type' => 'text',
 79+ 'label-message' => 'openstackmanager-volumename',
 80+ 'validation-callback' => array( $this, 'validateVolumeName' ),
 81+ 'default' => '',
 82+ 'section' => 'volume/info',
 83+ 'name' => 'volumename',
 84+ );
 85+ $volumeInfo['volumedescription'] = array(
 86+ 'type' => 'text',
 87+ 'label-message' => 'openstackmanager-volumedescription',
 88+ 'default' => '',
 89+ 'section' => 'volume/info',
 90+ 'name' => 'volumedescription',
 91+ );
 92+
 93+
 94+ # Availability zone names can't be translated. Get the keys, and make an array
 95+ # where the name points to itself as a value
 96+ $availabilityZones = $this->adminNova->getAvailabilityZones();
 97+ $availabilityZone_keys = array();
 98+ foreach ( array_keys( $availabilityZones ) as $availabilityZone_key ) {
 99+ $availabilityZone_keys["$availabilityZone_key"] = $availabilityZone_key;
 100+ }
 101+ $volumeInfo['availabilityZone'] = array(
 102+ 'type' => 'select',
 103+ 'section' => 'volume/info',
 104+ 'options' => $availabilityZone_keys,
 105+ 'label-message' => 'openstackmanager-availabilityzone',
 106+ 'name' => 'availabilityZone',
 107+ );
 108+
 109+ $volumeInfo['volumeSize'] = array(
 110+ 'type' => 'int',
 111+ 'section' => 'volume/info',
 112+ 'label-message' => 'openstackmanager-volumesize',
 113+ 'name' => 'volumeSize',
 114+ );
 115+
 116+ $volumeInfo['project'] = array(
 117+ 'type' => 'hidden',
 118+ 'default' => $project,
 119+ 'name' => 'project',
 120+ );
 121+ $volumeInfo['action'] = array(
 122+ 'type' => 'hidden',
 123+ 'default' => 'create',
 124+ 'name' => 'action',
 125+ );
 126+
 127+ $volumeForm = new SpecialNovaVolumeForm( $volumeInfo, 'openstackmanager-novavolume' );
 128+ $volumeForm->setTitle( SpecialPage::getTitleFor( 'NovaVolume' ) );
 129+ $volumeForm->setSubmitID( 'openstackmanager-novavolume-createvolumesubmit' );
 130+ $volumeForm->setSubmitCallback( array( $this, 'tryCreateSubmit' ) );
 131+ $volumeForm->show();
 132+
 133+ return true;
 134+ }
 135+
 136+ /**
 137+ * @return bool
 138+ */
 139+ function deleteVolume() {
 140+ global $wgOut, $wgRequest;
 141+
 142+ $this->setHeaders();
 143+ $wgOut->setPagetitle( wfMsg( 'openstackmanager-deletevolume' ) );
 144+
 145+ $project = $wgRequest->getText( 'project' );
 146+ if ( ! $this->userLDAP->inRole( 'sysadmin', $project ) ) {
 147+ $this->notInRole( 'sysadmin' );
 148+ return false;
 149+ }
 150+ $volumeid = $wgRequest->getText( 'volumeid' );
 151+ if ( ! $wgRequest->wasPosted() ) {
 152+ $wgOut->addWikiMsg( 'openstackmanager-deletevolumequestion', $volumeid );
 153+ }
 154+ $volumeInfo = array();
 155+ $volumeInfo['volumeid'] = array(
 156+ 'type' => 'hidden',
 157+ 'default' => $volumeid,
 158+ 'name' => 'volumeid',
 159+ );
 160+ $volumeInfo['project'] = array(
 161+ 'type' => 'hidden',
 162+ 'default' => $project,
 163+ 'name' => 'project',
 164+ );
 165+ $volumeInfo['action'] = array(
 166+ 'type' => 'hidden',
 167+ 'default' => 'delete',
 168+ 'name' => 'action',
 169+ );
 170+ $volumeForm = new SpecialNovaVolumeForm( $volumeInfo, 'openstackmanager-novavolume' );
 171+ $volumeForm->setTitle( SpecialPage::getTitleFor( 'NovaVolume' ) );
 172+ $volumeForm->setSubmitID( 'novavolume-form-deletevolumesubmit' );
 173+ $volumeForm->setSubmitCallback( array( $this, 'tryDeleteSubmit' ) );
 174+ $volumeForm->show();
 175+
 176+ return true;
 177+ }
 178+
 179+ /**
 180+ * @return void
 181+ */
 182+ function listVolumes() {
 183+ global $wgOut, $wgUser;
 184+
 185+ $this->setHeaders();
 186+ $wgOut->setPagetitle( wfMsg( 'openstackmanager-volumelist' ) );
 187+
 188+ $userProjects = $this->userLDAP->getProjects();
 189+ $sk = $wgUser->getSkin();
 190+ $out = '';
 191+ $volumes = $this->adminNova->getVolumes();
 192+ $header = Html::element( 'th', array(), wfMsg( 'openstackmanager-volumename' ) );
 193+ $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-volumeid' ) );
 194+ $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-volumedescription' ) );
 195+ $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-volumestate' ) );
 196+ $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-volumeattachmentinstance' ) );
 197+ $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-volumeattachmentdevice' ) );
 198+ $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-volumeattachmentstatus' ) );
 199+ $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-volumesize' ) );
 200+ $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-volumedeleteonvolumedelete' ) );
 201+ $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-availabilityzone' ) );
 202+ $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-volumecreationtime' ) );
 203+ $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-actions' ) );
 204+ $projectArr = array();
 205+ foreach ( $volumes as $volume ) {
 206+ $project = $volume->getOwner();
 207+ if ( ! in_array( $project, $userProjects ) ) {
 208+ continue;
 209+ }
 210+ $volumeOut = Html::element( 'td', array(), $volume->getVolumeName() );
 211+ $volumeId = $volume->getVolumeId();
 212+ $volumeId = htmlentities( $volumeId );
 213+ $title = Title::newFromText( $volumeId, NS_NOVA_RESOURCE );
 214+ $volumeIdLink = $sk->link( $title, $volumeId );
 215+ $volumeOut .= Html::rawElement( 'td', array(), $volumeIdLink );
 216+ $volumeOut .= Html::element( 'td', array(), $volume->getVolumeDescription() );
 217+ $volumeOut .= Html::element( 'td', array(), $volume->getVolumeStatus() );
 218+ $volumeOut .= Html::element( 'td', array(), $volume->getAttachedInstanceId() );
 219+ $volumeOut .= Html::element( 'td', array(), $volume->getAttachedDevice() );
 220+ $volumeOut .= Html::element( 'td', array(), $volume->getAttachmentStatus() );
 221+ $volumeOut .= Html::element( 'td', array(), $volume->getVolumeSize() );
 222+ $volumeOut .= Html::element( 'td', array(), $volume->deleteOnInstanceDeletion() );
 223+ $volumeOut .= Html::element( 'td', array(), $volume->getVolumeAvailabilityZone() );
 224+ $volumeOut .= Html::element( 'td', array(), $volume->getVolumeCreationTime() );
 225+ $msg = wfMsgHtml( 'openstackmanager-delete' );
 226+ $link = $sk->link( $this->getTitle(), $msg, array(),
 227+ array( 'action' => 'delete',
 228+ 'project' => $project,
 229+ 'volumeid' => $volume->getVolumeId() ) );
 230+ $actions = Html::rawElement( 'li', array(), $link );
 231+ #$msg = wfMsgHtml( 'openstackmanager-rename' );
 232+ #$actions .= $sk->link( $this->getTitle(), $msg, array(),
 233+ # array( 'action' => 'rename',
 234+ # 'project' => $project,
 235+ # 'volumeid' => $volume->getVolumeId() ) );
 236+ $msg = wfMsgHtml( 'openstackmanager-attach' );
 237+ $link = $sk->link( $this->getTitle(), $msg, array(),
 238+ array( 'action' => 'attach',
 239+ 'project' => $project,
 240+ 'volumeid' => $volume->getVolumeId() ) );
 241+ $actions .= Html::rawElement( 'li', array(), $link );
 242+ $msg = wfMsgHtml( 'openstackmanager-detach' );
 243+ $link = $sk->link( $this->getTitle(), $msg, array(),
 244+ array( 'action' => 'detach',
 245+ 'project' => $project,
 246+ 'volumeid' => $volume->getVolumeId() ) );
 247+ $actions .= Html::rawElement( 'li', array(), $link );
 248+ $actions = Html::rawElement( 'ul', array(), $actions );
 249+ $volumeOut .= Html::rawElement( 'td', array(), $actions );
 250+ if ( isset( $projectArr["$project"] ) ) {
 251+ $projectArr["$project"] .= Html::rawElement( 'tr', array(), $volumeOut );
 252+ } else {
 253+ $projectArr["$project"] = Html::rawElement( 'tr', array(), $volumeOut );
 254+ }
 255+ }
 256+ foreach ( $userProjects as $project ) {
 257+ $out .= Html::element( 'h2', array(), $project );
 258+ $out .= $sk->link( $this->getTitle(), wfMsgHtml( 'openstackmanager-createvolume' ), array(),
 259+ array( 'action' => 'create', 'project' => $project ) );
 260+ if ( isset( $projectArr["$project"] ) ) {
 261+ $projectOut = $header;
 262+ $projectOut .= $projectArr["$project"];
 263+ $out .= Html::rawElement( 'table',
 264+ array( 'id' => 'novavolumelist', 'class' => 'wikitable sortable collapsible' ), $projectOut );
 265+ }
 266+ }
 267+
 268+ $wgOut->addHTML( $out );
 269+ }
 270+
 271+ /**
 272+ * @param $formData
 273+ * @param string $entryPoint
 274+ * @return bool
 275+ */
 276+ function tryCreateSubmit( $formData, $entryPoint = 'internal' ) {
 277+ global $wgOut, $wgUser;
 278+
 279+ $volume = $this->userNova->createVolume( $formData['availabilityZone'], $formData['volumeSize'], $formData['volumename'], $formData['volumedescription'] );
 280+ if ( $volume ) {
 281+ $wgOut->addWikiMsg( 'openstackmanager-createdvolume', $volume->getVolumeID() );
 282+ } else {
 283+ $wgOut->addWikiMsg( 'openstackmanager-createevolumefailed' );
 284+ }
 285+ $sk = $wgUser->getSkin();
 286+ $out = '<br />';
 287+ $out .= $sk->link( $this->getTitle(), wfMsgHtml( 'openstackmanager-backvolumelist' ) );
 288+
 289+ $wgOut->addHTML( $out );
 290+ return true;
 291+ }
 292+
 293+ /**
 294+ * @param $formData
 295+ * @param string $entryPoint
 296+ * @return bool
 297+ */
 298+ function tryDeleteSubmit( $formData, $entryPoint = 'internal' ) {
 299+ global $wgOut, $wgUser;
 300+
 301+ $volume = $this->adminNova->getVolume( $formData['volumeid'] );
 302+ if ( ! $volume ) {
 303+ $wgOut->addWikiMsg( 'openstackmanager-nonexistantvolume' );
 304+ return true;
 305+ }
 306+ $volumeid = $volume->getVolumeId();
 307+ $success = $this->userNova->deleteVolume( $volumeid );
 308+ if ( $success ) {
 309+ $wgOut->addWikiMsg( 'openstackmanager-deletedvolume', $volumeid );
 310+ } else {
 311+ $wgOut->addWikiMsg( 'openstackmanager-deletevolumefailed' );
 312+ }
 313+ $sk = $wgUser->getSkin();
 314+ $out = '<br />';
 315+ $out .= $sk->link( $this->getTitle(), wfMsgHtml( 'openstackmanager-backvolumelist' ) );
 316+
 317+ $wgOut->addHTML( $out );
 318+ return true;
 319+ }
 320+
 321+ /**
 322+ * @param $volumename
 323+ * @param $alldata
 324+ * @return bool|string
 325+ */
 326+ function validateVolumeName( $volumename, $alldata ) {
 327+ if ( ! preg_match( "/^[a-z][a-z0-9\-]*$/", $volumename ) ) {
 328+ return Xml::element( 'span', array( 'class' => 'error' ), wfMsg( 'openstackmanager-badvolumename' ) );
 329+ } else {
 330+ return true;
 331+ }
 332+ }
 333+
 334+}
 335+
 336+class SpecialNovaVolumeForm extends HTMLForm {
 337+}
Property changes on: trunk/extensions/OpenStackManager/special/SpecialNovaVolume.php
___________________________________________________________________
Added: svn:eol-style
1338 + native
Index: trunk/extensions/OpenStackManager/special/SpecialNovaKey.php
@@ -183,7 +183,7 @@
184184 $keyOut .= Html::element( 'td', array(), $keypair->getKeyFingerprint() );
185185 $projectOut .= Html::rawElement( 'tr', array(), $keyOut );
186186 }
187 - $out .= Html::rawElement( 'table', array( 'id' => 'novakeylist', 'class' => 'wikitable' ), $projectOut );
 187+ $out .= Html::rawElement( 'table', array( 'id' => 'novakeylist', 'class' => 'wikitable sortable collapsible' ), $projectOut );
188188 }
189189 } else if ( $wgOpenStackManagerNovaKeypairStorage == 'ldap' ) {
190190 $out .= $sk->link( $this->getTitle(), wfMsgHtml( 'openstackmanager-importkey' ), array(), array( 'action' => 'import' ) );
Index: trunk/extensions/OpenStackManager/special/SpecialNovaRole.php
@@ -234,7 +234,7 @@
235235 $rolesOut .= Html::rawElement( 'tr', array(), $roleOut );
236236 }
237237 if ( $rolesOut ) {
238 - $out .= Html::rawElement( 'table', array( 'class' => 'wikitable' ), $rolesOut );
 238+ $out .= Html::rawElement( 'table', array( 'class' => 'wikitable sortable collapsible' ), $rolesOut );
239239 }
240240
241241 $wgOut->addHTML( $out );
Index: trunk/extensions/OpenStackManager/OpenStackManager.i18n.php
@@ -72,6 +72,7 @@
7373 'openstackmanager-novainstance-info' => 'Instance information',
7474 'openstackmanager-novainstance-puppetinfo' => 'Puppet information',
7575
 76+ 'openstackmanager-deleteinstance' => 'Delete Instance',
7677 'openstackmanager-deleteinstancequestion' => 'Are you sure you wish to delete instance "$1"?',
7778 'openstackmanager-instancelist' => 'Instance list',
7879 'openstackmanager-instancename' => 'Instance name',
@@ -101,6 +102,31 @@
102103 'openstackmanager-consoleoutput' => 'Console Output',
103104 'openstackmanager-getconsoleoutput' => 'get console output',
104105
 106+ 'openstackmanager-createvolume' => 'Create Volume',
 107+ 'openstackmanager-volumename' => 'Volume Name',
 108+ 'openstackmanager-volumeid' => 'Volume Id',
 109+ 'openstackmanager-volumedescription' => 'Volume Description',
 110+ 'openstackmanager-volumestate' => 'Volume State',
 111+ 'openstackmanager-volumeattachmentinstance' => 'Attached to Instance',
 112+ 'openstackmanager-volumeattachmentdevice' => 'Attached as Device',
 113+ 'openstackmanager-volumesize' => 'Volume Size (in GBs)',
 114+ 'openstackmanager-volumeattachmentstatus' => 'Attachment Status',
 115+ 'openstackmanager-volumedeleteonvolumedelete' => 'Delete on Instance Deletion?',
 116+ 'openstackmanager-volumecreationtime' => 'Volume Creation Time',
 117+ 'openstackmanager-attach' => 'attach',
 118+ 'openstackmanager-detach' => 'detach',
 119+ 'openstackmanager-deletevolume' => 'Delete Volume',
 120+ 'openstackmanager-deletevolumequestion' => 'Are you sure you wish to delete volume "$1"?',
 121+ 'openstackmanager-volumelist' => 'Volume List',
 122+ 'openstackmanager-badvolumename' => 'An invalid volume name was given.',
 123+ 'openstackmanager-novavolume-volume' => 'Volume',
 124+ 'openstackmanager-novavolume-info' => 'Volume Info',
 125+ 'openstackmanager-createdvolume' => 'Created volume $1.',
 126+ 'openstackmanager-createevolumefailed' => 'Failed to create volume.',
 127+ 'openstackmanager-deletedvolume' => 'Deleted volume.',
 128+ 'openstackmanager-deletevolumefailed' => 'Failed to delete volume.',
 129+ 'openstackmanager-backvolumelist' => 'Back to volume list',
 130+
105131 'openstackmanager-novapublickey' => 'Public SSH key',
106132 'openstackmanager-novakey-key' => 'Public SSH key',
107133 'openstackmanager-novakey-info' => 'Public SSH key info',
Index: trunk/extensions/OpenStackManager/OpenStackNovaVolume.php
@@ -0,0 +1,151 @@
 2+<?php
 3+
 4+# TODO: Make this an abstract class, and make the EC2 API a subclass
 5+class OpenStackNovaVolume {
 6+
 7+ var $volume;
 8+
 9+ /**
 10+ * @param $apiInstanceResponse
 11+ */
 12+ function __construct( $apiInstanceResponse ) {
 13+ $this->volume = $apiInstanceResponse;
 14+ }
 15+
 16+ /**
 17+ * Return the assigned display name of this volume
 18+ *
 19+ * @return string
 20+ */
 21+ function getVolumeName() {
 22+ return (string)$this->volume->displayName;
 23+ }
 24+
 25+ /**
 26+ * Return the assigned description of this volume
 27+ *
 28+ * @return string
 29+ */
 30+ function getVolumeDescription() {
 31+ return (string)$this->volume->displayDescription;
 32+ }
 33+
 34+ /**
 35+ * Return the ID of this volume
 36+ *
 37+ * @return string
 38+ */
 39+ function getVolumeId() {
 40+ return (string)$this->volume->volumeId;
 41+ }
 42+
 43+ /**
 44+ * Return the status of this volume
 45+ *
 46+ * @return string
 47+ */
 48+ function getVolumeStatus() {
 49+ $status = (string)$this->volume->status;
 50+ $status = explode( ' ', $status );
 51+
 52+ return $status[0];
 53+ }
 54+
 55+ /**
 56+ * Returns the instance ID this volume is attached to, or an empty string if
 57+ * not attached
 58+ *
 59+ * @return string
 60+ */
 61+ function getAttachedInstanceId() {
 62+ return (string)$this->volume->attachmentSet->item->instanceId;
 63+ }
 64+
 65+ /**
 66+ * Returns the attachment status of this volume
 67+ *
 68+ * @return string
 69+ */
 70+ function getAttachmentStatus() {
 71+ return (string)$this->volume->attachmentSet->item->status;
 72+ }
 73+
 74+ /**
 75+ * Returns the attachment time of this volume
 76+ *
 77+ * @return string
 78+ */
 79+ function getAttachmentTime() {
 80+ return (string)$this->volume->attachmentSet->item->attachTime;
 81+ }
 82+
 83+ /**
 84+ * Will this volume be deleted when the instance it is attached to is deleted?
 85+ *
 86+ * @return bool
 87+ */
 88+ function deleteOnInstanceDeletion() {
 89+ return (bool)$this->volume->attachmentSet->item->deleteOnTermination;
 90+ }
 91+
 92+ /**
 93+ * Return the device used when attached to an instance
 94+ *
 95+ * @return string
 96+ */
 97+ function getAttachedDevice() {
 98+ return (string)$this->volume->attachmentSet->item->device;
 99+ }
 100+
 101+ /**
 102+ * Return the size, in GB, of this volume
 103+ *
 104+ * @return int
 105+ */
 106+ function getVolumeSize() {
 107+ return (string)$this->volume->size;
 108+ }
 109+
 110+ /**
 111+ * Return the creation date of this volume
 112+ *
 113+ * @return string
 114+ */
 115+ function getVolumeCreationTime() {
 116+ return (string)$this->volume->creationTime;
 117+ }
 118+
 119+ /**
 120+ * Return the volume's availability zone
 121+ *
 122+ * @return string
 123+ */
 124+ function getVolumeAvailabilityZone() {
 125+ return (string)$this->volume->availabilityZone;
 126+ }
 127+
 128+ /**
 129+ * Return the project that owns this instance
 130+ *
 131+ * @return string
 132+ */
 133+ function getOwner() {
 134+ $status = (string)$this->volume->status;
 135+ $status = explode( ' ', $status );
 136+
 137+ return str_replace( array('(',','), '', $status[1] );
 138+ }
 139+
 140+ /**
 141+ * Return the volume node that this volume exists on
 142+ *
 143+ * @return string
 144+ */
 145+ function getVolumeNode() {
 146+ $status = (string)$this->volume->status;
 147+ $status = explode( ' ', $status );
 148+
 149+ return str_replace( array(','), '', $status[2] );
 150+ }
 151+
 152+}
Property changes on: trunk/extensions/OpenStackManager/OpenStackNovaVolume.php
___________________________________________________________________
Added: svn:eol-style
1153 + native
Index: trunk/extensions/OpenStackManager/OpenStackNovaController.php
@@ -7,6 +7,7 @@
88 var $instances, $images, $keypairs, $availabilityZones;
99 var $addresses, $securityGroups;
1010 var $instanceTypes;
 11+ var $volumes;
1112
1213 /**
1314 * @param $credentials
@@ -184,6 +185,36 @@
185186 }
186187
187188 /**
 189+ * @param $volumeId
 190+ * @return null|OpenStackNovaVolume
 191+ */
 192+ function getVolume( $volumeId ) {
 193+ $this->getVolumes();
 194+ if ( isset( $this->volumes["$volumeId"] ) ) {
 195+ return $this->volumes["$volumeId"];
 196+ } else {
 197+ return null;
 198+ }
 199+ }
 200+
 201+ /**
 202+ * Get all volumes
 203+ *
 204+ * @return array
 205+ */
 206+ function getVolumes() {
 207+ $this->volumes = array();
 208+ $volumes = $this->novaConnection->describe_volumes();
 209+ $volumes = $volumes->body->volumeSet->item;
 210+ foreach ( $volumes as $volume ) {
 211+ $volume = new OpenStackNovaVolume( $volume );
 212+ $volumeId = $volume->getVolumeId();
 213+ $this->volumes["$volumeId"] = $volume;
 214+ }
 215+ return $this->volumes;
 216+ }
 217+
 218+ /**
188219 * @param $instanceName
189220 * @param $image
190221 * @param $key
@@ -475,4 +506,41 @@
476507 return $response->isOK();
477508 }
478509
 510+ /**
 511+ * Create a Nova volume
 512+ *
 513+ * @param $zone
 514+ * @param $size
 515+ * @param $name
 516+ * @param $description
 517+ * @return OpenStackNovaVolume
 518+ */
 519+ function createVolume( $zone, $size, $name, $description ) {
 520+ $response = $this->novaConnection->createVolume( $zone, array(
 521+ 'Size' => (int)$size,
 522+ 'DisplayName' => $name,
 523+ 'DisplayDescription' => $description,
 524+ ));
 525+ if ( ! $response->isOK() ) {
 526+ return null;
 527+ } else {
 528+ $volume = new OpenStackNovaVolume( $response->body->volumeSet->item );
 529+ $id = $volume->getVolumeId();
 530+ $this->volumes["$id"] = $volume;
 531+ return $volume;
 532+ }
 533+ }
 534+
 535+ /**
 536+ * Delete a Nova volume
 537+ *
 538+ * @param $volumeid
 539+ * @return boolean
 540+ */
 541+ function deleteVolume( $volumeid ) {
 542+ $response = $this->novaConnection->deleteVolume( $volumeid );
 543+
 544+ return $response->isOK();
 545+ }
 546+
479547 }
Index: trunk/extensions/OpenStackManager/OpenStackManager.php
@@ -21,15 +21,15 @@
2222 'path' => __FILE__,
2323 'name' => 'OpenStackManager',
2424 'author' => 'Ryan Lane',
25 - 'version' => '1.1',
 25+ 'version' => '1.2',
2626 'url' => 'http://mediawiki.org/wiki/Extension:OpenStackManager',
2727 'descriptionmsg' => 'openstackmanager-desc',
2828 );
2929
30 -define( "NS_VM", 498 );
31 -define( "NS_VM_TALK", 499 );
32 -$wgExtraNamespaces[NS_VM] = 'VM';
33 -$wgExtraNamespaces[NS_VM_TALK] = 'VM_talk';
 30+define( "NS_NOVA_RESOURCE", 498 );
 31+define( "NS_NOVA_RESOURCE_TALK", 499 );
 32+$wgExtraNamespaces[NS_NOVA_RESOURCE] = 'Nova_Resource';
 33+$wgExtraNamespaces[NS_NOVA_RESOURCE_TALK] = 'Nova_Resource_Talk';
3434
3535 $wgGroupPermissions['sysop']['manageproject'] = true;
3636 $wgAvailableRights[] = 'manageproject';
@@ -91,6 +91,7 @@
9292 $wgAutoloadClasses['OpenStackNovaSecurityGroup'] = $dir . 'OpenStackNovaSecurityGroup.php';
9393 $wgAutoloadClasses['OpenStackNovaSecurityGroupRule'] = $dir . 'OpenStackNovaSecurityGroupRule.php';
9494 $wgAutoloadClasses['OpenStackNovaRole'] = $dir . 'OpenStackNovaRole.php';
 95+$wgAutoloadClasses['OpenStackNovaVolume'] = $dir . 'OpenStackNovaVolume.php';
9596 $wgAutoloadClasses['SpecialNovaInstance'] = $dir . 'special/SpecialNovaInstance.php';
9697 $wgAutoloadClasses['SpecialNovaKey'] = $dir . 'special/SpecialNovaKey.php';
9798 $wgAutoloadClasses['SpecialNovaProject'] = $dir . 'special/SpecialNovaProject.php';
@@ -98,6 +99,7 @@
99100 $wgAutoloadClasses['SpecialNovaAddress'] = $dir . 'special/SpecialNovaAddress.php';
100101 $wgAutoloadClasses['SpecialNovaSecurityGroup'] = $dir . 'special/SpecialNovaSecurityGroup.php';
101102 $wgAutoloadClasses['SpecialNovaRole'] = $dir . 'special/SpecialNovaRole.php';
 103+$wgAutoloadClasses['SpecialNovaVolume'] = $dir . 'special/SpecialNovaVolume.php';
102104 $wgAutoloadClasses['SpecialNova'] = $dir . 'special/SpecialNova.php';
103105 $wgAutoloadClasses['OpenStackNovaHostJob'] = $dir . 'OpenStackNovaHostJob.php';
104106 $wgAutoloadClasses['AmazonEC2'] = $dir . 'aws-sdk/sdk.class.php';
@@ -115,6 +117,8 @@
116118 $wgSpecialPageGroups['NovaSecurityGroup'] = 'nova';
117119 $wgSpecialPages['NovaRole'] = 'SpecialNovaRole';
118120 $wgSpecialPageGroups['NovaRole'] = 'nova';
 121+$wgSpecialPages['NovaVolume'] = 'SpecialNovaVolume';
 122+$wgSpecialPageGroups['NovaVolume'] = 'nova';
119123 $wgJobClasses['addDNSHostToLDAP'] = 'OpenStackNovaHostJob';
120124
121125 $wgHooks['LDAPSetCreationValues'][] = 'OpenStackNovaUser::LDAPSetCreationValues';

Status & tagging log