r114680 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r114679‎ | r114680 | r114681 >
Date:01:42, 3 April 2012
Author:laner
Status:deferred (Comments)
Tags:
Comment:
* Refactor all special pages to create list pages more sanely
* Add memcaching to OpenStackNovaUser and OpenStackNovaRole
* A minor fix for deleting security groups
* Add a project filter, only displaying projects enabled in the filter, by default
Modified paths:
  • /trunk/extensions/OpenStackManager/OpenStackManager.i18n.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackManager.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaAddress.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaArticle.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/OpenStackNovaHostJob.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaImage.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaInstance.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaInstanceType.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaKeypair.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaLdapConnection.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaProject.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaPuppetGroup.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaRole.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaSecurityGroup.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaSudoer.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaUser.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaVolume.php (modified) (history)
  • /trunk/extensions/OpenStackManager/special/SpecialNova.php (modified) (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/SpecialNovaPuppetGroup.php (modified) (history)
  • /trunk/extensions/OpenStackManager/special/SpecialNovaRole.php (modified) (history)
  • /trunk/extensions/OpenStackManager/special/SpecialNovaSecurityGroup.php (modified) (history)
  • /trunk/extensions/OpenStackManager/special/SpecialNovaSudoer.php (modified) (history)
  • /trunk/extensions/OpenStackManager/special/SpecialNovaVolume.php (modified) (history)

Diff [purge]

Index: trunk/extensions/OpenStackManager/special/SpecialNovaInstance.php
@@ -1,4 +1,12 @@
22 <?php
 3+
 4+/**
 5+ * special for nova instance
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
311 class SpecialNovaInstance extends SpecialNova {
412
513 /**
@@ -199,7 +207,7 @@
200208 $group_keys = array();
201209 $defaults = array();
202210 foreach ( $securityGroups as $securityGroup ) {
203 - if ( $securityGroup->getOwner() == $project ) {
 211+ if ( $securityGroup->getProject() == $project ) {
204212 $securityGroupName = $securityGroup->getGroupName();
205213 $group_keys["$securityGroupName"] = $securityGroupName;
206214 if ( $securityGroupName == "default" ) {
@@ -466,109 +474,79 @@
467475 $this->getOutput()->addModuleStyles( 'ext.openstack' );
468476 $this->getOutput()->setPagetitle( wfMsg( 'openstackmanager-instancelist' ) );
469477
470 - $userProjects = $this->userLDAP->getProjects();
 478+ if ( $this->userLDAP->inGlobalRole( 'cloudadmin' ) ) {
 479+ $projects = OpenStackNovaProject::getAllProjects();
 480+ } else {
 481+ $projects = OpenStackNovaProject::getProjectsByName( $this->userLDAP->getProjects() );
 482+ }
 483+ $projectfilter = $this->getProjectFilter();
 484+ if ( !$projectfilter ) {
 485+ $this->getOutput()->addWikiMsg( 'openstackmanager-setprojectfilter' );
 486+ $this->showProjectFilter( $projects, true );
 487+ return null;
 488+ }
 489+ $this->showProjectFilter( $projects );
471490
472491 $out = '';
473 - $instances = $this->adminNova->getInstances();
474 - $header = Html::element( 'th', array(), wfMsg( 'openstackmanager-instancename' ) );
475 - $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-instanceid' ) );
476 - $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-instancestate' ) );
477 - $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-instancetype' ) );
478 - $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-instanceip' ) );
479 - $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-instancepublicip' ) );
480 - $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-securitygroups' ) );
481 - $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-availabilityzone' ) );
482 - $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-imageid' ) );
483 - $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-launchtime' ) );
484 - $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-actions' ) );
485 - $projectArr = array();
486492
 493+ # Ideally we could filter the stupid instance list, but alas, openstack doesn't
 494+ # currently support this. We can filter the search when this is supported.
 495+ $instances = $this->getResourcesGroupedByProject( $this->adminNova->getInstances() );
 496+ foreach ( $projects as $project ) {
 497+ $projectName = $project->getProjectName();
 498+ if ( !in_array( $projectName, $projectfilter ) ) {
 499+ continue;
 500+ }
 501+ $actions = Array( 'sysadmin' => Array() );
 502+ $actions['sysadmin'][] = $this->createActionLink( 'openstackmanager-createinstance', array( 'action' => 'create', 'project' => $projectName ) );
 503+ $out .= $this->createProjectSection( $projectName, $actions, $this->getInstances( $projectName, $this->getResourceByProject( $instances, $projectName ) ) );
 504+ }
 505+
 506+ $this->getOutput()->addHTML( $out );
 507+ }
 508+
 509+ function getInstances( $projectName, $instances ) {
 510+ $headers = Array( 'openstackmanager-instancename', 'openstackmanager-instanceid', 'openstackmanager-instancestate',
 511+ 'openstackmanager-instancetype', 'openstackmanager-instanceip', 'openstackmanager-instancepublicip',
 512+ 'openstackmanager-securitygroups', 'openstackmanager-availabilityzone', 'openstackmanager-imageid',
 513+ 'openstackmanager-launchtime', 'openstackmanager-actions' );
 514+ $instanceRows = Array();
487515 /**
488516 * @var $instance OpenStackNovaInstance
489517 */
490518 foreach ( $instances as $instance ) {
491 - $project = $instance->getOwner();
492 - if ( ! in_array( $project, $userProjects ) ) {
493 - continue;
494 - }
495 - $instanceOut = Html::element( 'td', array(), $instance->getInstanceName() );
496 - $instanceId = $instance->getInstanceId();
497 - $instanceId = htmlentities( $instanceId );
498 - $title = Title::newFromText( $instanceId, NS_NOVA_RESOURCE );
499 - $instanceIdLink = Linker::link( $title, $instanceId );
500 - $instanceOut .= Html::rawElement( 'td', array(), $instanceIdLink );
501 - $instanceOut .= Html::element( 'td', array(), $instance->getInstanceState() );
502 - $instanceOut .= Html::element( 'td', array(), $instance->getInstanceType() );
 519+ $instanceRow = array();
 520+ $this->pushResourceColumn( $instanceRow, $instance->getInstanceName() );
 521+ $this->pushRawResourceColumn( $instanceRow, $this->createResourceLink( $instance->getInstanceId() ) );
 522+ $this->pushResourceColumn( $instanceRow, $instance->getInstanceState() );
 523+ $this->pushResourceColumn( $instanceRow, $instance->getInstanceType() );
503524 $privateip = $instance->getInstancePrivateIP();
504525 $publicip = $instance->getInstancePublicIP();
505 - $instanceOut .= Html::element( 'td', array(), $privateip );
 526+ $this->pushResourceColumn( $instanceRow, $privateip );
506527 if ( $privateip != $publicip ) {
507 - $instanceOut .= Html::element( 'td', array(), $publicip );
 528+ $this->pushResourceColumn( $instanceRow, $publicip );
508529 } else {
509 - $instanceOut .= Html::element( 'td', array(), '' );
 530+ $this->pushResourceColumn( $instanceRow, '' );
510531 }
511 - $groupsOut = '';
512 - foreach ( $instance->getSecurityGroups() as $group ) {
513 - $groupsOut .= Html::element( 'li', array(), $group );
 532+ $this->pushRawResourceColumn( $instanceRow, $this->createResourceList( $instance->getSecurityGroups() ) );
 533+ $this->pushResourceColumn( $instanceRow, $instance->getAvailabilityZone() );
 534+ $this->pushResourceColumn( $instanceRow, $instance->getImageId() );
 535+ $this->pushResourceColumn( $instanceRow, $instance->getLaunchTime() );
 536+ $actions = Array();
 537+ if ( $this->userLDAP->inRole( 'sysadmin', $projectName ) ) {
 538+ array_push( $actions, $this->createActionLink( 'openstackmanager-delete', array( 'action' => 'delete', 'project' => $projectName, 'instanceid' => $instance->getInstanceId() ) ) );
 539+ array_push( $actions, $this->createActionLink( 'openstackmanager-reboot', array( 'action' => 'reboot', 'project' => $projectName, 'instanceid' => $instance->getInstanceId() ) ) );
 540+ array_push( $actions, $this->createActionLink( 'openstackmanager-configure', array( 'action' => 'configure', 'project' => $projectName, 'instanceid' => $instance->getInstanceId() ) ) );
 541+ array_push( $actions, $this->createActionLink( 'openstackmanager-getconsoleoutput', array( 'action' => 'consoleoutput', 'project' => $projectName, 'instanceid' => $instance->getInstanceId() ) ) );
514542 }
515 - $groupsOut = Html::rawElement( 'ul', array(), $groupsOut );
516 - $instanceOut .= Html::rawElement( 'td', array(), $groupsOut );
517 - $instanceOut .= Html::element( 'td', array(), $instance->getAvailabilityZone() );
518 - $instanceOut .= Html::element( 'td', array(), $instance->getImageId() );
519 - $instanceOut .= Html::element( 'td', array(), $instance->getLaunchTime() );
520 - $actions = '';
521 - if ( $this->userLDAP->inRole( 'sysadmin', $project ) ) {
522 - $msg = wfMsgHtml( 'openstackmanager-delete' );
523 - $link = Linker::link( $this->getTitle(), $msg, array(),
524 - array( 'action' => 'delete',
525 - 'project' => $project,
526 - 'instanceid' => $instance->getInstanceId() ) );
527 - $actions = Html::rawElement( 'li', array(), $link );
528 - $msg = wfMsgHtml( 'openstackmanager-reboot' );
529 - $link = Linker::link( $this->getTitle(), $msg, array(),
530 - array( 'action' => 'reboot',
531 - 'project' => $project,
532 - 'instanceid' => $instance->getInstanceId() ) );
533 - $actions .= Html::rawElement( 'li', array(), $link );
534 - $msg = wfMsgHtml( 'openstackmanager-configure' );
535 - $link = Linker::link( $this->getTitle(), $msg, array(),
536 - array( 'action' => 'configure',
537 - 'project' => $project,
538 - 'instanceid' => $instance->getInstanceId() ) );
539 - $actions .= Html::rawElement( 'li', array(), $link );
540 - $msg = wfMsgHtml( 'openstackmanager-getconsoleoutput' );
541 - $link = Linker::link( $this->getTitle(), $msg, array(),
542 - array( 'action' => 'consoleoutput',
543 - 'project' => $project,
544 - 'instanceid' => $instance->getInstanceId() ) );
545 - $actions .= Html::rawElement( 'li', array(), $link );
546 - $actions = Html::rawElement( 'ul', array(), $actions );
547 - }
548 - $instanceOut .= Html::rawElement( 'td', array(), $actions );
549 - if ( isset( $projectArr["$project"] ) ) {
550 - $projectArr["$project"] .= Html::rawElement( 'tr', array(), $instanceOut );
551 - } else {
552 - $projectArr["$project"] = Html::rawElement( 'tr', array(), $instanceOut );
553 - }
 543+ $this->pushRawResourceColumn( $instanceRow, $this->createResourceList( $actions ) );
 544+ array_push( $instanceRows, $instanceRow );
554545 }
555 - foreach ( $userProjects as $project ) {
556 - $action = '';
557 - if ( $this->userLDAP->inRole( 'sysadmin', $project ) ) {
558 - $action = Linker::link( $this->getTitle(), wfMsgHtml( 'openstackmanager-createinstance' ), array(), array( 'action' => 'create', 'project' => $project ) );
559 - $action = Html::rawElement( 'span', array( 'id' => 'novaaction' ), "[$action]" );
560 - }
561 - $projectName = Html::rawElement( 'span', array( 'class' => 'mw-customtoggle-' . $project, 'id' => 'novaproject' ), $project );
562 - $out .= Html::rawElement( 'h2', array(), "$projectName $action" );
563 - $projectOut = '';
564 - if ( isset( $projectArr["$project"] ) ) {
565 - $projectOut .= $header;
566 - $projectOut .= $projectArr["$project"];
567 - $projectOut = Html::rawElement( 'table', array( 'id' => 'novainstancelist', 'class' => 'wikitable sortable' ), $projectOut );
568 - }
569 - $out .= Html::rawElement( 'div', array( 'class' => 'mw-collapsible', 'id' => 'mw-customcollapsible-' . $project ), $projectOut );
 546+ if ( $instanceRows ) {
 547+ return $this->createResourceTable( $headers, $instanceRows );
 548+ } else {
 549+ return '';
570550 }
571 -
572 - $this->getOutput()->addHTML( $out );
573551 }
574552
575553 /**
Index: trunk/extensions/OpenStackManager/special/SpecialNovaSecurityGroup.php
@@ -1,4 +1,12 @@
22 <?php
 3+
 4+/**
 5+ * todo comment me
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
311 class SpecialNovaSecurityGroup extends SpecialNova {
412
513 /**
@@ -200,64 +208,78 @@
201209 $this->getOutput()->addModuleStyles( 'ext.openstack' );
202210 $this->getOutput()->setPagetitle( wfMsg( 'openstackmanager-securitygrouplist' ) );
203211
204 - $userProjects = $this->userLDAP->getProjects();
 212+ if ( $this->userLDAP->inGlobalRole( 'cloudadmin' ) ) {
 213+ $projects = OpenStackNovaProject::getAllProjects();
 214+ } else {
 215+ $projects = OpenStackNovaProject::getProjectsByName( $this->userLDAP->getProjects() );
 216+ }
 217+ $projectfilter = $this->getProjectFilter();
 218+ if ( !$projectfilter ) {
 219+ $this->getOutput()->addWikiMsg( 'openstackmanager-setprojectfilter' );
 220+ $this->showProjectFilter( $projects, true );
 221+ return null;
 222+ }
 223+ $this->showProjectFilter( $projects );
205224
206225 $out = '';
207 - $groupheader = Html::element( 'th', array(), wfMsg( 'openstackmanager-securitygroupname' ) );
208 - $groupheader .= Html::element( 'th', array(), wfMsg( 'openstackmanager-securitygroupdescription' ) );
209 - $groupheader .= Html::element( 'th', array(), wfMsg( 'openstackmanager-securitygrouprule' ) );
210 - $groupheader .= Html::element( 'th', array(), wfMsg( 'openstackmanager-actions' ) );
211 - $ruleheader = Html::element( 'th', array(), wfMsg( 'openstackmanager-securitygrouprule-fromport' ) );
212 - $ruleheader .= Html::element( 'th', array(), wfMsg( 'openstackmanager-securitygrouprule-toport' ) );
213 - $ruleheader .= Html::element( 'th', array(), wfMsg( 'openstackmanager-securitygrouprule-protocol' ) );
214 - $ruleheader .= Html::element( 'th', array(), wfMsg( 'openstackmanager-securitygrouprule-ipranges' ) );
215 - $ruleheader .= Html::element( 'th', array(), wfMsg( 'openstackmanager-securitygrouprule-groups' ) );
216 - $ruleheader .= Html::element( 'th', array(), wfMsg( 'openstackmanager-actions' ) );
217 - $projectArr = array();
218 - $securityGroups = $this->adminNova->getSecurityGroups();
219 - foreach ( $securityGroups as $group ) {
220 - $project = $group->getOwner();
221 - if ( ! in_array( $project, $userProjects ) ) {
 226+ $securityGroups = $this->getResourcesGroupedByProject( $this->adminNova->getSecurityGroups() );
 227+ foreach ( $projects as $project ) {
 228+ $projectName = $project->getProjectName();
 229+ if ( !in_array( $projectName, $projectfilter ) ) {
222230 continue;
223231 }
 232+ $actions = Array( 'netadmin' => Array() );
 233+ $actions['netadmin'][] = $this->createActionLink( 'openstackmanager-createnewsecuritygroup', array( 'action' => 'create', 'project' => $projectName ) );
 234+ $out .= $this->createProjectSection( $projectName, $actions, $this->getSecurityGroups( $projectName, $this->getResourceByProject( $securityGroups, $projectName ) ) );
 235+ }
 236+
 237+ $this->getOutput()->addHTML( $out );
 238+ return true;
 239+ }
 240+
 241+ function getSecurityGroups( $projectName, $securityGroups ) {
 242+ $groupHeaders = Array( 'openstackmanager-securitygroupname', 'openstackmanager-securitygroupdescription',
 243+ 'openstackmanager-securitygrouprule', 'openstackmanager-actions' );
 244+ $ruleHeaders = Array( 'openstackmanager-securitygrouprule-fromport', 'openstackmanager-securitygrouprule-toport',
 245+ 'openstackmanager-securitygrouprule-protocol', 'openstackmanager-securitygrouprule-ipranges',
 246+ 'openstackmanager-securitygrouprule-groups', 'openstackmanager-actions' );
 247+ $groupRows = Array();
 248+ foreach ( $securityGroups as $group ) {
 249+ $groupRow = Array();
 250+ $project = $group->getProject();
224251 $groupname = $group->getGroupName();
225 - $groupOut = Html::element( 'td', array(), $groupname );
226 - $groupOut .= Html::element( 'td', array(), $group->getGroupDescription() );
 252+ $this->pushResourceColumn( $groupRow, $groupname );
 253+ $this->pushResourceColumn( $groupRow, $group->getGroupDescription() );
227254 # Add rules
228255 $rules = $group->getRules();
229256 if ( $rules ) {
230 - $rulesOut = $ruleheader;
 257+ $ruleRows = Array();
231258 foreach ( $rules as $rule ) {
 259+ $ruleRow = Array();
232260 $fromport = $rule->getFromPort();
233261 $toport = $rule->getToPort();
234262 $ipprotocol = $rule->getIPProtocol();
235 - $ruleOut = Html::element( 'td', array(), $fromport );
236 - $ruleOut .= Html::element( 'td', array(), $toport );
237 - $ruleOut .= Html::element( 'td', array(), $ipprotocol );
 263+ $this->pushResourceColumn( $ruleRow, $fromport );
 264+ $this->pushResourceColumn( $ruleRow, $toport );
 265+ $this->pushResourceColumn( $ruleRow, $ipprotocol );
238266 $ranges = $rule->getIPRanges();
239267 if ( $ranges ) {
240 - $rangesOut = '';
241 - foreach ( $ranges as $range ) {
242 - $rangesOut .= Html::element( 'li', array(), $range );
243 - }
244 - $rangesOut = Html::rawElement( 'ul', array(), $rangesOut );
245 - $ruleOut .= Html::rawElement( 'td', array(), $rangesOut );
 268+ $this->pushRawResourceColumn( $ruleRow, $this->createResourceList( $ranges ) );
246269 } else {
247 - $ruleOut .= Html::rawElement( 'td', array(), '' );
 270+ $this->pushRawResourceColumn( $ruleRow, '' );
248271 }
249272 $sourcegroups = $rule->getGroups();
250273 $groupinfo = array();
251274 if ( $sourcegroups ) {
252 - $sourcegroupsOut = '';
 275+ $sourcegroupsArr = Array();
253276 foreach ( $sourcegroups as $sourcegroup ) {
254277 $groupinfo[] = $sourcegroup['groupname'] . ':' . $sourcegroup['project'];
255278 $sourcegroupinfo = $sourcegroup['groupname'] . ' (' . $sourcegroup['project'] . ')';
256 - $sourcegroupsOut .= Html::element( 'li', array(), $sourcegroupinfo );
 279+ array_push($sourcegroupsArr, $sourcegroupinfo );
257280 }
258 - $sourcegroupsOut = Html::rawElement( 'ul', array(), $sourcegroupsOut );
259 - $ruleOut .= Html::rawElement( 'td', array(), $sourcegroupsOut );
 281+ $this->pushRawResourceColumn( $ruleRow, $this->createResourceList( $sourcegroupsArr ) );
260282 } else {
261 - $ruleOut .= Html::rawElement( 'td', array(), '' );
 283+ $this->pushRawResourceColumn( $ruleRow, '' );
262284 }
263285 $actions = '';
264286 if ( $this->userLDAP->inRole( 'netadmin', $project ) ) {
@@ -270,66 +292,30 @@
271293 'protocol' => $ipprotocol,
272294 'ranges' => implode( ',', $ranges ),
273295 'groups' => implode( ',', $groupinfo ) );
274 - $link = Linker::link( $this->getTitle(), $msg, array(), $args );
275 - $actions = Html::rawElement( 'li', array(), $link );
276 - $actions = Html::rawElement( 'ul', array(), $actions );
 296+ $link = $this->createActionLink( 'openstackmanager-removerule-action', $args );
 297+ $actions = $this->createResourceList( array( $link ) );
277298 }
278 - $ruleOut .= Html::rawElement( 'td', array(), $actions );
279 - $rulesOut .= Html::rawElement( 'tr', array(), $ruleOut );
 299+ $this->pushRawResourceColumn( $ruleRow, $actions );
 300+ array_push( $ruleRows, $ruleRow );
280301 }
281 - $rulesOut = Html::rawElement( 'table', array( 'id' => 'novasecuritygrouplist', 'class' => 'wikitable sortable collapsible' ), $rulesOut );
282 - $groupOut .= Html::rawElement( 'td', array(), $rulesOut );
 302+ $this->pushRawResourceColumn( $groupRow, $this->createResourceTable( $ruleHeaders, $ruleRows ) );
283303 } else {
284 - $groupOut .= Html::rawElement( 'td', array(), '' );
 304+ $this->pushRawResourceColumn( $groupRow, '' );
285305 }
286 - $actions = '';
 306+ $actions = Array();
287307 if ( $this->userLDAP->inRole( 'netadmin', $project ) ) {
288 - $msg = wfMsgHtml( 'openstackmanager-delete' );
289 - $link = Linker::link( $this->getTitle(), $msg, array(),
290 - array( 'action' => 'delete',
291 - 'project' => $project,
292 - 'groupname' => $group->getGroupName() ) );
293 - $actions = Html::rawElement( 'li', array(), $link );
294 - #$msg = wfMsgHtml( 'openstackmanager-configure' );
295 - #$link = Linker::link( $this->getTitle(), $msg, array(),
296 - # array( 'action' => 'configure',
297 - # 'project' => $project,
298 - # 'groupname' => $group->getGroupName() ) );
299 - #$actions .= Html::rawElement( 'li', array(), $link );
300 - $msg = wfMsgHtml( 'openstackmanager-addrule-action' );
301 - $link = Linker::link( $this->getTitle(), $msg, array(),
302 - array( 'action' => 'addrule',
303 - 'project' => $project,
304 - 'groupname' => $group->getGroupName() ) );
305 - $actions .= Html::rawElement( 'li', array(), $link );
306 - $actions = Html::rawElement( 'ul', array(), $actions );
 308+ array_push( $actions, $this->createActionLink( 'openstackmanager-delete', array( 'action' => 'delete', 'project' => $project, 'groupname' => $group->getGroupName() ) ) );
 309+ #array_push( $actions, $this->createActionLink( 'openstackmanager-configure', array( 'action' => 'configure', 'project' => $project, 'groupname' => $group->getGroupName() ) ) );
 310+ array_push( $actions, $this->createActionLink( 'openstackmanager-addrule-action', array( 'action' => 'addrule', 'project' => $project, 'groupname' => $group->getGroupName() ) ) );
307311 }
308 - $groupOut .= Html::rawElement( 'td', array(), $actions );
309 - if ( isset( $projectArr["$project"] ) ) {
310 - $projectArr["$project"] .= Html::rawElement( 'tr', array(), $groupOut );
311 - } else {
312 - $projectArr["$project"] = Html::rawElement( 'tr', array(), $groupOut );
313 - }
 312+ $this->pushRawResourceColumn( $groupRow, $this->createResourceList( $actions ) );
 313+ array_push( $groupRows, $groupRow );
314314 }
315 - foreach ( $userProjects as $project ) {
316 - $action = '';
317 - if ( $this->userLDAP->inRole( 'netadmin', $project ) ) {
318 - $action = Linker::link( $this->getTitle(), wfMsgHtml( 'openstackmanager-createnewsecuritygroup' ), array(),
319 - array( 'action' => 'create', 'project' => $project ) );
320 - $action = Html::rawElement( 'span', array( 'id' => 'novaaction' ), "[$action]" );
321 - }
322 - $projectName = Html::rawElement( 'span', array( 'class' => 'mw-customtoggle-' . $project, 'id' => 'novaproject' ), $project );
323 - $out .= Html::rawElement( 'h2', array(), "$projectName $action" );
324 - if ( isset( $projectArr["$project"] ) ) {
325 - $projectOut = $groupheader;
326 - $projectOut .= $projectArr["$project"];
327 - $projectOut = Html::rawElement( 'table', array( 'id' => 'novainstancelist', 'class' => 'wikitable sortable' ), $projectOut );
328 - }
329 - $out .= Html::rawElement( 'div', array( 'class' => 'mw-collapsible', 'id' => 'mw-customcollapsible-' . $project ), $projectOut );
 315+ if ( $groupRows ) {
 316+ return $this->createResourceTable( $groupHeaders, $groupRows );
 317+ } else {
 318+ return '';
330319 }
331 -
332 - $this->getOutput()->addHTML( $out );
333 - return true;
334320 }
335321
336322 /**
@@ -351,7 +337,7 @@
352338 $securityGroups = $this->adminNova->getSecurityGroups();
353339 foreach ( $securityGroups as $securityGroup ) {
354340 $securityGroupName = $securityGroup->getGroupName();
355 - $securityGroupProject = $securityGroup->getOwner();
 341+ $securityGroupProject = $securityGroup->getProject();
356342 $info["$securityGroupProject"]["$securityGroupName"] = $securityGroupName . ':' . $securityGroupProject;
357343 }
358344 $group_keys = $info;
Index: trunk/extensions/OpenStackManager/special/SpecialNovaAddress.php
@@ -1,4 +1,12 @@
22 <?php
 3+
 4+/**
 5+ * Special page from nova address
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
311 class SpecialNovaAddress extends SpecialNova {
412
513 var $adminNova;
@@ -147,7 +155,7 @@
148156 $instances = $this->userNova->getInstances();
149157 $instance_keys = array();
150158 foreach ( $instances as $instance ) {
151 - if ( $instance->getOwner() == $project ) {
 159+ if ( $instance->getProject() == $project ) {
152160 $instancename = $instance->getInstanceName();
153161 $instanceid = $instance->getInstanceId();
154162 $instance_keys["$instancename"] = $instanceid;
@@ -350,99 +358,95 @@
351359 $this->getOutput()->addModuleStyles( 'ext.openstack' );
352360 $this->getOutput()->setPagetitle( wfMsg( 'openstackmanager-addresslist' ) );
353361
354 - $userProjects = $this->userLDAP->getProjects();
 362+ if ( $this->userLDAP->inGlobalRole( 'cloudadmin' ) ) {
 363+ $projects = OpenStackNovaProject::getAllProjects();
 364+ } else {
 365+ $projects = OpenStackNovaProject::getProjectsByName( $this->userLDAP->getProjects() );
 366+ }
 367+ $projectfilter = $this->getProjectFilter();
 368+ if ( !$projectfilter ) {
 369+ $this->getOutput()->addWikiMsg( 'openstackmanager-setprojectfilter' );
 370+ $this->showProjectFilter( $projects, true );
 371+ return null;
 372+ }
 373+ $this->showProjectFilter( $projects );
 374+
355375 $out = '';
356376
357 - $header = Html::element( 'th', array(), wfMsg( 'openstackmanager-address' ) );
358 - $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-instanceid' ) );
359 - $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-instancename' ) );
360 - $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-hostnames' ) );
361 - $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-actions' ) );
362 - $addresses = $this->adminNova->getAddresses();
 377+ $addresses = $this->getResourcesGroupedByProject( $this->adminNova->getAddresses() );
 378+ $instances = $this->adminNova->getInstances();
363379 $projectArr = array();
 380+ $projectRows = Array();
 381+ foreach ( $projects as $project ) {
 382+ $projectName = $project->getProjectName();
 383+ if ( !in_array( $projectName, $projectfilter ) ) {
 384+ continue;
 385+ }
 386+ $actions = Array( 'netadmin' => Array() );
 387+ $actions['netadmin'][] = $this->createActionLink( 'openstackmanager-allocateaddress', array( 'action' => 'allocate', 'project' => $projectName ) );
 388+ $out .= $this->createProjectSection( $projectName, $actions, $this->getAddresses( $projectName, $this->getResourceByProject( $addresses, $projectName ), $instances ) );
 389+ }
 390+ $this->getOutput()->addHTML( $out );
 391+
 392+ return true;
 393+ }
 394+
 395+ function getAddresses( $projectName, $addresses, $instances ) {
 396+ $headers = Array( 'openstackmanager-address', 'openstackmanager-instanceid', 'openstackmanager-instancename',
 397+ 'openstackmanager-hostnames', 'openstackmanager-actions' );
 398+ $addressRows = Array();
 399+ /**
 400+ * @var $address OpenStackNovaAddress
 401+ */
364402 foreach ( $addresses as $address ) {
 403+ $addressRow = array();
365404 $ip = $address->getPublicIP();
366405 $instanceid = $address->getInstanceId();
367406 $project = $address->getProject();
368 - $addressOut = Html::element( 'td', array(), $ip );
 407+ $this->pushResourceColumn( $addressRow, $ip );
369408 if ( $instanceid ) {
370 - $addressOut .= Html::element( 'td', array(), $instanceid );
371 - $instance = $this->adminNova->getInstance( $instanceid );
372 - $instancename = $instance->getInstanceName();
373 - $addressOut .= Html::element( 'td', array(), $instancename );
 409+ $this->pushResourceColumn( $addressRow, $instanceid );
 410+ $instancename = $instances["$instanceid"]->getInstanceName();
 411+ $this->pushResourceColumn( $addressRow, $instancename );
374412 } else {
375 - $addressOut .= Html::element( 'td', array(), '' );
376 - $addressOut .= Html::element( 'td', array(), '' );
 413+ $this->pushResourceColumn( $addressRow, '' );
 414+ $this->pushResourceColumn( $addressRow, '' );
377415 }
378416 $hosts = OpenStackNovaHost::getHostsByIP( $ip );
379417 if ( $hosts ) {
380 - $hostsOut = '';
381418 $msg = wfMsgHtml( 'openstackmanager-removehost-action' );
 419+ $hostArr = Array();
382420 foreach ( $hosts as $host ) {
383421 $domain = $host->getDomain();
384422 $fqdns = $host->getAssociatedDomains();
385423 foreach ( $fqdns as $fqdn ) {
386424 $hostname = explode( '.', $fqdn );
387425 $hostname = $hostname[0];
388 - $link = Linker::link( $this->getTitle(), $msg, array(),
389 - array( 'action' => 'removehost', 'ip' => $ip, 'project' => $project, 'domain' => $domain->getDomainName(), 'hostname' => $hostname ) );
390 - $hostOut = htmlentities( $fqdn ) . ' ' . $link;
391 - $hostsOut .= Html::rawElement( 'li', array(), $hostOut );
 426+ $link = $this->createActionLink( 'openstackmanager-removehost-action', array( 'action' => 'removehost', 'ip' => $ip, 'project' => $project, 'domain' => $domain->getDomainName(), 'hostname' => $hostname ) );
 427+ array_push( $hostArr, htmlentities( $fqdn ) . ' ' . $link );
392428 }
393429 }
394 - $hostsOut = Html::rawElement( 'ul', array(), $hostsOut );
395 - $addressOut .= Html::rawElement( 'td', array(), $hostsOut );
 430+ $this->pushRawResourceColumn( $addressRow, $this->createResourceList( $hostArr ) );
396431 } else {
397 - $addressOut .= Html::element( 'td', array(), '' );
 432+ $this->pushResourceColumn( $addressRow, '' );
398433 }
399 - $actions = '';
 434+ $actions = Array();
400435 if ( $instanceid ) {
401 - $msg = wfMsgHtml( 'openstackmanager-reassociateaddress' );
 436+ array_push( $actions, $this->createActionLink( 'openstackmanager-reassociateaddress', array( 'action' => 'associate', 'ip' => $ip, 'project' => $project ) ) );
 437+ array_push( $actions, $this->createActionLink( 'openstackmanager-disassociateaddress', array( 'action' => 'disassociate', 'ip' => $ip, 'project' => $project ) ) );
402438 } else {
403 - $msg = wfMsgHtml( 'openstackmanager-releaseaddress' );
404 - $link = Linker::link( $this->getTitle(), $msg, array(),
405 - array( 'action' => 'release', 'ip' => $ip, 'project' => $project ) );
406 - $actions = Html::rawElement( 'li', array(), $link );
407 - $msg = wfMsgHtml( 'openstackmanager-associateaddress' );
 439+ array_push( $actions, $this->createActionLink( 'openstackmanager-releaseaddress', array( 'action' => 'release', 'ip' => $ip, 'project' => $project ) ) );
 440+ array_push( $actions, $this->createActionLink( 'openstackmanager-associateaddress', array( 'action' => 'associate', 'ip' => $ip, 'project' => $project ) ) );
408441 }
409 - $link = Linker::link( $this->getTitle(), $msg, array(),
410 - array( 'action' => 'associate', 'ip' => $ip, 'project' => $project ) );
411 - $actions .= Html::rawElement( 'li', array(), $link );
412 - if ( $instanceid ) {
413 - $msg = wfMsgHtml( 'openstackmanager-disassociateaddress' );
414 - $link = Linker::link( $this->getTitle(), $msg, array(),
415 - array( 'action' => 'disassociate', 'ip' => $ip, 'project' => $project ) );
416 - $actions .= Html::rawElement( 'li', array(), $link );
417 - }
418 - $msg = wfMsgHtml( 'openstackmanager-addhost' );
419 - $link = Linker::link( $this->getTitle(), $msg, array(),
420 - array( 'action' => 'addhost', 'ip' => $ip, 'project' => $project ) );
421 - $actions .= Html::rawElement( 'li', array(), $link );
422 - $actions = Html::rawElement( 'ul', array(), $actions );
423 - $addressOut .= Html::rawElement( 'td', array(), $actions );
424 - if ( isset( $projectArr["$project"] ) ) {
425 - $projectArr["$project"] .= Html::rawElement( 'tr', array(), $addressOut );
426 - } else {
427 - $projectArr["$project"] = Html::rawElement( 'tr', array(), $addressOut );
428 - }
 442+ array_push( $actions, $this->createActionLink( 'openstackmanager-addhost', array( 'action' => 'addhost', 'ip' => $ip, 'project' => $project ) ) );
 443+ $this->pushRawResourceColumn( $addressRow, $this->createResourceList( $actions ) );
 444+ array_push( $addressRows, $addressRow );
429445 }
430 - foreach ( $userProjects as $project ) {
431 - $action = Linker::link( $this->getTitle(), wfMsgHtml( 'openstackmanager-allocateaddress' ), array(), array( 'action' => 'allocate', 'project' => $project ) );
432 - $action = Html::rawElement( 'span', array( 'id' => 'novaaction' ), "[$action]" );
433 - $projectName = Html::rawElement( 'span', array( 'class' => 'mw-customtoggle-' . $project, 'id' => 'novaproject' ), $project );
434 - $out .= Html::rawElement( 'h2', array(), "$projectName $action" );
435 - $projectOut = '';
436 - if ( isset( $projectArr["$project"] ) ) {
437 - $projectOut = $header;
438 - $projectOut .= $projectArr["$project"];
439 - $projectOut = Html::rawElement( 'table',
440 - array( 'id' => 'novainstancelist', 'class' => 'wikitable sortable collapsible' ), $projectOut );
441 - }
442 - $out .= Html::rawElement( 'div', array( 'class' => 'mw-collapsible', 'id' => 'mw-customcollapsible-' . $project ), $projectOut );
 446+ if ( $addressRows ) {
 447+ return $this->createResourceTable( $headers, $addressRows );
 448+ } else {
 449+ return '';
443450 }
444 - $this->getOutput()->addHTML( $out );
445 -
446 - return true;
447451 }
448452
449453 /**
Index: trunk/extensions/OpenStackManager/special/SpecialNovaProject.php
@@ -1,4 +1,12 @@
22 <?php
 3+
 4+/**
 5+ * To do: comment me
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
311 class SpecialNovaProject extends SpecialNova {
412
513 var $adminNova;
@@ -155,118 +163,117 @@
156164 * @return void
157165 */
158166 function listProjects() {
 167+ global $wgRequest;
 168+
159169 $this->setHeaders();
160170 $this->getOutput()->setPageTitle( wfMsg( 'openstackmanager-projectlist' ) );
161171 $this->getOutput()->addModuleStyles( 'ext.openstack' );
162172
163173 if ( $this->userLDAP->inGlobalRole( 'cloudadmin' ) ) {
164 - $projectInfo = array();
165 - $projectInfo['projectname'] = array(
166 - 'type' => 'text',
167 - 'label-message' => 'openstackmanager-projectname',
168 - 'validation-callback' => array( $this, 'validateText' ),
169 - 'default' => '',
170 - 'section' => 'project',
171 - 'name' => 'projectname',
172 - );
173 - $projectInfo['member'] = array(
174 - 'type' => 'text',
175 - 'label-message' => 'openstackmanager-member',
176 - 'default' => '',
177 - 'section' => 'project',
178 - 'name' => 'member',
179 - );
180 - $role_keys = array();
181 - foreach ( OpenStackNovaProject::$rolenames as $rolename ) {
182 - $role_keys["$rolename"] = $rolename;
183 - }
184 - $projectInfo['roles'] = array(
185 - 'type' => 'multiselect',
186 - 'label-message' => 'openstackmanager-roles',
187 - 'section' => 'project',
188 - 'options' => $role_keys,
189 - 'name' => 'roles',
190 - );
191 -
192 - $projectInfo['action'] = array(
193 - 'type' => 'hidden',
194 - 'default' => 'create',
195 - 'name' => 'action',
196 - );
197 -
198 - $projectForm = new SpecialNovaProjectForm( $projectInfo, 'openstackmanager-novaproject' );
199 - $projectForm->setTitle( SpecialPage::getTitleFor( 'NovaProject' ) );
200 - $projectForm->setSubmitID( 'novaproject-form-createprojectsubmit' );
201 - $projectForm->setSubmitCallback( array( $this, 'tryCreateSubmit' ) );
202 - $projectForm->show();
 174+ $projects = OpenStackNovaProject::getAllProjects();
 175+ $this->showCreateProject();
 176+ } else {
 177+ $projects = OpenStackNovaProject::getProjectsByName( $this->userLDAP->getProjects() );
203178 }
 179+ $projectfilter = $this->getProjectFilter();
 180+ if ( !$projectfilter ) {
 181+ $this->getOutput()->addWikiMsg( 'openstackmanager-setprojectfilter' );
 182+ $this->showProjectFilter( $projects, true );
 183+ return null;
 184+ }
 185+ $this->showProjectFilter( $projects );
204186
205187 $out = '';
206188
207 - $header = Html::element( 'th', array(), wfMsg( 'openstackmanager-members' ) );
208 - $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-roles' ) );
209 - $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-actions' ) );
210 - $projects = OpenStackNovaProject::getAllProjects();
211 - if ( ! $projects ) {
212 - $projectsOut = '';
213 - }
214189 foreach ( $projects as $project ) {
215190 $projectName = $project->getProjectName();
216 - $projectName = htmlentities( $projectName );
217 - $out .= Html::rawElement( 'h2', array( 'class' => 'mw-customtoggle-' . $projectName, 'id' => 'novaproject' ), $projectName );
218 - $projectMembers = $project->getMembers();
219 - $memberOut = '';
220 - foreach ( $projectMembers as $projectMember ) {
221 - $memberOut .= Html::element( 'li', array(), $projectMember );
 191+ if ( !in_array( $projectName, $projectfilter ) ) {
 192+ continue;
222193 }
223 - if ( $memberOut ) {
224 - $memberOut = Html::rawElement( 'ul', array(), $memberOut );
225 - }
226 - $projectOut = Html::rawElement( 'td', array(), $memberOut );
227 - $rolesOut = Html::element( 'th', array(), wfMsg( 'openstackmanager-rolename' ) );
228 - $rolesOut .= Html::element( 'th', array(), wfMsg( 'openstackmanager-members' ) );
229 - $rolesOut .= Html::element( 'th', array(), wfMsg( 'openstackmanager-actions' ) );
230 - foreach ( $project->getRoles() as $role ) {
231 - $roleOut = Html::element( 'td', array(), $role->getRoleName() );
232 - $roleMembers = '';
233 - $specialRoleTitle = Title::newFromText( 'Special:NovaRole' );
234 - foreach ( $role->getMembers() as $member ) {
235 - $roleMembers .= Html::element( 'li', array(), $member );
236 - }
237 - $roleMembers = Html::rawElement( 'ul', array(), $roleMembers );
238 - $roleOut .= Html::rawElement( 'td', array(), $roleMembers );
239 - $link = Linker::link( $specialRoleTitle, wfMsgHtml( 'openstackmanager-addrolemember' ), array(),
240 - array( 'action' => 'addmember', 'projectname' => $projectName, 'rolename' => $role->getRoleName(), 'returnto' => 'Special:NovaProject' ) );
241 - $actions = Html::rawElement( 'li', array(), $link );
242 - $link = Linker::link( $specialRoleTitle, wfMsgHtml( 'openstackmanager-removerolemember' ), array(),
243 - array( 'action' => 'deletemember', 'projectname' => $projectName, 'rolename' => $role->getRoleName(), 'returnto' => 'Special:NovaProject' ) );
244 - $actions .= Html::rawElement( 'li', array(), $link );
245 - $actions = Html::rawElement( 'ul', array(), $actions );
246 - $roleOut .= Html::rawElement( 'td', array(), $actions );
247 - $rolesOut .= Html::rawElement( 'tr', array(), $roleOut );
248 - }
249 - $rolesOut = Html::rawElement( 'table', array( 'class' => 'wikitable sortable collapsible' ), $rolesOut );
250 - $projectOut .= Html::rawElement( 'td', array( 'class' => 'Nova_cell' ), $rolesOut );
251 - $link = Linker::link( $this->getTitle(), wfMsgHtml( 'openstackmanager-deleteproject' ), array(),
252 - array( 'action' => 'delete', 'projectname' => $projectName ) );
253 - $actions = Html::rawElement( 'li', array(), $link );
254 - $link = Linker::link( $this->getTitle(), wfMsgHtml( 'openstackmanager-addmember' ), array(),
255 - array( 'action' => 'addmember', 'projectname' => $projectName ) );
256 - $actions .= Html::rawElement( 'li', array(), $link );
257 - $link = Linker::link( $this->getTitle(), wfMsgHtml( 'openstackmanager-removemember' ), array(),
258 - array( 'action' => 'deletemember', 'projectname' => $projectName ) );
259 - $actions .= Html::rawElement( 'li', array(), $link );
260 - $actions = Html::rawElement( 'ul', array(), $actions );
261 - $projectOut .= Html::rawElement( 'td', array(), $actions );
262 - $projectOut = Html::rawElement( 'tr', array(), $projectOut );
263 - $projectOut = $header . $projectOut;
264 - $projectOut = Html::rawElement( 'table', array( 'class' => 'wikitable sortable collapsible' ), $projectOut );
265 - $out .= Html::rawElement( 'div', array( 'class' => 'mw-collapsible', 'id' => 'mw-customcollapsible-' . $projectName ), $projectOut );
 194+ $actions = Array();
 195+ $out .= $this->createProjectSection( $projectName, $actions, $this->getProject( $project ) );
266196 }
267197
268198 $this->getOutput()->addHTML( $out );
269199 }
270200
 201+ function getProject( $project ) {
 202+ $headers = Array( 'openstackmanager-rolename', 'openstackmanager-members', 'openstackmanager-actions' );
 203+ $projectRows = Array();
 204+ $projectRow = Array();
 205+ $this->pushRawResourceColumn( $projectRow, $this->createResourceList( $project->getMembers() ) );
 206+ $roleRows = Array();
 207+ $projectName = $project->getProjectName();
 208+ foreach ( $project->getRoles() as $role ) {
 209+ $roleRow = Array();
 210+ $roleName = $role->getRoleName();
 211+ $this->pushResourceColumn( $roleRow, $roleName );
 212+ $this->pushRawResourceColumn( $roleRow, $this->createResourceList( $role->getMembers() ) );
 213+ $actions= Array();
 214+ $specialRoleTitle = Title::newFromText( 'Special:NovaRole' );
 215+ array_push( $actions, $this->createActionLink( 'openstackmanager-addrolemember', array( 'action' => 'addmember', 'projectname' => $projectName, 'rolename' => $roleName, 'returnto' => 'Special:NovaProject' ), $specialRoleTitle ) );
 216+ array_push( $actions, $this->createActionLink( 'openstackmanager-removerolemember', array( 'action' => 'deletemember', 'projectname' => $projectName, 'rolename' => $roleName, 'returnto' => 'Special:NovaProject' ), $specialRoleTitle ) );
 217+ $this->pushRawResourceColumn( $roleRow, $this->createResourceList( $actions ) );
 218+ array_push( $roleRows, $roleRow );
 219+ }
 220+ // TODO: add back in Nova_cell class to this column
 221+ $this->pushRawResourceColumn( $projectRow, $this->createResourceTable( $headers, $roleRows ) );
 222+ $actions = Array();
 223+ array_push( $actions, $this->createActionLink( 'openstackmanager-deleteproject', array( 'action' => 'delete', 'projectname' => $projectName ) ) );
 224+ array_push( $actions, $this->createActionLink( 'openstackmanager-addmember', array( 'action' => 'addmember', 'projectname' => $projectName ) ) );
 225+ array_push( $actions, $this->createActionLink( 'openstackmanager-removemember', array( 'action' => 'deletemember', 'projectname' => $projectName ) ) );
 226+ $this->pushRawResourceColumn( $projectRow, $this->createResourceList( $actions ) );
 227+ array_push( $projectRows, $projectRow );
 228+ return $this->createResourceTable( $headers, $projectRows );
 229+ }
 230+
 231+ function showCreateProject() {
 232+ global $wgRequest;
 233+
 234+ if ( $wgRequest->wasPosted() && $wgRequest->getVal( 'action' ) != 'create' ) {
 235+ return null;
 236+ }
 237+ $projectInfo = array();
 238+ $projectInfo['projectname'] = array(
 239+ 'type' => 'text',
 240+ 'label-message' => 'openstackmanager-projectname',
 241+ 'validation-callback' => array( $this, 'validateText' ),
 242+ 'default' => '',
 243+ 'section' => 'project',
 244+ 'name' => 'projectname',
 245+ );
 246+ $projectInfo['member'] = array(
 247+ 'type' => 'text',
 248+ 'label-message' => 'openstackmanager-member',
 249+ 'default' => '',
 250+ 'section' => 'project',
 251+ 'name' => 'member',
 252+ );
 253+ $role_keys = array();
 254+ foreach ( OpenStackNovaProject::$rolenames as $rolename ) {
 255+ $role_keys["$rolename"] = $rolename;
 256+ }
 257+ $projectInfo['roles'] = array(
 258+ 'type' => 'multiselect',
 259+ 'label-message' => 'openstackmanager-roles',
 260+ 'section' => 'project',
 261+ 'options' => $role_keys,
 262+ 'name' => 'roles',
 263+ );
 264+
 265+ $projectInfo['action'] = array(
 266+ 'type' => 'hidden',
 267+ 'default' => 'create',
 268+ 'name' => 'action',
 269+ );
 270+
 271+ $projectForm = new SpecialNovaProjectForm( $projectInfo, 'openstackmanager-novaproject' );
 272+ $projectForm->setTitle( SpecialPage::getTitleFor( 'NovaProject' ) );
 273+ $projectForm->setSubmitID( 'novaproject-form-createprojectsubmit' );
 274+ $projectForm->setSubmitCallback( array( $this, 'tryCreateSubmit' ) );
 275+ $projectForm->show();
 276+ }
 277+
271278 /**
272279 * @param $formData
273280 * @param string $entryPoint
Index: trunk/extensions/OpenStackManager/special/SpecialNovaDomain.php
@@ -1,4 +1,12 @@
22 <?php
 3+
 4+/**
 5+ * Special page from nova domain
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
311 class SpecialNovaDomain extends SpecialNova {
412
513 var $adminNova;
@@ -119,28 +127,22 @@
120128 $domainForm->setSubmitCallback( array( $this, 'tryCreateSubmit' ) );
121129 $domainForm->show();
122130
123 - $out = '';
124 -
125 - $domainsOut = Html::element( 'th', array(), wfMsg( 'openstackmanager-domainname' ) );
126 - $domainsOut .= Html::element( 'th', array(), wfMsg( 'openstackmanager-fqdn' ) );
127 - $domainsOut .= Html::element( 'th', array(), wfMsg( 'openstackmanager-location' ) );
128 - $domainsOut .= Html::element( 'th', array(), wfMsg( 'openstackmanager-actions' ) );
 131+ $headers = Array( 'openstackmanager-domainname', 'openstackmanager-fqdn', 'openstackmanager-location', 'openstackmanager-actions' );
129132 $domains = OpenStackNovaDomain::getAllDomains();
 133+ $domainRows = Array();
130134 foreach ( $domains as $domain ) {
 135+ $domainRow = Array();
131136 $domainName = $domain->getDomainName();
132 - $fqdn = $domain->getFullyQualifiedDomainName();
133 - $location = $domain->getLocation();
134 - $domainOut = Html::element( 'td', array(), $domainName );
135 - $domainOut .= Html::element( 'td', array(), $fqdn );
136 - $domainOut .= Html::element( 'td', array(), $location );
137 - $msg = wfMsgHtml( 'openstackmanager-delete' );
138 - $link = Linker::link( $this->getTitle(), $msg, array(),
139 - array( 'action' => 'delete', 'domainname' => $domainName ) );
140 - $domainOut .= Html::rawElement( 'td', array(), $link );
141 - $domainsOut .= Html::rawElement( 'tr', array(), $domainOut );
 137+ $this->pushResourceColumn( $domainRow, $domainName );
 138+ $this->pushResourceColumn( $domainRow, $domain->getFullyQualifiedDomainName() );
 139+ $this->pushResourceColumn( $domainRow, $domain->getLocation() );
 140+ $this->pushRawResourceColumn( $domainRow, $this->createActionLink( 'openstackmanager-delete', array( 'action' => 'delete', 'domainname' => $domainName ) ) );
 141+ array_push( $domainRows, $domainRow );
142142 }
143 - if ( $domains ) {
144 - $out .= Html::rawElement( 'table', array( 'class' => 'wikitable sortable collapsible' ), $domainsOut );
 143+ if ( $domainRows ) {
 144+ $out = createResourceTable( $headers, $domainRows );
 145+ } else {
 146+ $out = '';
145147 }
146148
147149 $this->getOutput()->addHTML( $out );
Index: trunk/extensions/OpenStackManager/special/SpecialNovaVolume.php
@@ -1,4 +1,12 @@
22 <?php
 3+
 4+/**
 5+ * todo comment me
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
311 class SpecialNovaVolume extends SpecialNova {
412
513 /**
@@ -196,7 +204,7 @@
197205 $instances = $this->userNova->getInstances();
198206 $instance_keys = array();
199207 foreach ( $instances as $instance ) {
200 - if ( $instance->getOwner() == $project ) {
 208+ if ( $instance->getProject() == $project ) {
201209 $instancename = $instance->getInstanceName();
202210 $instanceid = $instance->getInstanceId();
203211 $instance_keys["$instancename"] = $instanceid;
@@ -311,91 +319,77 @@
312320 */
313321 function listVolumes() {
314322 $this->setHeaders();
 323+ $this->getOutput()->addModuleStyles( 'ext.openstack' );
315324 $this->getOutput()->setPagetitle( wfMsg( 'openstackmanager-volumelist' ) );
316325
317 - $userProjects = $this->userLDAP->getProjects();
 326+ if ( $this->userLDAP->inGlobalRole( 'cloudadmin' ) ) {
 327+ $projects = OpenStackNovaProject::getAllProjects();
 328+ } else {
 329+ $projects = OpenStackNovaProject::getProjectsByName( $this->userLDAP->getProjects() );
 330+ }
 331+ $projectfilter = $this->getProjectFilter();
 332+ if ( !$projectfilter ) {
 333+ $this->getOutput()->addWikiMsg( 'openstackmanager-setprojectfilter' );
 334+ $this->showProjectFilter( $projects, true );
 335+ return null;
 336+ }
 337+ $this->showProjectFilter( $projects );
318338
319339 $out = '';
320 - $volumes = $this->adminNova->getVolumes();
321 - $header = Html::element( 'th', array(), wfMsg( 'openstackmanager-volumename' ) );
322 - $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-volumeid' ) );
323 - $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-volumedescription' ) );
324 - $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-volumestate' ) );
325 - $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-volumeattachmentinstance' ) );
326 - $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-volumeattachmentdevice' ) );
327 - $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-volumeattachmentstatus' ) );
328 - $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-volumesize' ) );
329 - $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-volumedeleteonvolumedelete' ) );
330 - $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-availabilityzone' ) );
331 - $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-volumecreationtime' ) );
332 - $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-actions' ) );
333 - $projectArr = array();
334 - foreach ( $volumes as $volume ) {
335 - $project = $volume->getOwner();
336 - if ( ! in_array( $project, $userProjects ) ) {
 340+
 341+ $volumes = $this->getResourcesGroupedByProject( $this->adminNova->getVolumes() );
 342+ foreach ( $projects as $project ) {
 343+ $projectName = $project->getProjectName();
 344+ if ( !in_array( $projectName, $projectfilter ) ) {
337345 continue;
338346 }
339 - $volumeOut = Html::element( 'td', array(), $volume->getVolumeName() );
340 - $volumeId = $volume->getVolumeId();
341 - $volumeId = htmlentities( $volumeId );
342 - $title = Title::newFromText( $volumeId, NS_NOVA_RESOURCE );
343 - $volumeIdLink = Linker::link( $title, $volumeId );
344 - $volumeOut .= Html::rawElement( 'td', array(), $volumeIdLink );
345 - $volumeOut .= Html::element( 'td', array(), $volume->getVolumeDescription() );
346 - $volumeOut .= Html::element( 'td', array(), $volume->getVolumeStatus() );
347 - $volumeOut .= Html::element( 'td', array(), $volume->getAttachedInstanceId() );
348 - $volumeOut .= Html::element( 'td', array(), $volume->getAttachedDevice() );
349 - $volumeOut .= Html::element( 'td', array(), $volume->getAttachmentStatus() );
350 - $volumeOut .= Html::element( 'td', array(), $volume->getVolumeSize() );
351 - $volumeOut .= Html::element( 'td', array(), $volume->deleteOnInstanceDeletion() );
352 - $volumeOut .= Html::element( 'td', array(), $volume->getVolumeAvailabilityZone() );
353 - $volumeOut .= Html::element( 'td', array(), $volume->getVolumeCreationTime() );
354 - $msg = wfMsgHtml( 'openstackmanager-delete' );
355 - $link = Linker::link( $this->getTitle(), $msg, array(),
356 - array( 'action' => 'delete',
357 - 'project' => $project,
358 - 'volumeid' => $volume->getVolumeId() ) );
359 - $actions = Html::rawElement( 'li', array(), $link );
360 - #$msg = wfMsgHtml( 'openstackmanager-rename' );
361 - #$actions .= Linker::link( $this->getTitle(), $msg, array(),
362 - # array( 'action' => 'rename',
363 - # 'project' => $project,
364 - # 'volumeid' => $volume->getVolumeId() ) );
365 - $msg = wfMsgHtml( 'openstackmanager-attach' );
366 - $link = Linker::link( $this->getTitle(), $msg, array(),
367 - array( 'action' => 'attach',
368 - 'project' => $project,
369 - 'volumeid' => $volume->getVolumeId() ) );
370 - $actions .= Html::rawElement( 'li', array(), $link );
371 - $msg = wfMsgHtml( 'openstackmanager-detach' );
372 - $link = Linker::link( $this->getTitle(), $msg, array(),
373 - array( 'action' => 'detach',
374 - 'project' => $project,
375 - 'volumeid' => $volume->getVolumeId() ) );
376 - $actions .= Html::rawElement( 'li', array(), $link );
377 - $actions = Html::rawElement( 'ul', array(), $actions );
378 - $volumeOut .= Html::rawElement( 'td', array(), $actions );
379 - if ( isset( $projectArr["$project"] ) ) {
380 - $projectArr["$project"] .= Html::rawElement( 'tr', array(), $volumeOut );
381 - } else {
382 - $projectArr["$project"] = Html::rawElement( 'tr', array(), $volumeOut );
 347+ if ( !array_key_exists( $projectName, $volumes ) ) {
 348+ continue;
383349 }
 350+ $actions = Array( 'sysadmin' => Array() );
 351+ $actions['sysadmin'][] = $this->createActionLink( 'openstackmanager-createvolume', array( 'action' => 'create', 'project' => $projectName ) );
 352+ $out .= $this->createProjectSection( $projectName, $actions, $this->getVolumes( $projectName, $this->getResourceByProject( $volumes, $projectName ) ) );
384353 }
385 - foreach ( $userProjects as $project ) {
386 - $out .= Html::element( 'h2', array(), $project );
387 - $out .= Linker::link( $this->getTitle(), wfMsgHtml( 'openstackmanager-createvolume' ), array(),
388 - array( 'action' => 'create', 'project' => $project ) );
389 - if ( isset( $projectArr["$project"] ) ) {
390 - $projectOut = $header;
391 - $projectOut .= $projectArr["$project"];
392 - $out .= Html::rawElement( 'table',
393 - array( 'id' => 'novavolumelist', 'class' => 'wikitable sortable collapsible' ), $projectOut );
394 - }
395 - }
396354
397355 $this->getOutput()->addHTML( $out );
398356 }
399357
 358+ function getVolumes( $projectName, $volumes ) {
 359+ $headers = Array( 'openstackmanager-volumename', 'openstackmanager-volumeid', 'openstackmanager-volumedescription',
 360+ 'openstackmanager-volumestate', 'openstackmanager-volumeattachmentinstance',
 361+ 'openstackmanager-volumeattachmentdevice', 'openstackmanager-volumeattachmentstatus',
 362+ 'openstackmanager-volumesize', 'openstackmanager-volumedeleteonvolumedelete',
 363+ 'openstackmanager-availabilityzone', 'openstackmanager-volumecreationtime', 'openstackmanager-actions' );
 364+ $volumeRows = Array();
 365+ foreach ( $volumes as $volume ) {
 366+ $volumeRow = Array();
 367+ $this->pushResourceColumn( $volumeRow, $volume->getVolumeName() );
 368+ $volumeId = $volume->getVolumeId();
 369+ $this->pushRawResourceColumn( $volumeRow, $this->createResourceLink( $volumeId ) );
 370+ $this->pushResourceColumn( $volumeRow, $volume->getVolumeDescription() );
 371+ $this->pushResourceColumn( $volumeRow, $volume->getVolumeStatus() );
 372+ $this->pushResourceColumn( $volumeRow, $volume->getAttachedInstanceId() );
 373+ $this->pushResourceColumn( $volumeRow, $volume->getAttachedDevice() );
 374+ $this->pushResourceColumn( $volumeRow, $volume->getAttachmentStatus() );
 375+ $this->pushResourceColumn( $volumeRow, $volume->getVolumeSize() );
 376+ $this->pushResourceColumn( $volumeRow, $volume->deleteOnInstanceDeletion() );
 377+ $this->pushResourceColumn( $volumeRow, $volume->getVolumeAvailabilityZone() );
 378+ $this->pushResourceColumn( $volumeRow, $volume->getVolumeCreationTime() );
 379+ $actions = Array();
 380+ array_push( $actions, $this->createActionLink( 'openstackmanager-delete', array( 'action' => 'delete', 'project' => $projectName, 'volumeid' => $volumeId ) ) );
 381+ #array_push( $actions, $this->createActionLink( 'openstackmanager-rename', array( 'action' => 'rename', 'project' => $projectName, 'volumeid' => $volumeId ) ) );
 382+ array_push( $actions, $this->createActionLink( 'openstackmanager-attach', array( 'action' => 'attach', 'project' => $projectName, 'volumeid' => $volumeId ) ) );
 383+ array_push( $actions, $this->createActionLink( 'openstackmanager-detach', array( 'action' => 'detach', 'project' => $projectName, 'volumeid' => $volumeId ) ) );
 384+ $this->pushRawResourceColumn( $volumeRow, $this->createResourceList( $actions ) );
 385+ array_push( $volumeRows, $volumeRow );
 386+ }
 387+ if ( $volumeRows ) {
 388+ return $this->createResourceTable( $headers, $volumeRows );
 389+ } else {
 390+ return '';
 391+ }
 392+ }
 393+
400394 /**
401395 * @param $formData
402396 * @param string $entryPoint
Index: trunk/extensions/OpenStackManager/special/SpecialNovaKey.php
@@ -1,4 +1,12 @@
22 <?php
 3+
 4+/**
 5+ * special page for nova key
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
311 class SpecialNovaKey extends SpecialNova {
412
513 var $userNova;
@@ -142,6 +150,7 @@
143151 $out = '';
144152
145153 if ( $wgOpenStackManagerNovaKeypairStorage == 'nova' ) {
 154+ # TODO: add project filter
146155 foreach ( $projects as $project ) {
147156 $userCredentials = $this->userLDAP->getCredentials();
148157 $this->userNova = new OpenStackNovaController( $userCredentials, $project );
@@ -150,50 +159,50 @@
151160 continue;
152161 }
153162 $out .= Html::element( 'h2', array(), $project );
154 - $projectOut = Html::element( 'th', array(), wfMsg( 'openstackmanager-name' ) );
155 - $projectOut .= Html::element( 'th', array(), wfMsg( 'openstackmanager-fingerprint' ) );
 163+ $headers = Array( 'openstackmanager-name', 'openstackmanager-fingerprint' );
 164+ $keyRows = Array();
156165 foreach ( $keypairs as $keypair ) {
157 - $keyOut = Html::element( 'td', array( 'class' => 'Nova_col' ), $keypair->getKeyName() );
158 - $keyOut .= Html::element( 'td', array(), $keypair->getKeyFingerprint() );
159 - $projectOut .= Html::rawElement( 'tr', array(), $keyOut );
 166+ $keyRow = Array();
 167+ $this->pushResourceColumn( $keyRow, $keypair->getKeyName() );
 168+ $this->pushResourceColumn( $keyRow, $keypair->getKeyFingerprint() );
 169+ array_push( $keyRows, $keyRow );
160170 }
161 - $out .= Html::rawElement( 'table', array( 'id' => 'novakeylist', 'class' => 'wikitable sortable collapsible' ), $projectOut );
 171+ $out .= $this->createResourceTable( $headers, $keyRows );
162172 }
163173 } elseif ( $wgOpenStackManagerNovaKeypairStorage == 'ldap' ) {
 174+ $headers = Array( 'openstackmanager-keys', 'openstackmanager-actions' );
164175 $keypairs = $this->userLDAP->getKeypairs();
165 - $keysOut = '';
166 - $keysOut .= Html::element( 'th', array(), wfMsg( 'openstackmanager-keys' ) );
167 - $keysOut .= Html::element( 'th', array(), wfMsg( 'openstackmanager-actions' ) );
 176+ $keyRows = Array();
168177 foreach ( $keypairs as $hash => $key ) {
169 - $keyOut = Html::element( 'td', array( 'class' => 'Nova_col' ), $key );
170 - $msg = wfMsgHtml( 'openstackmanager-delete' );
171 - $link = Linker::link( $this->getTitle(), $msg, array(), array( 'action' => 'delete', 'hash' => $hash ) );
172 - $action = Html::rawElement( 'li', array(), $link );
173 - $action = Html::rawElement( 'ul', array(), $action );
174 - $keyOut .= Html::rawElement( 'td', array(), $action );
175 - $keysOut .= Html::rawElement( 'tr', array(), $keyOut );
 178+ $keyRow = Array();
 179+ # TODO: add Nova_col class back to this column
 180+ $this->pushResourceColumn( $keyRow, $key );
 181+ $actions = Array();
 182+ array_push( $actions, $this->createActionLink( 'openstackmanager-delete', array( 'action' => 'delete', 'hash' => $hash ) ) );
 183+ $this->pushResourceColumn( $keyRow, $this->createResourceList( $actions) );
 184+ array_push( $keyRows, $keyRow );
176185 }
177 - $out .= Html::rawElement( 'table', array( 'id' => 'novakeylist', 'class' => 'wikitable' ), $keysOut );
 186+ $out .= $this->createResourceTable( $headers, $keyRows );
178187 } else {
179188 $this->getOutput()->addWikiMsg( 'openstackmanager-invalidkeypair' );
180189 }
181190
182191 $this->getOutput()->addHTML( $out );
183192 }
184 -
 193+
185194 /**
186195 * Converts a public ssh key to openssh format.
187196 * @param $keydata SSH public/private key in some format
188197 * @return mixed Public key in openssh format or false
189198 */
190 - static function opensshFormatKey($keydata) {
 199+ static function opensshFormatKey( $keydata ) {
191200 global $wgSshKeygen, $wgPuttygen;
192201
193202 $public = self::opensshFormatKeySshKeygen( $keydata );
194203
195204 if ( !$public )
196205 $public = self::opensshFormatKeyPuttygen( $keydata );
197 -
 206+
198207 return $public;
199208 }
200209
@@ -202,8 +211,9 @@
203212 * @param $keydata SSH public/private key in some format
204213 * @return mixed Public key in openssh format or false
205214 */
206 - static function opensshFormatKeyPuttygen($keydata) {
 215+ static function opensshFormatKeyPuttygen( $keydata ) {
207216 global $wgPuttygen;
 217+
208218 if ( wfIsWindows() || !$wgPuttygen )
209219 return false;
210220
@@ -215,7 +225,7 @@
216226 fwrite( $tmpfile, $keydata );
217227
218228 $descriptorspec = array(
219 - 0 => $tmpfile,
 229+ 0 => $tmpfile,
220230 1 => array("pipe", "w"),
221231 2 => array("file", wfGetNull(), "a")
222232 );
@@ -248,14 +258,14 @@
249259
250260 return $data;
251261 }
252 -
253 - /**
 262+ /**
254263 * Converts a public ssh key to openssh format, using ssh-keygen.
255264 * @param $keydata SSH public/private key in some format
256265 * @return mixed Public key in openssh format or false
257266 */
258 - static function opensshFormatKeySshKeygen($keydata) {
 267+ static function opensshFormatKeySshKeygen( $keydata ) {
259268 global $wgSshKeygen;
 269+
260270 if ( wfIsWindows() || !$wgSshKeygen )
261271 return false;
262272
@@ -265,7 +275,7 @@
266276 }
267277
268278 $descriptorspec = array(
269 - 0 => array("pipe", "r"),
 279+ 0 => array("pipe", "r"),
270280 1 => array("pipe", "w"),
271281 2 => array("file", wfGetNull(), "a")
272282 );
@@ -287,7 +297,6 @@
288298 return $data;
289299 }
290300
291 -
292301 /**
293302 * @param $formData
294303 * @param string $entryPoint
@@ -307,9 +316,9 @@
308317 }
309318 $this->getOutput()->addWikiMsg( 'openstackmanager-keypairformatconverted' );
310319 }
311 -
 320+
312321 if ( $wgOpenStackManagerNovaKeypairStorage == 'ldap' ) {
313 - $success = $this->userLDAP->importKeypair( $key );
 322+ $success = $this->userLDAP->importKeypair( $formData['key'] );
314323 if ( ! $success ) {
315324 $this->getOutput()->addWikiMsg( 'openstackmanager-keypairimportfailed' );
316325 return false;
Index: trunk/extensions/OpenStackManager/special/SpecialNovaPuppetGroup.php
@@ -1,4 +1,12 @@
22 <?php
 3+
 4+/**
 5+ * todo comment me
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
311 class SpecialNovaPuppetGroup extends SpecialNova {
412
513 function __construct() {
@@ -605,24 +613,37 @@
606614 $this->getOutput()->setPagetitle( wfMsg( 'openstackmanager-puppetgrouplist' ) );
607615 $this->getOutput()->addModuleStyles( 'ext.openstack' );
608616
 617+ if ( $this->userLDAP->inGlobalRole( 'cloudadmin' ) ) {
 618+ $projects = OpenStackNovaProject::getAllProjects();
 619+ } else {
 620+ $projects = OpenStackNovaProject::getProjectsByName( $this->userLDAP->getProjects() );
 621+ }
 622+ $projectfilter = $this->getProjectFilter();
 623+ if ( !$projectfilter ) {
 624+ $this->getOutput()->addWikiMsg( 'openstackmanager-setprojectfilter' );
 625+ $this->showProjectFilter( $projects, true );
 626+ return null;
 627+ }
 628+ $this->showProjectFilter( $projects );
 629+
609630 $out = '';
610 - $projects = $this->userLDAP->getProjects();
611631 foreach ( $projects as $project ) {
612 - if ( !$this->userLDAP->inRole( 'sysadmin', $project ) ) {
 632+ $projectName = $project->getProjectName();
 633+ if ( $projectfilter && !in_array( $projectName, $projectfilter ) ) {
613634 continue;
614635 }
615 - $action = Linker::link( $this->getTitle(), wfMsgHtml( 'openstackmanager-createpuppetgroup' ), array(), array( 'action' => 'create', 'project' => $project ) );
616 - $action = Html::rawElement( 'span', array( 'id' => 'novaaction' ), "[$action]" );
617 - $projectName = Html::rawElement( 'span', array( 'class' => 'mw-customtoggle-' . $project, 'id' => 'novaproject' ), $project );
618 - $out .= Html::rawElement( 'h2', array(), "$projectName $action" );
619 - $groupsOut = $this->getPuppetGroupOutput( OpenStackNovaPuppetGroup::getGroupList( $project ) );
620 - $out .= Html::rawElement( 'div', array( 'class' => 'mw-collapsible', 'id' => 'mw-customcollapsible-' . $project ), $groupsOut );
 636+ if ( !$this->userLDAP->inRole( 'sysadmin', $projectName ) ) {
 637+ continue;
 638+ }
 639+ $actions = Array( 'sysadmin' => Array() );
 640+ $actions['sysadmin'][] = $this->createActionLink( 'openstackmanager-createpuppetgroup', array( 'action' => 'create', 'project' => $projectName ) );
 641+ $out .= $this->createProjectSection( $projectName, $actions, $this->getPuppetGroupOutput( OpenStackNovaPuppetGroup::getGroupList( $projectName ) ) );
621642 }
622643 $action = '';
623644 $showlinks = $this->userCanExecute( $this->getUser() );
624645 if ( $showlinks ) {
625646
626 - $action = Linker::link( $this->getTitle(), wfMsgHtml( 'openstackmanager-createpuppetgroup' ), array(), array( 'action' => 'create' ) );
 647+ $action = $this->createActionLink( 'openstackmanager-createpuppetgroup', array( 'action' => 'create' ) );
627648 $action = Html::rawElement( 'span', array( 'id' => 'novaaction' ), "[$action]" );
628649 }
629650 $allProjectsMsg = Html::rawElement( 'span', array( 'class' => 'mw-customtoggle-allprojects', 'id' => 'novaproject' ), wfMsgHtml( 'openstackmanager-puppetallprojects' ) );
@@ -636,7 +657,7 @@
637658 $out = '';
638659 foreach ( $puppetGroups as $puppetGroup ) {
639660 $puppetGroupProject = $puppetGroup->getProject();
640 - //$puppetGroupProject can be null
 661+ # $puppetGroupProject can be null
641662 if ( !$puppetGroupProject ) {
642663 $puppetGroupProject = '';
643664 }
@@ -646,14 +667,14 @@
647668 $puppetGroupName = "[$puppetGroupPosition] " . htmlentities( $puppetGroupName );
648669 $specialPuppetGroupTitle = Title::newFromText( 'Special:NovaPuppetGroup' );
649670 if ( $showlinks ) {
650 - $modify = Linker::link( $specialPuppetGroupTitle, wfMsgHtml( 'openstackmanager-modify' ), array(), array( 'action' => 'modify', 'puppetgroupid' => $puppetGroupId, 'puppetgroupposition' => $puppetGroupPosition, 'returnto' => 'Special:NovaPuppetGroup' ) );
651 - $delete = Linker::link( $specialPuppetGroupTitle, wfMsgHtml( 'openstackmanager-delete' ), array(), array( 'action' => 'delete', 'puppetgroupid' => $puppetGroupId, 'returnto' => 'Special:NovaPuppetGroup' ) );
 671+ $modify = $this->createActionLink( 'openstackmanager-modify', array( 'action' => 'modify', 'puppetgroupid' => $puppetGroupId, 'puppetgroupposition' => $puppetGroupPosition, 'returnto' => 'Special:NovaPuppetGroup' ) );
 672+ $delete = $this->createActionLink( 'openstackmanager-delete', array( 'action' => 'delete', 'puppetgroupid' => $puppetGroupId, 'returnto' => 'Special:NovaPuppetGroup' ) );
652673 $action = Html::rawElement( 'span', array( 'id' => 'novaaction' ), "[$modify, $delete]" );
653674 $out .= Html::rawElement( 'h3', array(), "$puppetGroupName $action" );
654675 }
655676 $action = '';
656677 if ( $showlinks ) {
657 - $action = Linker::link( $specialPuppetGroupTitle, wfMsgHtml( 'openstackmanager-addpuppetclass' ), array(), array( 'action' => 'addclass', 'puppetgroupid' => $puppetGroupId, 'project' => $puppetGroupProject, 'returnto' => 'Special:NovaPuppetGroup' ) );
 678+ $action = $this->createActionLink( 'openstackmanager-addpuppetclass', array( 'action' => 'addclass', 'puppetgroupid' => $puppetGroupId, 'project' => $puppetGroupProject, 'returnto' => 'Special:NovaPuppetGroup' ) );
658679 $action = Html::rawElement( 'span', array( 'id' => 'novaaction' ), "[$action]" );
659680 }
660681 $classesMsg = wfMsgHtml( 'openstackmanager-puppetclasses' );
@@ -661,18 +682,18 @@
662683 $puppetGroupClasses = $puppetGroup->getClasses();
663684 $puppetGroupVars = $puppetGroup->getVars();
664685 if ( $puppetGroupClasses ) {
665 - $classesOut = '';
 686+ $classes = Array();
666687 foreach ( $puppetGroupClasses as $puppetGroupClass ) {
667688 $classname = '[' . $puppetGroupClass["position"] . '] ' . htmlentities( $puppetGroupClass["name"] );
668689 if ( $showlinks ) {
669 - $modify = Linker::link( $specialPuppetGroupTitle, wfMsgHtml( 'openstackmanager-modify' ), array(), array( 'action' => 'modifyclass', 'puppetclassid' => $puppetGroupClass["id"], 'puppetclassposition' => $puppetGroupClass["position"], 'puppetgroupid' => $puppetGroupId, 'returnto' => 'Special:NovaPuppetGroup' ) );
670 - $delete = Linker::link( $specialPuppetGroupTitle, wfMsgHtml( 'openstackmanager-delete' ), array(), array( 'action' => 'deleteclass', 'puppetclassid' => $puppetGroupClass["id"], 'returnto' => 'Special:NovaPuppetGroup' ) );
 690+ $modify = $this->createActionLink( 'openstackmanager-modify', array( 'action' => 'modifyclass', 'puppetclassid' => $puppetGroupClass["id"], 'puppetclassposition' => $puppetGroupClass["position"], 'puppetgroupid' => $puppetGroupId, 'returnto' => 'Special:NovaPuppetGroup' ) );
 691+ $delete = $this->createActionLink( 'openstackmanager-delete', array( 'action' => 'deleteclass', 'puppetclassid' => $puppetGroupClass["id"], 'returnto' => 'Special:NovaPuppetGroup' ) );
671692 $classname .= Html::rawElement( 'span', array( 'id' => 'novaaction' ), " [$modify, $delete]" );
672693 }
673694
674 - $classesOut .= Html::rawElement( 'li', array(), $classname );
 695+ array_push( $classes, $classname );
675696 }
676 - $out .= Html::rawElement( 'ul', array(), $classesOut );
 697+ $out .= $this->createResourceList( $classes );
677698 }
678699 $action = '';
679700 if ( $showlinks ) {
@@ -682,17 +703,17 @@
683704 $varsMsg = wfMsgHtml( 'openstackmanager-puppetvars' );
684705 $out .= Html::rawElement( 'h4', array(), "$varsMsg $action" );
685706 if ( $puppetGroupVars ) {
686 - $varsOut = '';
 707+ $vars = Array();
687708 foreach ( $puppetGroupVars as $puppetGroupVar ) {
688709 $varname = '[' . $puppetGroupVar["position"] . '] ' . htmlentities( $puppetGroupVar["name"] );
689710 if ( $showlinks ) {
690 - $modify = Linker::link( $specialPuppetGroupTitle, wfMsgHtml( 'openstackmanager-modify' ), array(), array( 'action' => 'modifyvar', 'puppetvarid' => $puppetGroupVar["id"], 'puppetvarposition' => $puppetGroupVar["position"], 'puppetgroupid' => $puppetGroupId, 'returnto' => 'Special:NovaPuppetGroup' ) );
691 - $delete = Linker::link( $specialPuppetGroupTitle, wfMsgHtml( 'openstackmanager-delete' ), array(), array( 'action' => 'deletevar', 'puppetvarid' => $puppetGroupVar["id"], 'returnto' => 'Special:NovaPuppetGroup' ) );
 711+ $modify = $this->createActionLink( 'openstackmanager-modify', array( 'action' => 'modifyvar', 'puppetvarid' => $puppetGroupVar["id"], 'puppetvarposition' => $puppetGroupVar["position"], 'puppetgroupid' => $puppetGroupId, 'returnto' => 'Special:NovaPuppetGroup' ) );
 712+ $delete = $this->createActionLink( 'openstackmanager-delete', array( 'action' => 'deletevar', 'puppetvarid' => $puppetGroupVar["id"], 'returnto' => 'Special:NovaPuppetGroup' ) );
692713 $varname .= Html::rawElement( 'span', array( 'id' => 'novaaction' ), " [$modify, $delete]" );
693714 }
694 - $varsOut .= Html::rawElement( 'li', array(), $varname );
 715+ array_push( $vars, $varname );
695716 }
696 - $out .= Html::rawElement( 'ul', array(), $varsOut );
 717+ $out .= $this->createResourceList( $vars );
697718 }
698719 }
699720 return $out;
Index: trunk/extensions/OpenStackManager/special/SpecialNova.php
@@ -1,5 +1,12 @@
22 <?php
33
 4+/**
 5+ * Special page for nova
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
411 abstract class SpecialNova extends SpecialPage {
512
613 /**
@@ -75,4 +82,163 @@
7683 }
7784 }
7885
 86+ function getProjectFilter() {
 87+ global $wgRequest;
 88+
 89+ if ( $wgRequest->getCookie( 'projectfilter' ) ) {
 90+ return explode( ',', urldecode( $wgRequest->getCookie( 'projectfilter' ) ) );
 91+ }
 92+ return array();
 93+ }
 94+
 95+ function showProjectFilter( $projects, $showbydefault=false ) {
 96+ global $wgRequest;
 97+
 98+ if ( $this->getRequest()->wasPosted() && $this->getRequest()->getVal( 'action' ) != 'setprojectfilter' ) {
 99+ return null;
 100+ }
 101+ $showmsg = $this->getRequest()->getText( 'showmsg' );
 102+ if ( $showmsg == "setfilter" ) {
 103+ $this->getOutput()->addWikiMsg( 'openstackmanager-setprojects' );
 104+ }
 105+ $currentProjects = $this->getProjectFilter();
 106+ $project_keys = array();
 107+ $defaults = array();
 108+ foreach ( $projects as $project ) {
 109+ $projectName = $project->getProjectName();
 110+ $project_keys["$projectName"] = $projectName;
 111+ if ( in_array( $projectName, $currentProjects ) ) {
 112+ $defaults["$projectName"] = $projectName;
 113+ }
 114+ }
 115+ $projectFilter = array();
 116+ $projectFilter['projects'] = array(
 117+ 'type' => 'multiselect',
 118+ 'label-message' => 'openstackmanager-projects',
 119+ 'section' => 'projectfilter',
 120+ 'options' => $project_keys,
 121+ 'default' => $defaults,
 122+ 'name' => 'projects',
 123+ );
 124+ $projectFilter['action'] = array(
 125+ 'type' => 'hidden',
 126+ 'default' => 'setprojectfilter',
 127+ 'name' => 'action',
 128+ );
 129+ $projectFilterForm = new HTMLForm( $projectFilter, 'openstackmanager-novaprojectfilter' );
 130+ $projectFilterForm->setTitle( $this->getTitle() );
 131+ if ( $showbydefault ) {
 132+ $classes = "mw-collapsible";
 133+ } else {
 134+ $classes = "mw-collapsible mw-collapsed";
 135+ }
 136+ $projectFilterForm->addHeaderText( '<div class="' . $classes .'" data-expandtext="Show project filter" data-collapsetext="Hide project filter">' );
 137+ $projectFilterForm->addFooterText( '</div>' );
 138+ $projectFilterForm->setSubmitID( 'novaproject-form-setprojectfiltersubmit' );
 139+ $projectFilterForm->setSubmitCallback( array( $this, 'trySetProjectFilter' ) );
 140+ $projectFilterForm->show();
 141+ }
 142+
 143+ function getResourcesGroupedByProject( $resources ) {
 144+ $groupResources = Array();
 145+ foreach ( $resources as $resource ) {
 146+ $project = $resource->getProject();
 147+ if ( array_key_exists( $project, $groupResources ) ) {
 148+ $groupResources["$project"][] = $resource;
 149+ } else {
 150+ $groupResources["$project"] = Array( $resource );
 151+ }
 152+ }
 153+ return $groupResources;
 154+ }
 155+
 156+ function getResourceByProject( $resources, $projectName ) {
 157+ if ( in_array( $projectName, array_keys( $resources ) ) ) {
 158+ return $resources["$projectName"];
 159+ } else {
 160+ return Array();
 161+ }
 162+ }
 163+
 164+ function createResourceLink( $resource ) {
 165+ $resource = htmlentities( $resource );
 166+ $title = Title::newFromText( $resource, NS_NOVA_RESOURCE );
 167+ return Linker::link( $title, $resource );
 168+ }
 169+
 170+ function createActionLink( $msg, $params, $title = Null ) {
 171+ if ( !$title ) {
 172+ $title = $this->getTitle();
 173+ }
 174+ return Linker::link( $title, wfMsgHtml( $msg ), array(), $params );
 175+ }
 176+
 177+ function createResourceList( $resources ) {
 178+ $resourceList = '';
 179+ foreach ( $resources as $resource ) {
 180+ $resourceList .= Html::rawElement( 'li', array(), $resource );
 181+ }
 182+ return Html::rawElement( 'ul', array(), $resourceList );
 183+ }
 184+
 185+ function pushResourceColumn( &$row, $value ) {
 186+ array_push( $row, Html::element( 'td', array(), $value ) );
 187+ }
 188+
 189+ function pushRawResourceColumn( &$row, $value ) {
 190+ array_push( $row, Html::rawElement( 'td', array(), $value ) );
 191+ }
 192+
 193+ function createResourceTable( $headers, $rows ) {
 194+ $table = '';
 195+ foreach ( $headers as $header ) {
 196+ $table .= Html::element( 'th', array(), wfMsg( $header ) );
 197+ }
 198+ foreach ( $rows as $row ) {
 199+ $rowOut = '';
 200+ foreach ( $row as $column ) {
 201+ $rowOut .= $column;
 202+ }
 203+ $table .= Html::rawElement( 'tr', array(), $rowOut );
 204+ }
 205+ return Html::rawElement( 'table', array( 'class' => 'wikitable sortable collapsible' ), $table );
 206+ }
 207+
 208+ function createProjectSection( $projectName, $actionsByRole, $data ) {
 209+ $actions = Array();
 210+ foreach ( $actionsByRole as $role => $roleActions ) {
 211+ foreach ( $roleActions as $action ) {
 212+ if ( $this->userLDAP->inRole( $role, $projectName ) ) {
 213+ array_push( $actions, $action );
 214+ }
 215+ }
 216+ }
 217+ if ( $actions ) {
 218+ $actions = implode( ',', $actions );
 219+ $actionOut = Html::rawElement( 'span', array( 'id' => 'novaaction' ), "[$actions]" );
 220+ } else {
 221+ $actionOut = '';
 222+ }
 223+ $projectNameOut = Html::rawElement( 'span', array( 'class' => 'mw-customtoggle-' . $projectName, 'id' => 'novaproject' ), $projectName );
 224+ $out = Html::rawElement( 'h2', array(), "$projectNameOut $actionOut" );
 225+ $out .= Html::rawElement( 'div', array( 'class' => 'mw-collapsible', 'id' => 'mw-customcollapsible-' . $projectName ), $data );
 226+
 227+ return $out;
 228+ }
 229+
 230+ function trySetProjectFilter( $formData, $entryPoint = 'internal' ) {
 231+ global $wgRequest;
 232+
 233+ if ( !$formData['projects'] ) {
 234+ $wgRequest->response()->setCookie( 'projectfilter', '', time() - 86400 );
 235+ $this->getOutput()->redirect( $this->getTitle()->getFullUrl() );
 236+ } else {
 237+ $projects = implode( ',', $formData['projects'] );
 238+ $wgRequest->response()->setCookie( 'projectfilter', $projects );
 239+ $this->getOutput()->redirect( $this->getTitle()->getFullUrl( 'showmsg=setfilter' ) );
 240+ }
 241+
 242+ return true;
 243+ }
 244+
79245 }
Index: trunk/extensions/OpenStackManager/special/SpecialNovaRole.php
@@ -1,4 +1,12 @@
22 <?php
 3+
 4+/**
 5+ * todo comment me
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
311 class SpecialNovaRole extends SpecialNova {
412
513 var $adminNova;
@@ -198,37 +206,24 @@
199207 $this->setHeaders();
200208 $this->getOutput()->setPagetitle( wfMsg( 'openstackmanager-rolelist' ) );
201209
202 - $out = '';
203 -
204 - $rolesOut = Html::element( 'th', array(), wfMsg( 'openstackmanager-rolename' ) );
205 - $rolesOut .= Html::element( 'th', array(), wfMsg( 'openstackmanager-members' ) );
206 - $rolesOut .= Html::element( 'th', array(), wfMsg( 'openstackmanager-actions' ) );
 210+ $headers = Array( 'openstackmanager-rolename', 'openstackmanager-members', 'openstackmanager-actions' );
207211 $roles = OpenStackNovaRole::getAllGlobalRoles();
208 - if ( ! $roles ) {
209 - $rolesOut = '';
210 - }
 212+ $roleRows = Array();
211213 foreach ( $roles as $role ) {
 214+ $roleRow = Array();
212215 $roleName = $role->getRoleName();
213 - $roleOut = Html::element( 'td', array(), $roleName );
214 - $roleMembers = $role->getMembers();
215 - $memberOut = '';
216 - foreach ( $roleMembers as $roleMember ) {
217 - $memberOut .= Html::element( 'li', array(), $roleMember );
218 - }
219 - if ( $memberOut ) {
220 - $memberOut = Html::rawElement( 'ul', array(), $memberOut );
221 - }
222 - $roleOut .= Html::rawElement( 'td', array(), $memberOut );
223 - $link = Linker::link( $this->getTitle(), wfMsgHtml( 'openstackmanager-addrolemember' ), array(), array( 'action' => 'addmember', 'rolename' => $roleName, 'returnto' => 'Special:NovaRole' ) );
224 - $actions = Html::rawElement( 'li', array(), $link );
225 - $link = Linker::link( $this->getTitle(), wfMsgHtml( 'openstackmanager-removerolemember' ), array(), array( 'action' => 'deletemember', 'rolename' => $roleName, 'returnto' => 'Special:NovaRole' ) );
226 - $actions .= Html::rawElement( 'li', array(), $link );
227 - $actions = Html::rawElement( 'ul', array(), $actions );
228 - $roleOut .= Html::rawElement( 'td', array(), $actions );
229 - $rolesOut .= Html::rawElement( 'tr', array(), $roleOut );
 216+ $this->pushResourceColumn( $roleRow, $roleName );
 217+ $this->pushRawResourceColumn( $roleRow, $this->createResourceList( $role->getMembers() ) );
 218+ $actions = Array();
 219+ array_push( $actions, $this->createActionLink( 'openstackmanager-addrolemember', array( 'action' => 'addmember', 'rolename' => $roleName, 'returnto' => 'Special:NovaRole' ) ) );
 220+ array_push( $actions, $this->createActionLink( 'openstackmanager-removerolemember', array( 'action' => 'deletemember', 'rolename' => $roleName, 'returnto' => 'Special:NovaRole' ) ) );
 221+ $this->pushRawResourceColumn( $roleRow, $this->createResourceList( $actions ) );
 222+ array_push( $roleRows, $roleRow );
230223 }
231 - if ( $rolesOut ) {
232 - $out .= Html::rawElement( 'table', array( 'class' => 'wikitable sortable collapsible' ), $rolesOut );
 224+ if ( $roleRows ) {
 225+ $out = $this->createResourceTable( $headers, $roleRows );
 226+ } else {
 227+ $out = '';
233228 }
234229
235230 $this->getOutput()->addHTML( $out );
Index: trunk/extensions/OpenStackManager/special/SpecialNovaSudoer.php
@@ -1,4 +1,12 @@
22 <?php
 3+
 4+/**
 5+ * todo comment me
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
311 class SpecialNovaSudoer extends SpecialNova {
412
513 var $userLDAP;
@@ -18,6 +26,10 @@
1927 $this->noCredentials();
2028 return;
2129 }
 30+ if ( !$this->userLDAP->inGlobalRole( 'cloudadmin' ) ) {
 31+ $this->notInRole( 'cloudadmin' );
 32+ return;
 33+ }
2234
2335 $action = $this->getRequest()->getVal( 'action' );
2436 if ( $action == "delete" ) {
@@ -192,59 +204,28 @@
193205 $sudoerForm->setSubmitCallback( array( $this, 'tryCreateSubmit' ) );
194206 $sudoerForm->show();
195207
196 - $out = '';
197 - $sudoersOut = Html::element( 'th', array(), wfMsg( 'openstackmanager-sudoername' ) );
198 - $sudoersOut .= Html::element( 'th', array(), wfMsg( 'openstackmanager-sudoerusers' ) );
199 - $sudoersOut .= Html::element( 'th', array(), wfMsg( 'openstackmanager-sudoerhosts' ) );
200 - $sudoersOut .= Html::element( 'th', array(), wfMsg( 'openstackmanager-sudoercommands' ) );
201 - $sudoersOut .= Html::element( 'th', array(), wfMsg( 'openstackmanager-sudoeroptions' ) );
202 - $sudoersOut .= Html::element( 'th', array(), wfMsg( 'openstackmanager-actions' ) );
 208+ $headers = Array( 'openstackmanager-sudoername', 'openstackmanager-sudoerusers', 'openstackmanager-sudoerhosts',
 209+ 'openstackmanager-sudoercommands', 'openstackmanager-sudoeroptions', 'openstackmanager-actions' );
203210 $sudoers = OpenStackNovaSudoer::getAllSudoers();
 211+ $sudoerRows = Array();
204212 foreach ( $sudoers as $sudoer ) {
 213+ $sudoerRow = Array();
205214 $sudoerName = $sudoer->getSudoerName();
206 - $sudoerOut = Html::element( 'td', array(), $sudoerName );
207 - $users = $sudoer->getSudoerUsers();
208 - $sudoerUsers = '';
209 - foreach ( $users as $user ) {
210 - $sudoerUsers .= Html::element( 'li', array(), $user );
211 - }
212 - $sudoerUsers = Html::rawElement( 'ul', array(), $sudoerUsers );
213 - $sudoerOut .= Html::rawElement( 'td', array(), $sudoerUsers );
214 - $hosts = $sudoer->getSudoerHosts();
215 - $sudoerHosts = '';
216 - foreach ( $hosts as $host ) {
217 - $sudoerHosts .= Html::element( 'li', array(), $host );
218 - }
219 - $sudoerHosts = Html::rawElement( 'ul', array(), $sudoerHosts );
220 - $sudoerOut .= Html::rawElement( 'td', array(), $sudoerHosts );
221 - $commands = $sudoer->getSudoerCommands();
222 - $sudoerCommands = '';
223 - foreach ( $commands as $command ) {
224 - $sudoerCommands .= Html::element( 'li', array(), $command );
225 - }
226 - $sudoerCommands = Html::rawElement( 'ul', array(), $sudoerCommands );
227 - $sudoerOut .= Html::rawElement( 'td', array(), $sudoerCommands );
228 - $options = $sudoer->getSudoerOptions();
229 - $sudoerOptions = '';
230 - foreach ( $options as $option ) {
231 - $sudoerOptions .= Html::element( 'li', array(), $option );
232 - }
233 - $sudoerOptions = Html::rawElement( 'ul', array(), $sudoerOptions );
234 - $sudoerOut .= Html::rawElement( 'td', array(), $sudoerOptions );
235 - $msg = wfMsgHtml( 'openstackmanager-modify' );
236 - $link = Linker::link( $this->getTitle(), $msg, array(),
237 - array( 'action' => 'modify', 'sudoername' => $sudoerName ) );
238 - $actions = Html::rawElement( 'li', array(), $link );
239 - $msg = wfMsgHtml( 'openstackmanager-delete' );
240 - $link = Linker::link( $this->getTitle(), $msg, array(),
241 - array( 'action' => 'delete', 'sudoername' => $sudoerName ) );
242 - $actions .= Html::rawElement( 'li', array(), $link );
243 - $actions = Html::rawElement( 'ul', array(), $actions );
244 - $sudoerOut .= Html::rawElement( 'td', array(), $actions );
245 - $sudoersOut .= Html::rawElement( 'tr', array(), $sudoerOut );
 215+ $this->pushResourceColumn( $sudoerRow, $sudoerName );
 216+ $this->pushRawResourceColumn( $sudoerRow, $this->createResourceList( $sudoer->getSudoerUsers() ) );
 217+ $this->pushRawResourceColumn( $sudoerRow, $this->createResourceList( $sudoer->getSudoerHosts() ) );
 218+ $this->pushRawResourceColumn( $sudoerRow, $this->createResourceList( $sudoer->getSudoerCommands() ) );
 219+ $this->pushRawResourceColumn( $sudoerRow, $this->createResourceList( $sudoer->getSudoerOptions() ) );
 220+ $actions = Array();
 221+ array_push( $actions, $this->createActionLink( 'openstackmanager-modify', array( 'action' => 'modify', 'sudoername' => $sudoerName ) ) );
 222+ array_push( $actions, $this->createActionLink( 'openstackmanager-delete', array( 'action' => 'delete', 'sudoername' => $sudoerName ) ) );
 223+ $this->pushRawResourceColumn( $sudoerRow, $this->createResourceList( $actions ) );
 224+ array_push( $sudoerRows, $sudoerRow );
246225 }
247 - if ( $sudoers ) {
248 - $out .= Html::rawElement( 'table', array( 'class' => 'wikitable sortable collapsible' ), $sudoersOut );
 226+ if ( $sudoerRows ) {
 227+ $out = $this->createResourceTable( $headers, $sudoerRows );
 228+ } else {
 229+ $out = '';
249230 }
250231
251232 $this->getOutput()->addHTML( $out );
Index: trunk/extensions/OpenStackManager/OpenStackNovaLdapConnection.php
@@ -1,5 +1,12 @@
22 <?php
33
 4+/**
 5+ * class for nova ldap
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
411 class OpenStackNovaLdapConnection {
512
613 /**
Index: trunk/extensions/OpenStackManager/OpenStackNovaSudoer.php
@@ -1,5 +1,12 @@
22 <?php
33
 4+/**
 5+ * class for nova sudoers
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
411 class OpenStackNovaSudoer {
512
613 var $sudoername;
Index: trunk/extensions/OpenStackManager/OpenStackNovaRole.php
@@ -1,5 +1,12 @@
22 <?php
33
 4+/**
 5+ * todo comment me
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
411 class OpenStackNovaRole {
512
613 var $rolename;
@@ -10,7 +17,7 @@
1118
1219 /**
1320 * @param $rolename
14 - * @param null $project
 21+ * @param null $project, optional
1522 */
1623 function __construct( $rolename, $project=null ) {
1724 $this->rolename = $rolename;
@@ -117,6 +124,8 @@
118125 }
119126 $success = LdapAuthenticationPlugin::ldap_modify( $wgAuth->ldapconn, $this->roleDN, $values );
120127 if ( $success ) {
 128+ $key = $this->getMemcKey( $user );
 129+ $wgMemc->delete( $key );
121130 $this->fetchRoleInfo();
122131 $wgAuth->printDebug( "Successfully removed $user->userDN from $this->roleDN", NONSENSITIVE );
123132 return true;
@@ -135,6 +144,7 @@
136145 */
137146 function addMember( $username ) {
138147 global $wgAuth;
 148+ global $wgMemc;
139149
140150 $members = array();
141151 if ( isset( $this->roleInfo[0]['member'] ) ) {
@@ -153,6 +163,8 @@
154164 if ( $success ) {
155165 $this->fetchRoleInfo();
156166 $wgAuth->printDebug( "Successfully added $user->userDN to $this->roleDN", NONSENSITIVE );
 167+ $key = $this->getMemcKey( $user );
 168+ $wgMemc->delete( $key );
157169 return true;
158170 } else {
159171 $wgAuth->printDebug( "Failed to add $user->userDN to $this->roleDN", NONSENSITIVE );
@@ -160,6 +172,17 @@
161173 }
162174 }
163175
 176+ function getMemcKey( $user ) {
 177+ if ( $this->global ) {
 178+ $role = $this->getRoleName();
 179+ $key = wfMemcKey( 'openstackmanager', "globalrole-$role", $user->userDN );
 180+ } else {
 181+ $projectname = $this->project->getProjectName();
 182+ $role = $this->getRoleName();
 183+ $key = wfMemcKey( 'openstackmanager', "projectrole-$projectname-$role", $user->userDN );
 184+ }
 185+ }
 186+
164187 /**
165188 * @static
166189 * @param $rolename
Index: trunk/extensions/OpenStackManager/OpenStackManager.i18n.php
@@ -190,6 +190,10 @@
191191 'openstackmanager-removedfrom' => 'Successfully removed $1 from $2.',
192192 'openstackmanager-failedtoremove' => 'Failed to remove $1 from $2.',
193193 'openstackmanager-novaproject-project' => 'Add project',
 194+ 'openstackmanager-novaprojectfilter-projectfilter' => 'Project filter',
 195+ 'openstackmanager-projects' => 'Projects',
 196+ 'openstackmanager-setprojects' => 'Successfully set the project filter.',
 197+ 'openstackmanager-setprojectfilter' => 'Please select projects to display using the project filter.',
194198
195199 'openstackmanager-roles' => 'Roles',
196200 'openstackmanager-rolename' => 'Role name',
@@ -419,6 +423,10 @@
420424 'openstackmanager-sudoerusers' => '{{Identical|User}}',
421425 'openstackmanager-sudoeroptions' => '{{Identical|Options}}',
422426 'right-manageproject' => '{{doc-right|manageproject}}',
 427+ 'openstackmanager-novaprojectfilter-projectfilter' => 'It is a filter than can be used to selectively show a set of projects in all management interfaces.',
 428+ 'openstackmanager-projects' => 'A set of projects',
 429+ 'openstackmanager-setprojects' => 'A message informing the user that a project filter has been successfully assigned',
 430+ 'openstackmanager-setprojectfilter' => ' A message telling the user that a project filter should be applied to see any resources.',
423431 );
424432
425433 /** Afrikaans (Afrikaans)
Index: trunk/extensions/OpenStackManager/OpenStackNovaInstance.php
@@ -1,5 +1,12 @@
22 <?php
33
 4+/**
 5+ * class for NovaInstance
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
411 # TODO: Make this an abstract class, and make the EC2 API a subclass
512 class OpenStackNovaInstance {
613
@@ -12,7 +19,7 @@
1320
1421 /**
1522 * @param $apiInstanceResponse
16 - * @param bool $loadhost
 23+ * @param bool $loadhost, optional
1724 */
1825 function __construct( $apiInstanceResponse, $loadhost = false ) {
1926 $this->instance = $apiInstanceResponse;
@@ -131,7 +138,7 @@
132139 *
133140 * @return string
134141 */
135 - function getOwner() {
 142+ function getProject() {
136143 return (string)$this->instance->ownerId;
137144 }
138145
@@ -254,7 +261,7 @@
255262 $instanceType->getNumberOfCPUs(),
256263 $instanceType->getStorageSize(),
257264 $this->getImageId(),
258 - $this->getOwner(),
 265+ $this->getProject(),
259266 $this->getAvailabilityZone(),
260267 $this->getRegion(),
261268 implode( ',', $this->getSecurityGroups() ),
Index: trunk/extensions/OpenStackManager/OpenStackNovaKeypair.php
@@ -1,5 +1,12 @@
22 <?php
33
 4+/**
 5+ * todo comment me
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
411 # TODO: Make this an abstract class, and make the EC2 API a subclass
512 class OpenStackNovaKeyPair {
613
Index: trunk/extensions/OpenStackManager/OpenStackNovaInstanceType.php
@@ -1,5 +1,12 @@
22 <?php
33
 4+/**
 5+ * todo comment me
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
411 # TODO: Make this an abstract class, and make the EC2 API a subclass
512 class OpenStackNovaInstanceType {
613
Index: trunk/extensions/OpenStackManager/OpenStackNovaProject.php
@@ -1,5 +1,12 @@
22 <?php
33
 4+/**
 5+ * todo comment me
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
411 class OpenStackNovaProject {
512
613 var $projectname;
@@ -7,6 +14,7 @@
815 var $projectInfo;
916 var $roles;
1017
 18+ // list of roles
1119 static $rolenames = array( 'sysadmin', 'netadmin' );
1220
1321 /**
@@ -179,6 +187,17 @@
180188 }
181189 }
182190
 191+ static function getProjectsByName( $projectnames ) {
 192+ $projects = array();
 193+ foreach ( $projectnames as $projectname ) {
 194+ $project = new OpenStackNovaProject( $projectname );
 195+ if ( $project->projectInfo ) {
 196+ array_push( $projects, $project );
 197+ }
 198+ }
 199+ return $projects;
 200+ }
 201+
183202 /**
184203 * Return all existing projects. Returns an empty array if no projects exist.
185204 *
@@ -346,7 +365,7 @@
347366 OpenStackNovaArticle::editArticle( $this->getProjectName(), $text );
348367 if ( $wgOpenStackManagerCreateProjectSALPages ) {
349368 $pagename = $this->getProjectName() . "/SAL";
350 - $id = Title::newFromText( $pagename, NS_NOVA_RESOURCE )->getArticleID();
 369+ $id = Title::newFromText( $pagename, NS_NOVA_RESOURCE )->getArticleId();
351370 $article = Article::newFromId( $id );
352371 $content = '';
353372 if ( $article ) {
Index: trunk/extensions/OpenStackManager/OpenStackNovaVolume.php
@@ -1,5 +1,12 @@
22 <?php
33
 4+/**
 5+ * todo comment me
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
411 # TODO: Make this an abstract class, and make the EC2 API a subclass
512 class OpenStackNovaVolume {
613
@@ -129,7 +136,7 @@
130137 *
131138 * @return string
132139 */
133 - function getOwner() {
 140+ function getProject() {
134141 $status = (string)$this->volume->status;
135142 $status = explode( ' ', $status );
136143
Index: trunk/extensions/OpenStackManager/OpenStackNovaDomain.php
@@ -1,11 +1,18 @@
22 <?php
33
 4+/**
 5+ * Class for Nova Domain
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
411 class OpenStackNovaDomain {
512
613 var $domainname;
714 var $domainDN;
815 var $domainInfo;
9 - var $fqdn;
 16+ var $fqdn; // fq domain name
1017
1118 /**
1219 * @param $domainname
Index: trunk/extensions/OpenStackManager/OpenStackNovaHostJob.php
@@ -1,4 +1,12 @@
22 <?php
 3+
 4+/**
 5+ * todo comment me
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
311 class OpenStackNovaHostJob extends Job {
412
513 /**
Index: trunk/extensions/OpenStackManager/OpenStackNovaHost.php
@@ -1,5 +1,12 @@
22 <?php
33
 4+/**
 5+ * todo comment me
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
411 class OpenStackNovaHost {
512
613 /**
@@ -572,7 +579,7 @@
573580
574581 $hostname = $instance->getInstanceName();
575582 $instanceid = $instance->getInstanceId();
576 - $project = $instance->getOwner();
 583+ $project = $instance->getProject();
577584 $ip = $instance->getInstancePrivateIP();
578585 $domainname = $domain->getFullyQualifiedDomainName();
579586 $host = OpenStackNovaHost::getHostByName( $hostname, $domain );
Index: trunk/extensions/OpenStackManager/OpenStackNovaUser.php
@@ -1,5 +1,12 @@
22 <?php
33
 4+/**
 5+ * todo comment me
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
411 class OpenStackNovaUser {
512
613 var $username;
@@ -20,7 +27,17 @@
2128 */
2229 function fetchUserInfo() {
2330 global $wgAuth, $wgUser;
 31+ global $wgMemc;
2432
 33+ $key = wfMemcKey( 'ldapauthentication', "userinfo", $this->userDN );
 34+ $cacheLength = 3600;
 35+ $memcUserInfo = $wgMemc->get( $key );
 36+ if ( is_array( $memcUserInfo ) ) {
 37+ $this->userInfo = $memcUserInfo;
 38+ $this->userDN = $this->userInfo[0]["dn"];
 39+ $wgAuth->printDebug( "Fetched userdn from memcache: $this->userDN ", NONSENSITIVE );
 40+ return;
 41+ }
2542 if ( $this->username ) {
2643 $this->userDN = $wgAuth->getUserDN( strtolower( $this->username ) );
2744 $wgAuth->printDebug( "Fetching userdn using username: $this->userDN ", NONSENSITIVE );
@@ -29,6 +46,7 @@
3047 $wgAuth->printDebug( "Fetching userdn using wiki name: " . $wgUser->getName(), NONSENSITIVE );
3148 }
3249 $this->userInfo = $wgAuth->userInfo;
 50+ $wgMemc->set( $key, $this->userInfo, $cacheLength );
3351 }
3452
3553 /**
@@ -139,24 +157,30 @@
140158 function inProject( $project ) {
141159 global $wgAuth;
142160 global $wgOpenStackManagerLDAPProjectBaseDN;
 161+ global $wgMemc;
143162
 163+ $key = wfMemcKey( 'openstackmanager', "project-$projectname", $this->userDN );
 164+ $cacheLength = 3600;
 165+ $inProject = $wgMemc->get( $key );
 166+ if ( is_int( $inProject ) ) {
 167+ return (bool)$inRole;
 168+ }
 169+
144170 $filter = "(&(cn=$project)(member=$this->userDN)(owner=*))";
145171 $result = LdapAuthenticationPlugin::ldap_search( $wgAuth->ldapconn, $wgOpenStackManagerLDAPProjectBaseDN, $filter );
 172+ $ret = false;
146173 if ( $result ) {
147174 $entries = LdapAuthenticationPlugin::ldap_get_entries( $wgAuth->ldapconn, $result );
148175 if ( $entries ) {
149176 if ( $entries['count'] == "0" ) {
150177 $wgAuth->printDebug( "Couldn't find the user in project: $project", NONSENSITIVE );
151 - return false;
152178 } else {
153 - return true;
 179+ $ret = true;
154180 }
155 - } else {
156 - return false;
157181 }
158 - } else {
159 - return false;
160182 }
 183+ $wgMemc->set( $key, (int)$ret, $cacheLength );
 184+ return $ret;
161185 }
162186
163187 /**
@@ -167,23 +191,39 @@
168192 function inRole( $role, $projectname='', $strict=false ) {
169193 global $wgAuth;
170194 global $wgOpenStackManagerLDAPRolesIntersect;
 195+ global $wgMemc;
171196
 197+ if ( $projectname ) {
 198+ $key = wfMemcKey( 'openstackmanager', "projectrole-$projectname-$role", $this->userDN );
 199+ } else {
 200+ $key = wfMemcKey( 'openstackmanager', "globalrole-$role", $this->userDN );
 201+ }
 202+ $cacheLength = 3600;
 203+ $inRole = $wgMemc->get( $key );
 204+ if ( is_int( $inRole ) ) {
 205+ return (bool)$inRole;
 206+ }
 207+
172208 if ( $this->inGlobalRole( $role ) ) {
173209 # If roles intersect, or we wish to explicitly check
174210 # project role, we can't return here.
175211 if ( !$wgOpenStackManagerLDAPRolesIntersect && !$strict ) {
 212+ $wgMemc->set( $key, 1, $cacheLength );
176213 return true;
177214 }
178215 } else {
179216 if ( $wgOpenStackManagerLDAPRolesIntersect ) {
 217+ $wgMemc->set( $key, 0, $cacheLength );
180218 return false;
181219 }
182220 }
183221
 222+ $ret = false;
184223 if ( $projectname ) {
185224 # Check project specific role
186225 $project = OpenStackNovaProject::getProjectByName( $projectname );
187226 if ( ! $project ) {
 227+ $wgMemc->set( $key, 0, $cacheLength );
188228 return false;
189229 }
190230 $filter = "(&(cn=$role)(member=$this->userDN))";
@@ -193,18 +233,14 @@
194234 if ( $entries ) {
195235 if ( $entries['count'] == "0" ) {
196236 $wgAuth->printDebug( "Couldn't find the user in role: $role", NONSENSITIVE );
197 - return false;
198237 } else {
199 - return true;
 238+ $ret = true;
200239 }
201 - } else {
202 - return false;
203240 }
204 - } else {
205 - return false;
206241 }
207242 }
208 - return false;
 243+ $wgMemc->set( $key, (int)$ret, $cacheLength );
 244+ return $ret;
209245 }
210246
211247 /**
@@ -225,11 +261,11 @@
226262 if ( $wgOpenStackManagerLDAPGlobalRoles["$role"] ) {
227263 # Check global role
228264 $roledn = $wgOpenStackManagerLDAPGlobalRoles["$role"];
229 - $filter = "(objectclass=*)";
230 - $result = LdapAuthenticationPlugin::ldap_read( $wgAuth->ldapconn, $roledn, $filter );
 265+ $filter = "(member=$this->userDN)";
 266+ $result = LdapAuthenticationPlugin::ldap_search( $wgAuth->ldapconn, $roledn, $filter );
231267 if ( $result ) {
232268 $entries = LdapAuthenticationPlugin::ldap_get_entries( $wgAuth->ldapconn, $result );
233 - return ( in_array( $this->userDN, $entries[0]['member'] ) );
 269+ return ( (int)$entries['count'] > 0 );
234270 }
235271 }
236272 return false;
@@ -241,6 +277,7 @@
242278 */
243279 function importKeypair( $key ) {
244280 global $wgAuth;
 281+ global $wgMemc;
245282
246283 $keypairs = array();
247284 if ( isset( $this->userInfo[0]['sshpublickey'] ) ) {
@@ -253,6 +290,9 @@
254291 $success = LdapAuthenticationPlugin::ldap_modify( $wgAuth->ldapconn, $this->userDN, $values );
255292 if ( $success ) {
256293 $wgAuth->printDebug( "Successfully imported the user's sshpublickey", NONSENSITIVE );
 294+ $key = wfMemcKey( 'ldapauthentication', "userinfo", $this->userDN );
 295+ $this->printDebug( "Deleting memcache key: $key.", NONSENSITIVE );
 296+ $wgMemc->delete( $key );
257297 $this->fetchUserInfo();
258298 return true;
259299 } else {
@@ -267,6 +307,7 @@
268308 */
269309 function deleteKeypair( $key ) {
270310 global $wgAuth;
 311+ global $wgMemc;
271312
272313 if ( isset( $this->userInfo[0]['sshpublickey'] ) ) {
273314 $keypairs = $this->userInfo[0]['sshpublickey'];
@@ -285,6 +326,9 @@
286327 $success = LdapAuthenticationPlugin::ldap_modify( $wgAuth->ldapconn, $this->userDN, $values );
287328 if ( $success ) {
288329 $wgAuth->printDebug( "Successfully deleted the user's sshpublickey", NONSENSITIVE );
 330+ $key = wfMemcKey( 'ldapauthentication', "userinfo", $this->userDN );
 331+ $this->printDebug( "Deleting memcache key: $key.", NONSENSITIVE );
 332+ $wgMemc->delete( $key );
289333 $this->fetchUserInfo();
290334 return true;
291335 } else {
Index: trunk/extensions/OpenStackManager/OpenStackNovaImage.php
@@ -1,5 +1,12 @@
22 <?php
33
 4+/**
 5+ * todo comment me
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
411 # TODO: Make this an abstract class, and make the EC2 API a subclass
512 class OpenStackNovaImage {
613
Index: trunk/extensions/OpenStackManager/OpenStackNovaController.php
@@ -1,5 +1,12 @@
22 <?php
33
 4+/**
 5+ * todo comment me
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
411 # TODO: Make this an abstract class, and make the EC2 API a subclass
512 class OpenStackNovaController {
613
@@ -71,30 +78,40 @@
7279 * @return null|OpenStackNovaInstance
7380 */
7481 function getInstance( $instanceId ) {
75 - $this->getInstances();
76 - if ( isset( $this->instances["$instanceId"] ) ) {
77 - return $this->instances["$instanceId"];
 82+ $instances = $this->getInstances( $instanceId );
 83+ if ( isset( $instances["$instanceId"] ) ) {
 84+ return $instances["$instanceId"];
7885 } else {
7986 return null;
8087 }
8188 }
8289
8390 /**
 91+ * @param $instanceId string
 92+ * @param $project string|array
8493 * @return array
8594 */
86 - function getInstances() {
 95+ function getInstances( $instanceId = null, $project = array() ) {
8796 $this->instances = array();
88 - $response = $this->novaConnection->describe_instances();
 97+ $opt = array();
 98+ if ( $instanceId ) {
 99+ $opt['InstanceId'] = $instanceId;
 100+ }
 101+ if ( $project ) {
 102+ $opt = array( 'Filter' => array( array( 'Name' => 'project_id', 'Value' => $project ) ) );
 103+ }
 104+ $response = $this->novaConnection->describe_instances( $opt );
89105 $instances = $response->body->reservationSet->item;
90106 foreach ( $instances as $instance ) {
91107 $instance = new OpenStackNovaInstance( $instance, true );
92 - $instanceId = $instance->getInstanceId();
93 - $this->instances["$instanceId"] = $instance;
 108+ $id = $instance->getInstanceId();
 109+ $this->instances["$id"] = $instance;
94110 }
95111 return $this->instances;
96112 }
97113
98114 /**
 115+ * @param $instanceType
99116 * @return OpenStackNovaInstanceType
100117 */
101118 function getInstanceType( $instanceType ) {
@@ -176,6 +193,7 @@
177194 }
178195
179196 /**
 197+ * @param $project
180198 * @param $groupname
181199 * @return OpenStackNovaSecurityGroup
182200 */
@@ -197,7 +215,7 @@
198216 $securityGroups = $securityGroups->body->securityGroupInfo->item;
199217 foreach ( $securityGroups as $securityGroup ) {
200218 $securityGroup = new OpenStackNovaSecurityGroup( $securityGroup );
201 - $project = $securityGroup->getOwner();
 219+ $project = $securityGroup->getProject();
202220 $groupname = $securityGroup->getGroupName();
203221 $this->securityGroups["$project-$groupname"] = $securityGroup;
204222 }
@@ -381,7 +399,7 @@
382400 * @return
383401 */
384402 function deleteSecurityGroup( $groupname ) {
385 - $response = $this->novaConnection->delete_security_group( $groupname );
 403+ $response = $this->novaConnection->delete_security_group( Array( "GroupName" => $groupname ) );
386404
387405 return $response->isOK();
388406 }
@@ -504,6 +522,8 @@
505523 }
506524
507525 /**
 526+ * Release ip address
 527+ *
508528 * @param $ip
509529 * @return
510530 */
@@ -514,6 +534,8 @@
515535 }
516536
517537 /**
 538+ * Attach new ip address to instance
 539+ *
518540 * @param $instanceid
519541 * @param $ip
520542 * @return null|OpenStackNovaAddress
@@ -530,6 +552,8 @@
531553 }
532554
533555 /**
 556+ * Disassociate address from an instance
 557+ *
534558 * @param $ip
535559 * @return
536560 */
Index: trunk/extensions/OpenStackManager/OpenStackNovaArticle.php
@@ -1,5 +1,12 @@
22 <?php
33
 4+/**
 5+ * todo comment me
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
411 class OpenStackNovaArticle {
512
613 public static function canCreatePages() {
Index: trunk/extensions/OpenStackManager/OpenStackNovaSecurityGroup.php
@@ -1,5 +1,12 @@
22 <?php
33
 4+/**
 5+ * todo comment me
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
411 # TODO: Make this an abstract class, and make the EC2 API a subclass
512 class OpenStackNovaSecurityGroup {
613
@@ -34,7 +41,7 @@
3542 /**
3643 * @return string
3744 */
38 - function getOwner() {
 45+ function getProject() {
3946 return (string)$this->group->ownerId;
4047 }
4148
Index: trunk/extensions/OpenStackManager/OpenStackNovaAddress.php
@@ -1,5 +1,12 @@
22 <?php
33
 4+/**
 5+ * Class for Nova Address
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
 9+ */
 10+
411 # TODO: Make this an abstract class, and make the EC2 API a subclass
512 class OpenStackNovaAddress {
613
Index: trunk/extensions/OpenStackManager/OpenStackManager.php
@@ -81,12 +81,10 @@
8282 $wgOpenStackManagerCreateProjectSALPages = true;
8383 $wgOpenStackManagerLDAPUseUidAsNamingAttribute = false;
8484 $wgOpenStackManagerNovaDefaultProject = "";
85 -
8685 /**
8786 * Path to the ssh-keygen utility. Used for converting ssh key formats. False to disable its use.
8887 */
8988 $wgSshKeygen = 'ssh-keygen';
90 -
9189 /**
9290 * Path to the puttygen utility. Used for converting ssh key formats. False to disable its use.
9391 */
Index: trunk/extensions/OpenStackManager/OpenStackNovaPuppetGroup.php
@@ -2,7 +2,11 @@
33
44 /**
55 * Class for interacting with puppet groups, variables and classes
 6+ *
 7+ * @file
 8+ * @ingroup Extensions
69 */
 10+
711 class OpenStackNovaPuppetGroup {
812
913 private $id, $name, $position, $vars, $classes;

Comments

#Comment by Nikerabbit (talk | contribs)   16:20, 3 April 2012

Too big commit to even glance it through.

#Comment by Ryan lane (talk | contribs)   20:09, 3 April 2012

Yeah, I try to never make commits this large, but the majority of this commit is one refactoring.

The part I'd really like reviewed is the new functions in SpecialNova, and how they are being used, as I'd like to ensure I'm not introducing XSS.

Status & tagging log