Index: trunk/extensions/OpenStackManager/special/SpecialNovaInstance.php |
— | — | @@ -1,4 +1,12 @@ |
2 | 2 | <?php |
| 3 | + |
| 4 | +/** |
| 5 | + * special for nova instance |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
3 | 11 | class SpecialNovaInstance extends SpecialNova { |
4 | 12 | |
5 | 13 | /** |
— | — | @@ -199,7 +207,7 @@ |
200 | 208 | $group_keys = array(); |
201 | 209 | $defaults = array(); |
202 | 210 | foreach ( $securityGroups as $securityGroup ) { |
203 | | - if ( $securityGroup->getOwner() == $project ) { |
| 211 | + if ( $securityGroup->getProject() == $project ) { |
204 | 212 | $securityGroupName = $securityGroup->getGroupName(); |
205 | 213 | $group_keys["$securityGroupName"] = $securityGroupName; |
206 | 214 | if ( $securityGroupName == "default" ) { |
— | — | @@ -466,109 +474,79 @@ |
467 | 475 | $this->getOutput()->addModuleStyles( 'ext.openstack' ); |
468 | 476 | $this->getOutput()->setPagetitle( wfMsg( 'openstackmanager-instancelist' ) ); |
469 | 477 | |
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 ); |
471 | 490 | |
472 | 491 | $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(); |
486 | 492 | |
| 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(); |
487 | 515 | /** |
488 | 516 | * @var $instance OpenStackNovaInstance |
489 | 517 | */ |
490 | 518 | 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() ); |
503 | 524 | $privateip = $instance->getInstancePrivateIP(); |
504 | 525 | $publicip = $instance->getInstancePublicIP(); |
505 | | - $instanceOut .= Html::element( 'td', array(), $privateip ); |
| 526 | + $this->pushResourceColumn( $instanceRow, $privateip ); |
506 | 527 | if ( $privateip != $publicip ) { |
507 | | - $instanceOut .= Html::element( 'td', array(), $publicip ); |
| 528 | + $this->pushResourceColumn( $instanceRow, $publicip ); |
508 | 529 | } else { |
509 | | - $instanceOut .= Html::element( 'td', array(), '' ); |
| 530 | + $this->pushResourceColumn( $instanceRow, '' ); |
510 | 531 | } |
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() ) ) ); |
514 | 542 | } |
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 ); |
554 | 545 | } |
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 ''; |
570 | 550 | } |
571 | | - |
572 | | - $this->getOutput()->addHTML( $out ); |
573 | 551 | } |
574 | 552 | |
575 | 553 | /** |
Index: trunk/extensions/OpenStackManager/special/SpecialNovaSecurityGroup.php |
— | — | @@ -1,4 +1,12 @@ |
2 | 2 | <?php |
| 3 | + |
| 4 | +/** |
| 5 | + * todo comment me |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
3 | 11 | class SpecialNovaSecurityGroup extends SpecialNova { |
4 | 12 | |
5 | 13 | /** |
— | — | @@ -200,64 +208,78 @@ |
201 | 209 | $this->getOutput()->addModuleStyles( 'ext.openstack' ); |
202 | 210 | $this->getOutput()->setPagetitle( wfMsg( 'openstackmanager-securitygrouplist' ) ); |
203 | 211 | |
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 ); |
205 | 224 | |
206 | 225 | $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 ) ) { |
222 | 230 | continue; |
223 | 231 | } |
| 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(); |
224 | 251 | $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() ); |
227 | 254 | # Add rules |
228 | 255 | $rules = $group->getRules(); |
229 | 256 | if ( $rules ) { |
230 | | - $rulesOut = $ruleheader; |
| 257 | + $ruleRows = Array(); |
231 | 258 | foreach ( $rules as $rule ) { |
| 259 | + $ruleRow = Array(); |
232 | 260 | $fromport = $rule->getFromPort(); |
233 | 261 | $toport = $rule->getToPort(); |
234 | 262 | $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 ); |
238 | 266 | $ranges = $rule->getIPRanges(); |
239 | 267 | 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 ) ); |
246 | 269 | } else { |
247 | | - $ruleOut .= Html::rawElement( 'td', array(), '' ); |
| 270 | + $this->pushRawResourceColumn( $ruleRow, '' ); |
248 | 271 | } |
249 | 272 | $sourcegroups = $rule->getGroups(); |
250 | 273 | $groupinfo = array(); |
251 | 274 | if ( $sourcegroups ) { |
252 | | - $sourcegroupsOut = ''; |
| 275 | + $sourcegroupsArr = Array(); |
253 | 276 | foreach ( $sourcegroups as $sourcegroup ) { |
254 | 277 | $groupinfo[] = $sourcegroup['groupname'] . ':' . $sourcegroup['project']; |
255 | 278 | $sourcegroupinfo = $sourcegroup['groupname'] . ' (' . $sourcegroup['project'] . ')'; |
256 | | - $sourcegroupsOut .= Html::element( 'li', array(), $sourcegroupinfo ); |
| 279 | + array_push($sourcegroupsArr, $sourcegroupinfo ); |
257 | 280 | } |
258 | | - $sourcegroupsOut = Html::rawElement( 'ul', array(), $sourcegroupsOut ); |
259 | | - $ruleOut .= Html::rawElement( 'td', array(), $sourcegroupsOut ); |
| 281 | + $this->pushRawResourceColumn( $ruleRow, $this->createResourceList( $sourcegroupsArr ) ); |
260 | 282 | } else { |
261 | | - $ruleOut .= Html::rawElement( 'td', array(), '' ); |
| 283 | + $this->pushRawResourceColumn( $ruleRow, '' ); |
262 | 284 | } |
263 | 285 | $actions = ''; |
264 | 286 | if ( $this->userLDAP->inRole( 'netadmin', $project ) ) { |
— | — | @@ -270,66 +292,30 @@ |
271 | 293 | 'protocol' => $ipprotocol, |
272 | 294 | 'ranges' => implode( ',', $ranges ), |
273 | 295 | '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 ) ); |
277 | 298 | } |
278 | | - $ruleOut .= Html::rawElement( 'td', array(), $actions ); |
279 | | - $rulesOut .= Html::rawElement( 'tr', array(), $ruleOut ); |
| 299 | + $this->pushRawResourceColumn( $ruleRow, $actions ); |
| 300 | + array_push( $ruleRows, $ruleRow ); |
280 | 301 | } |
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 ) ); |
283 | 303 | } else { |
284 | | - $groupOut .= Html::rawElement( 'td', array(), '' ); |
| 304 | + $this->pushRawResourceColumn( $groupRow, '' ); |
285 | 305 | } |
286 | | - $actions = ''; |
| 306 | + $actions = Array(); |
287 | 307 | 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() ) ) ); |
307 | 311 | } |
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 ); |
314 | 314 | } |
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 ''; |
330 | 319 | } |
331 | | - |
332 | | - $this->getOutput()->addHTML( $out ); |
333 | | - return true; |
334 | 320 | } |
335 | 321 | |
336 | 322 | /** |
— | — | @@ -351,7 +337,7 @@ |
352 | 338 | $securityGroups = $this->adminNova->getSecurityGroups(); |
353 | 339 | foreach ( $securityGroups as $securityGroup ) { |
354 | 340 | $securityGroupName = $securityGroup->getGroupName(); |
355 | | - $securityGroupProject = $securityGroup->getOwner(); |
| 341 | + $securityGroupProject = $securityGroup->getProject(); |
356 | 342 | $info["$securityGroupProject"]["$securityGroupName"] = $securityGroupName . ':' . $securityGroupProject; |
357 | 343 | } |
358 | 344 | $group_keys = $info; |
Index: trunk/extensions/OpenStackManager/special/SpecialNovaAddress.php |
— | — | @@ -1,4 +1,12 @@ |
2 | 2 | <?php |
| 3 | + |
| 4 | +/** |
| 5 | + * Special page from nova address |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
3 | 11 | class SpecialNovaAddress extends SpecialNova { |
4 | 12 | |
5 | 13 | var $adminNova; |
— | — | @@ -147,7 +155,7 @@ |
148 | 156 | $instances = $this->userNova->getInstances(); |
149 | 157 | $instance_keys = array(); |
150 | 158 | foreach ( $instances as $instance ) { |
151 | | - if ( $instance->getOwner() == $project ) { |
| 159 | + if ( $instance->getProject() == $project ) { |
152 | 160 | $instancename = $instance->getInstanceName(); |
153 | 161 | $instanceid = $instance->getInstanceId(); |
154 | 162 | $instance_keys["$instancename"] = $instanceid; |
— | — | @@ -350,99 +358,95 @@ |
351 | 359 | $this->getOutput()->addModuleStyles( 'ext.openstack' ); |
352 | 360 | $this->getOutput()->setPagetitle( wfMsg( 'openstackmanager-addresslist' ) ); |
353 | 361 | |
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 | + |
355 | 375 | $out = ''; |
356 | 376 | |
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(); |
363 | 379 | $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 | + */ |
364 | 402 | foreach ( $addresses as $address ) { |
| 403 | + $addressRow = array(); |
365 | 404 | $ip = $address->getPublicIP(); |
366 | 405 | $instanceid = $address->getInstanceId(); |
367 | 406 | $project = $address->getProject(); |
368 | | - $addressOut = Html::element( 'td', array(), $ip ); |
| 407 | + $this->pushResourceColumn( $addressRow, $ip ); |
369 | 408 | 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 ); |
374 | 412 | } else { |
375 | | - $addressOut .= Html::element( 'td', array(), '' ); |
376 | | - $addressOut .= Html::element( 'td', array(), '' ); |
| 413 | + $this->pushResourceColumn( $addressRow, '' ); |
| 414 | + $this->pushResourceColumn( $addressRow, '' ); |
377 | 415 | } |
378 | 416 | $hosts = OpenStackNovaHost::getHostsByIP( $ip ); |
379 | 417 | if ( $hosts ) { |
380 | | - $hostsOut = ''; |
381 | 418 | $msg = wfMsgHtml( 'openstackmanager-removehost-action' ); |
| 419 | + $hostArr = Array(); |
382 | 420 | foreach ( $hosts as $host ) { |
383 | 421 | $domain = $host->getDomain(); |
384 | 422 | $fqdns = $host->getAssociatedDomains(); |
385 | 423 | foreach ( $fqdns as $fqdn ) { |
386 | 424 | $hostname = explode( '.', $fqdn ); |
387 | 425 | $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 ); |
392 | 428 | } |
393 | 429 | } |
394 | | - $hostsOut = Html::rawElement( 'ul', array(), $hostsOut ); |
395 | | - $addressOut .= Html::rawElement( 'td', array(), $hostsOut ); |
| 430 | + $this->pushRawResourceColumn( $addressRow, $this->createResourceList( $hostArr ) ); |
396 | 431 | } else { |
397 | | - $addressOut .= Html::element( 'td', array(), '' ); |
| 432 | + $this->pushResourceColumn( $addressRow, '' ); |
398 | 433 | } |
399 | | - $actions = ''; |
| 434 | + $actions = Array(); |
400 | 435 | 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 ) ) ); |
402 | 438 | } 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 ) ) ); |
408 | 441 | } |
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 ); |
429 | 445 | } |
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 ''; |
443 | 450 | } |
444 | | - $this->getOutput()->addHTML( $out ); |
445 | | - |
446 | | - return true; |
447 | 451 | } |
448 | 452 | |
449 | 453 | /** |
Index: trunk/extensions/OpenStackManager/special/SpecialNovaProject.php |
— | — | @@ -1,4 +1,12 @@ |
2 | 2 | <?php |
| 3 | + |
| 4 | +/** |
| 5 | + * To do: comment me |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
3 | 11 | class SpecialNovaProject extends SpecialNova { |
4 | 12 | |
5 | 13 | var $adminNova; |
— | — | @@ -155,118 +163,117 @@ |
156 | 164 | * @return void |
157 | 165 | */ |
158 | 166 | function listProjects() { |
| 167 | + global $wgRequest; |
| 168 | + |
159 | 169 | $this->setHeaders(); |
160 | 170 | $this->getOutput()->setPageTitle( wfMsg( 'openstackmanager-projectlist' ) ); |
161 | 171 | $this->getOutput()->addModuleStyles( 'ext.openstack' ); |
162 | 172 | |
163 | 173 | 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() ); |
203 | 178 | } |
| 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 ); |
204 | 186 | |
205 | 187 | $out = ''; |
206 | 188 | |
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 | | - } |
214 | 189 | foreach ( $projects as $project ) { |
215 | 190 | $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; |
222 | 193 | } |
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 ) ); |
266 | 196 | } |
267 | 197 | |
268 | 198 | $this->getOutput()->addHTML( $out ); |
269 | 199 | } |
270 | 200 | |
| 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 | + |
271 | 278 | /** |
272 | 279 | * @param $formData |
273 | 280 | * @param string $entryPoint |
Index: trunk/extensions/OpenStackManager/special/SpecialNovaDomain.php |
— | — | @@ -1,4 +1,12 @@ |
2 | 2 | <?php |
| 3 | + |
| 4 | +/** |
| 5 | + * Special page from nova domain |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
3 | 11 | class SpecialNovaDomain extends SpecialNova { |
4 | 12 | |
5 | 13 | var $adminNova; |
— | — | @@ -119,28 +127,22 @@ |
120 | 128 | $domainForm->setSubmitCallback( array( $this, 'tryCreateSubmit' ) ); |
121 | 129 | $domainForm->show(); |
122 | 130 | |
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' ); |
129 | 132 | $domains = OpenStackNovaDomain::getAllDomains(); |
| 133 | + $domainRows = Array(); |
130 | 134 | foreach ( $domains as $domain ) { |
| 135 | + $domainRow = Array(); |
131 | 136 | $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 ); |
142 | 142 | } |
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 = ''; |
145 | 147 | } |
146 | 148 | |
147 | 149 | $this->getOutput()->addHTML( $out ); |
Index: trunk/extensions/OpenStackManager/special/SpecialNovaVolume.php |
— | — | @@ -1,4 +1,12 @@ |
2 | 2 | <?php |
| 3 | + |
| 4 | +/** |
| 5 | + * todo comment me |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
3 | 11 | class SpecialNovaVolume extends SpecialNova { |
4 | 12 | |
5 | 13 | /** |
— | — | @@ -196,7 +204,7 @@ |
197 | 205 | $instances = $this->userNova->getInstances(); |
198 | 206 | $instance_keys = array(); |
199 | 207 | foreach ( $instances as $instance ) { |
200 | | - if ( $instance->getOwner() == $project ) { |
| 208 | + if ( $instance->getProject() == $project ) { |
201 | 209 | $instancename = $instance->getInstanceName(); |
202 | 210 | $instanceid = $instance->getInstanceId(); |
203 | 211 | $instance_keys["$instancename"] = $instanceid; |
— | — | @@ -311,91 +319,77 @@ |
312 | 320 | */ |
313 | 321 | function listVolumes() { |
314 | 322 | $this->setHeaders(); |
| 323 | + $this->getOutput()->addModuleStyles( 'ext.openstack' ); |
315 | 324 | $this->getOutput()->setPagetitle( wfMsg( 'openstackmanager-volumelist' ) ); |
316 | 325 | |
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 ); |
318 | 338 | |
319 | 339 | $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 ) ) { |
337 | 345 | continue; |
338 | 346 | } |
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; |
383 | 349 | } |
| 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 ) ) ); |
384 | 353 | } |
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 | | - } |
396 | 354 | |
397 | 355 | $this->getOutput()->addHTML( $out ); |
398 | 356 | } |
399 | 357 | |
| 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 | + |
400 | 394 | /** |
401 | 395 | * @param $formData |
402 | 396 | * @param string $entryPoint |
Index: trunk/extensions/OpenStackManager/special/SpecialNovaKey.php |
— | — | @@ -1,4 +1,12 @@ |
2 | 2 | <?php |
| 3 | + |
| 4 | +/** |
| 5 | + * special page for nova key |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
3 | 11 | class SpecialNovaKey extends SpecialNova { |
4 | 12 | |
5 | 13 | var $userNova; |
— | — | @@ -142,6 +150,7 @@ |
143 | 151 | $out = ''; |
144 | 152 | |
145 | 153 | if ( $wgOpenStackManagerNovaKeypairStorage == 'nova' ) { |
| 154 | + # TODO: add project filter |
146 | 155 | foreach ( $projects as $project ) { |
147 | 156 | $userCredentials = $this->userLDAP->getCredentials(); |
148 | 157 | $this->userNova = new OpenStackNovaController( $userCredentials, $project ); |
— | — | @@ -150,50 +159,50 @@ |
151 | 160 | continue; |
152 | 161 | } |
153 | 162 | $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(); |
156 | 165 | 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 ); |
160 | 170 | } |
161 | | - $out .= Html::rawElement( 'table', array( 'id' => 'novakeylist', 'class' => 'wikitable sortable collapsible' ), $projectOut ); |
| 171 | + $out .= $this->createResourceTable( $headers, $keyRows ); |
162 | 172 | } |
163 | 173 | } elseif ( $wgOpenStackManagerNovaKeypairStorage == 'ldap' ) { |
| 174 | + $headers = Array( 'openstackmanager-keys', 'openstackmanager-actions' ); |
164 | 175 | $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(); |
168 | 177 | 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 ); |
176 | 185 | } |
177 | | - $out .= Html::rawElement( 'table', array( 'id' => 'novakeylist', 'class' => 'wikitable' ), $keysOut ); |
| 186 | + $out .= $this->createResourceTable( $headers, $keyRows ); |
178 | 187 | } else { |
179 | 188 | $this->getOutput()->addWikiMsg( 'openstackmanager-invalidkeypair' ); |
180 | 189 | } |
181 | 190 | |
182 | 191 | $this->getOutput()->addHTML( $out ); |
183 | 192 | } |
184 | | - |
| 193 | + |
185 | 194 | /** |
186 | 195 | * Converts a public ssh key to openssh format. |
187 | 196 | * @param $keydata SSH public/private key in some format |
188 | 197 | * @return mixed Public key in openssh format or false |
189 | 198 | */ |
190 | | - static function opensshFormatKey($keydata) { |
| 199 | + static function opensshFormatKey( $keydata ) { |
191 | 200 | global $wgSshKeygen, $wgPuttygen; |
192 | 201 | |
193 | 202 | $public = self::opensshFormatKeySshKeygen( $keydata ); |
194 | 203 | |
195 | 204 | if ( !$public ) |
196 | 205 | $public = self::opensshFormatKeyPuttygen( $keydata ); |
197 | | - |
| 206 | + |
198 | 207 | return $public; |
199 | 208 | } |
200 | 209 | |
— | — | @@ -202,8 +211,9 @@ |
203 | 212 | * @param $keydata SSH public/private key in some format |
204 | 213 | * @return mixed Public key in openssh format or false |
205 | 214 | */ |
206 | | - static function opensshFormatKeyPuttygen($keydata) { |
| 215 | + static function opensshFormatKeyPuttygen( $keydata ) { |
207 | 216 | global $wgPuttygen; |
| 217 | + |
208 | 218 | if ( wfIsWindows() || !$wgPuttygen ) |
209 | 219 | return false; |
210 | 220 | |
— | — | @@ -215,7 +225,7 @@ |
216 | 226 | fwrite( $tmpfile, $keydata ); |
217 | 227 | |
218 | 228 | $descriptorspec = array( |
219 | | - 0 => $tmpfile, |
| 229 | + 0 => $tmpfile, |
220 | 230 | 1 => array("pipe", "w"), |
221 | 231 | 2 => array("file", wfGetNull(), "a") |
222 | 232 | ); |
— | — | @@ -248,14 +258,14 @@ |
249 | 259 | |
250 | 260 | return $data; |
251 | 261 | } |
252 | | - |
253 | | - /** |
| 262 | + /** |
254 | 263 | * Converts a public ssh key to openssh format, using ssh-keygen. |
255 | 264 | * @param $keydata SSH public/private key in some format |
256 | 265 | * @return mixed Public key in openssh format or false |
257 | 266 | */ |
258 | | - static function opensshFormatKeySshKeygen($keydata) { |
| 267 | + static function opensshFormatKeySshKeygen( $keydata ) { |
259 | 268 | global $wgSshKeygen; |
| 269 | + |
260 | 270 | if ( wfIsWindows() || !$wgSshKeygen ) |
261 | 271 | return false; |
262 | 272 | |
— | — | @@ -265,7 +275,7 @@ |
266 | 276 | } |
267 | 277 | |
268 | 278 | $descriptorspec = array( |
269 | | - 0 => array("pipe", "r"), |
| 279 | + 0 => array("pipe", "r"), |
270 | 280 | 1 => array("pipe", "w"), |
271 | 281 | 2 => array("file", wfGetNull(), "a") |
272 | 282 | ); |
— | — | @@ -287,7 +297,6 @@ |
288 | 298 | return $data; |
289 | 299 | } |
290 | 300 | |
291 | | - |
292 | 301 | /** |
293 | 302 | * @param $formData |
294 | 303 | * @param string $entryPoint |
— | — | @@ -307,9 +316,9 @@ |
308 | 317 | } |
309 | 318 | $this->getOutput()->addWikiMsg( 'openstackmanager-keypairformatconverted' ); |
310 | 319 | } |
311 | | - |
| 320 | + |
312 | 321 | if ( $wgOpenStackManagerNovaKeypairStorage == 'ldap' ) { |
313 | | - $success = $this->userLDAP->importKeypair( $key ); |
| 322 | + $success = $this->userLDAP->importKeypair( $formData['key'] ); |
314 | 323 | if ( ! $success ) { |
315 | 324 | $this->getOutput()->addWikiMsg( 'openstackmanager-keypairimportfailed' ); |
316 | 325 | return false; |
Index: trunk/extensions/OpenStackManager/special/SpecialNovaPuppetGroup.php |
— | — | @@ -1,4 +1,12 @@ |
2 | 2 | <?php |
| 3 | + |
| 4 | +/** |
| 5 | + * todo comment me |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
3 | 11 | class SpecialNovaPuppetGroup extends SpecialNova { |
4 | 12 | |
5 | 13 | function __construct() { |
— | — | @@ -605,24 +613,37 @@ |
606 | 614 | $this->getOutput()->setPagetitle( wfMsg( 'openstackmanager-puppetgrouplist' ) ); |
607 | 615 | $this->getOutput()->addModuleStyles( 'ext.openstack' ); |
608 | 616 | |
| 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 | + |
609 | 630 | $out = ''; |
610 | | - $projects = $this->userLDAP->getProjects(); |
611 | 631 | foreach ( $projects as $project ) { |
612 | | - if ( !$this->userLDAP->inRole( 'sysadmin', $project ) ) { |
| 632 | + $projectName = $project->getProjectName(); |
| 633 | + if ( $projectfilter && !in_array( $projectName, $projectfilter ) ) { |
613 | 634 | continue; |
614 | 635 | } |
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 ) ) ); |
621 | 642 | } |
622 | 643 | $action = ''; |
623 | 644 | $showlinks = $this->userCanExecute( $this->getUser() ); |
624 | 645 | if ( $showlinks ) { |
625 | 646 | |
626 | | - $action = Linker::link( $this->getTitle(), wfMsgHtml( 'openstackmanager-createpuppetgroup' ), array(), array( 'action' => 'create' ) ); |
| 647 | + $action = $this->createActionLink( 'openstackmanager-createpuppetgroup', array( 'action' => 'create' ) ); |
627 | 648 | $action = Html::rawElement( 'span', array( 'id' => 'novaaction' ), "[$action]" ); |
628 | 649 | } |
629 | 650 | $allProjectsMsg = Html::rawElement( 'span', array( 'class' => 'mw-customtoggle-allprojects', 'id' => 'novaproject' ), wfMsgHtml( 'openstackmanager-puppetallprojects' ) ); |
— | — | @@ -636,7 +657,7 @@ |
637 | 658 | $out = ''; |
638 | 659 | foreach ( $puppetGroups as $puppetGroup ) { |
639 | 660 | $puppetGroupProject = $puppetGroup->getProject(); |
640 | | - //$puppetGroupProject can be null |
| 661 | + # $puppetGroupProject can be null |
641 | 662 | if ( !$puppetGroupProject ) { |
642 | 663 | $puppetGroupProject = ''; |
643 | 664 | } |
— | — | @@ -646,14 +667,14 @@ |
647 | 668 | $puppetGroupName = "[$puppetGroupPosition] " . htmlentities( $puppetGroupName ); |
648 | 669 | $specialPuppetGroupTitle = Title::newFromText( 'Special:NovaPuppetGroup' ); |
649 | 670 | 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' ) ); |
652 | 673 | $action = Html::rawElement( 'span', array( 'id' => 'novaaction' ), "[$modify, $delete]" ); |
653 | 674 | $out .= Html::rawElement( 'h3', array(), "$puppetGroupName $action" ); |
654 | 675 | } |
655 | 676 | $action = ''; |
656 | 677 | 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' ) ); |
658 | 679 | $action = Html::rawElement( 'span', array( 'id' => 'novaaction' ), "[$action]" ); |
659 | 680 | } |
660 | 681 | $classesMsg = wfMsgHtml( 'openstackmanager-puppetclasses' ); |
— | — | @@ -661,18 +682,18 @@ |
662 | 683 | $puppetGroupClasses = $puppetGroup->getClasses(); |
663 | 684 | $puppetGroupVars = $puppetGroup->getVars(); |
664 | 685 | if ( $puppetGroupClasses ) { |
665 | | - $classesOut = ''; |
| 686 | + $classes = Array(); |
666 | 687 | foreach ( $puppetGroupClasses as $puppetGroupClass ) { |
667 | 688 | $classname = '[' . $puppetGroupClass["position"] . '] ' . htmlentities( $puppetGroupClass["name"] ); |
668 | 689 | 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' ) ); |
671 | 692 | $classname .= Html::rawElement( 'span', array( 'id' => 'novaaction' ), " [$modify, $delete]" ); |
672 | 693 | } |
673 | 694 | |
674 | | - $classesOut .= Html::rawElement( 'li', array(), $classname ); |
| 695 | + array_push( $classes, $classname ); |
675 | 696 | } |
676 | | - $out .= Html::rawElement( 'ul', array(), $classesOut ); |
| 697 | + $out .= $this->createResourceList( $classes ); |
677 | 698 | } |
678 | 699 | $action = ''; |
679 | 700 | if ( $showlinks ) { |
— | — | @@ -682,17 +703,17 @@ |
683 | 704 | $varsMsg = wfMsgHtml( 'openstackmanager-puppetvars' ); |
684 | 705 | $out .= Html::rawElement( 'h4', array(), "$varsMsg $action" ); |
685 | 706 | if ( $puppetGroupVars ) { |
686 | | - $varsOut = ''; |
| 707 | + $vars = Array(); |
687 | 708 | foreach ( $puppetGroupVars as $puppetGroupVar ) { |
688 | 709 | $varname = '[' . $puppetGroupVar["position"] . '] ' . htmlentities( $puppetGroupVar["name"] ); |
689 | 710 | 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' ) ); |
692 | 713 | $varname .= Html::rawElement( 'span', array( 'id' => 'novaaction' ), " [$modify, $delete]" ); |
693 | 714 | } |
694 | | - $varsOut .= Html::rawElement( 'li', array(), $varname ); |
| 715 | + array_push( $vars, $varname ); |
695 | 716 | } |
696 | | - $out .= Html::rawElement( 'ul', array(), $varsOut ); |
| 717 | + $out .= $this->createResourceList( $vars ); |
697 | 718 | } |
698 | 719 | } |
699 | 720 | return $out; |
Index: trunk/extensions/OpenStackManager/special/SpecialNova.php |
— | — | @@ -1,5 +1,12 @@ |
2 | 2 | <?php |
3 | 3 | |
| 4 | +/** |
| 5 | + * Special page for nova |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
4 | 11 | abstract class SpecialNova extends SpecialPage { |
5 | 12 | |
6 | 13 | /** |
— | — | @@ -75,4 +82,163 @@ |
76 | 83 | } |
77 | 84 | } |
78 | 85 | |
| 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 | + |
79 | 245 | } |
Index: trunk/extensions/OpenStackManager/special/SpecialNovaRole.php |
— | — | @@ -1,4 +1,12 @@ |
2 | 2 | <?php |
| 3 | + |
| 4 | +/** |
| 5 | + * todo comment me |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
3 | 11 | class SpecialNovaRole extends SpecialNova { |
4 | 12 | |
5 | 13 | var $adminNova; |
— | — | @@ -198,37 +206,24 @@ |
199 | 207 | $this->setHeaders(); |
200 | 208 | $this->getOutput()->setPagetitle( wfMsg( 'openstackmanager-rolelist' ) ); |
201 | 209 | |
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' ); |
207 | 211 | $roles = OpenStackNovaRole::getAllGlobalRoles(); |
208 | | - if ( ! $roles ) { |
209 | | - $rolesOut = ''; |
210 | | - } |
| 212 | + $roleRows = Array(); |
211 | 213 | foreach ( $roles as $role ) { |
| 214 | + $roleRow = Array(); |
212 | 215 | $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 ); |
230 | 223 | } |
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 = ''; |
233 | 228 | } |
234 | 229 | |
235 | 230 | $this->getOutput()->addHTML( $out ); |
Index: trunk/extensions/OpenStackManager/special/SpecialNovaSudoer.php |
— | — | @@ -1,4 +1,12 @@ |
2 | 2 | <?php |
| 3 | + |
| 4 | +/** |
| 5 | + * todo comment me |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
3 | 11 | class SpecialNovaSudoer extends SpecialNova { |
4 | 12 | |
5 | 13 | var $userLDAP; |
— | — | @@ -18,6 +26,10 @@ |
19 | 27 | $this->noCredentials(); |
20 | 28 | return; |
21 | 29 | } |
| 30 | + if ( !$this->userLDAP->inGlobalRole( 'cloudadmin' ) ) { |
| 31 | + $this->notInRole( 'cloudadmin' ); |
| 32 | + return; |
| 33 | + } |
22 | 34 | |
23 | 35 | $action = $this->getRequest()->getVal( 'action' ); |
24 | 36 | if ( $action == "delete" ) { |
— | — | @@ -192,59 +204,28 @@ |
193 | 205 | $sudoerForm->setSubmitCallback( array( $this, 'tryCreateSubmit' ) ); |
194 | 206 | $sudoerForm->show(); |
195 | 207 | |
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' ); |
203 | 210 | $sudoers = OpenStackNovaSudoer::getAllSudoers(); |
| 211 | + $sudoerRows = Array(); |
204 | 212 | foreach ( $sudoers as $sudoer ) { |
| 213 | + $sudoerRow = Array(); |
205 | 214 | $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 ); |
246 | 225 | } |
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 = ''; |
249 | 230 | } |
250 | 231 | |
251 | 232 | $this->getOutput()->addHTML( $out ); |
Index: trunk/extensions/OpenStackManager/OpenStackNovaLdapConnection.php |
— | — | @@ -1,5 +1,12 @@ |
2 | 2 | <?php |
3 | 3 | |
| 4 | +/** |
| 5 | + * class for nova ldap |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
4 | 11 | class OpenStackNovaLdapConnection { |
5 | 12 | |
6 | 13 | /** |
Index: trunk/extensions/OpenStackManager/OpenStackNovaSudoer.php |
— | — | @@ -1,5 +1,12 @@ |
2 | 2 | <?php |
3 | 3 | |
| 4 | +/** |
| 5 | + * class for nova sudoers |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
4 | 11 | class OpenStackNovaSudoer { |
5 | 12 | |
6 | 13 | var $sudoername; |
Index: trunk/extensions/OpenStackManager/OpenStackNovaRole.php |
— | — | @@ -1,5 +1,12 @@ |
2 | 2 | <?php |
3 | 3 | |
| 4 | +/** |
| 5 | + * todo comment me |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
4 | 11 | class OpenStackNovaRole { |
5 | 12 | |
6 | 13 | var $rolename; |
— | — | @@ -10,7 +17,7 @@ |
11 | 18 | |
12 | 19 | /** |
13 | 20 | * @param $rolename |
14 | | - * @param null $project |
| 21 | + * @param null $project, optional |
15 | 22 | */ |
16 | 23 | function __construct( $rolename, $project=null ) { |
17 | 24 | $this->rolename = $rolename; |
— | — | @@ -117,6 +124,8 @@ |
118 | 125 | } |
119 | 126 | $success = LdapAuthenticationPlugin::ldap_modify( $wgAuth->ldapconn, $this->roleDN, $values ); |
120 | 127 | if ( $success ) { |
| 128 | + $key = $this->getMemcKey( $user ); |
| 129 | + $wgMemc->delete( $key ); |
121 | 130 | $this->fetchRoleInfo(); |
122 | 131 | $wgAuth->printDebug( "Successfully removed $user->userDN from $this->roleDN", NONSENSITIVE ); |
123 | 132 | return true; |
— | — | @@ -135,6 +144,7 @@ |
136 | 145 | */ |
137 | 146 | function addMember( $username ) { |
138 | 147 | global $wgAuth; |
| 148 | + global $wgMemc; |
139 | 149 | |
140 | 150 | $members = array(); |
141 | 151 | if ( isset( $this->roleInfo[0]['member'] ) ) { |
— | — | @@ -153,6 +163,8 @@ |
154 | 164 | if ( $success ) { |
155 | 165 | $this->fetchRoleInfo(); |
156 | 166 | $wgAuth->printDebug( "Successfully added $user->userDN to $this->roleDN", NONSENSITIVE ); |
| 167 | + $key = $this->getMemcKey( $user ); |
| 168 | + $wgMemc->delete( $key ); |
157 | 169 | return true; |
158 | 170 | } else { |
159 | 171 | $wgAuth->printDebug( "Failed to add $user->userDN to $this->roleDN", NONSENSITIVE ); |
— | — | @@ -160,6 +172,17 @@ |
161 | 173 | } |
162 | 174 | } |
163 | 175 | |
| 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 | + |
164 | 187 | /** |
165 | 188 | * @static |
166 | 189 | * @param $rolename |
Index: trunk/extensions/OpenStackManager/OpenStackManager.i18n.php |
— | — | @@ -190,6 +190,10 @@ |
191 | 191 | 'openstackmanager-removedfrom' => 'Successfully removed $1 from $2.', |
192 | 192 | 'openstackmanager-failedtoremove' => 'Failed to remove $1 from $2.', |
193 | 193 | '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.', |
194 | 198 | |
195 | 199 | 'openstackmanager-roles' => 'Roles', |
196 | 200 | 'openstackmanager-rolename' => 'Role name', |
— | — | @@ -419,6 +423,10 @@ |
420 | 424 | 'openstackmanager-sudoerusers' => '{{Identical|User}}', |
421 | 425 | 'openstackmanager-sudoeroptions' => '{{Identical|Options}}', |
422 | 426 | '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.', |
423 | 431 | ); |
424 | 432 | |
425 | 433 | /** Afrikaans (Afrikaans) |
Index: trunk/extensions/OpenStackManager/OpenStackNovaInstance.php |
— | — | @@ -1,5 +1,12 @@ |
2 | 2 | <?php |
3 | 3 | |
| 4 | +/** |
| 5 | + * class for NovaInstance |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
4 | 11 | # TODO: Make this an abstract class, and make the EC2 API a subclass |
5 | 12 | class OpenStackNovaInstance { |
6 | 13 | |
— | — | @@ -12,7 +19,7 @@ |
13 | 20 | |
14 | 21 | /** |
15 | 22 | * @param $apiInstanceResponse |
16 | | - * @param bool $loadhost |
| 23 | + * @param bool $loadhost, optional |
17 | 24 | */ |
18 | 25 | function __construct( $apiInstanceResponse, $loadhost = false ) { |
19 | 26 | $this->instance = $apiInstanceResponse; |
— | — | @@ -131,7 +138,7 @@ |
132 | 139 | * |
133 | 140 | * @return string |
134 | 141 | */ |
135 | | - function getOwner() { |
| 142 | + function getProject() { |
136 | 143 | return (string)$this->instance->ownerId; |
137 | 144 | } |
138 | 145 | |
— | — | @@ -254,7 +261,7 @@ |
255 | 262 | $instanceType->getNumberOfCPUs(), |
256 | 263 | $instanceType->getStorageSize(), |
257 | 264 | $this->getImageId(), |
258 | | - $this->getOwner(), |
| 265 | + $this->getProject(), |
259 | 266 | $this->getAvailabilityZone(), |
260 | 267 | $this->getRegion(), |
261 | 268 | implode( ',', $this->getSecurityGroups() ), |
Index: trunk/extensions/OpenStackManager/OpenStackNovaKeypair.php |
— | — | @@ -1,5 +1,12 @@ |
2 | 2 | <?php |
3 | 3 | |
| 4 | +/** |
| 5 | + * todo comment me |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
4 | 11 | # TODO: Make this an abstract class, and make the EC2 API a subclass |
5 | 12 | class OpenStackNovaKeyPair { |
6 | 13 | |
Index: trunk/extensions/OpenStackManager/OpenStackNovaInstanceType.php |
— | — | @@ -1,5 +1,12 @@ |
2 | 2 | <?php |
3 | 3 | |
| 4 | +/** |
| 5 | + * todo comment me |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
4 | 11 | # TODO: Make this an abstract class, and make the EC2 API a subclass |
5 | 12 | class OpenStackNovaInstanceType { |
6 | 13 | |
Index: trunk/extensions/OpenStackManager/OpenStackNovaProject.php |
— | — | @@ -1,5 +1,12 @@ |
2 | 2 | <?php |
3 | 3 | |
| 4 | +/** |
| 5 | + * todo comment me |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
4 | 11 | class OpenStackNovaProject { |
5 | 12 | |
6 | 13 | var $projectname; |
— | — | @@ -7,6 +14,7 @@ |
8 | 15 | var $projectInfo; |
9 | 16 | var $roles; |
10 | 17 | |
| 18 | + // list of roles |
11 | 19 | static $rolenames = array( 'sysadmin', 'netadmin' ); |
12 | 20 | |
13 | 21 | /** |
— | — | @@ -179,6 +187,17 @@ |
180 | 188 | } |
181 | 189 | } |
182 | 190 | |
| 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 | + |
183 | 202 | /** |
184 | 203 | * Return all existing projects. Returns an empty array if no projects exist. |
185 | 204 | * |
— | — | @@ -346,7 +365,7 @@ |
347 | 366 | OpenStackNovaArticle::editArticle( $this->getProjectName(), $text ); |
348 | 367 | if ( $wgOpenStackManagerCreateProjectSALPages ) { |
349 | 368 | $pagename = $this->getProjectName() . "/SAL"; |
350 | | - $id = Title::newFromText( $pagename, NS_NOVA_RESOURCE )->getArticleID(); |
| 369 | + $id = Title::newFromText( $pagename, NS_NOVA_RESOURCE )->getArticleId(); |
351 | 370 | $article = Article::newFromId( $id ); |
352 | 371 | $content = ''; |
353 | 372 | if ( $article ) { |
Index: trunk/extensions/OpenStackManager/OpenStackNovaVolume.php |
— | — | @@ -1,5 +1,12 @@ |
2 | 2 | <?php |
3 | 3 | |
| 4 | +/** |
| 5 | + * todo comment me |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
4 | 11 | # TODO: Make this an abstract class, and make the EC2 API a subclass |
5 | 12 | class OpenStackNovaVolume { |
6 | 13 | |
— | — | @@ -129,7 +136,7 @@ |
130 | 137 | * |
131 | 138 | * @return string |
132 | 139 | */ |
133 | | - function getOwner() { |
| 140 | + function getProject() { |
134 | 141 | $status = (string)$this->volume->status; |
135 | 142 | $status = explode( ' ', $status ); |
136 | 143 | |
Index: trunk/extensions/OpenStackManager/OpenStackNovaDomain.php |
— | — | @@ -1,11 +1,18 @@ |
2 | 2 | <?php |
3 | 3 | |
| 4 | +/** |
| 5 | + * Class for Nova Domain |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
4 | 11 | class OpenStackNovaDomain { |
5 | 12 | |
6 | 13 | var $domainname; |
7 | 14 | var $domainDN; |
8 | 15 | var $domainInfo; |
9 | | - var $fqdn; |
| 16 | + var $fqdn; // fq domain name |
10 | 17 | |
11 | 18 | /** |
12 | 19 | * @param $domainname |
Index: trunk/extensions/OpenStackManager/OpenStackNovaHostJob.php |
— | — | @@ -1,4 +1,12 @@ |
2 | 2 | <?php |
| 3 | + |
| 4 | +/** |
| 5 | + * todo comment me |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
3 | 11 | class OpenStackNovaHostJob extends Job { |
4 | 12 | |
5 | 13 | /** |
Index: trunk/extensions/OpenStackManager/OpenStackNovaHost.php |
— | — | @@ -1,5 +1,12 @@ |
2 | 2 | <?php |
3 | 3 | |
| 4 | +/** |
| 5 | + * todo comment me |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
4 | 11 | class OpenStackNovaHost { |
5 | 12 | |
6 | 13 | /** |
— | — | @@ -572,7 +579,7 @@ |
573 | 580 | |
574 | 581 | $hostname = $instance->getInstanceName(); |
575 | 582 | $instanceid = $instance->getInstanceId(); |
576 | | - $project = $instance->getOwner(); |
| 583 | + $project = $instance->getProject(); |
577 | 584 | $ip = $instance->getInstancePrivateIP(); |
578 | 585 | $domainname = $domain->getFullyQualifiedDomainName(); |
579 | 586 | $host = OpenStackNovaHost::getHostByName( $hostname, $domain ); |
Index: trunk/extensions/OpenStackManager/OpenStackNovaUser.php |
— | — | @@ -1,5 +1,12 @@ |
2 | 2 | <?php |
3 | 3 | |
| 4 | +/** |
| 5 | + * todo comment me |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
4 | 11 | class OpenStackNovaUser { |
5 | 12 | |
6 | 13 | var $username; |
— | — | @@ -20,7 +27,17 @@ |
21 | 28 | */ |
22 | 29 | function fetchUserInfo() { |
23 | 30 | global $wgAuth, $wgUser; |
| 31 | + global $wgMemc; |
24 | 32 | |
| 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 | + } |
25 | 42 | if ( $this->username ) { |
26 | 43 | $this->userDN = $wgAuth->getUserDN( strtolower( $this->username ) ); |
27 | 44 | $wgAuth->printDebug( "Fetching userdn using username: $this->userDN ", NONSENSITIVE ); |
— | — | @@ -29,6 +46,7 @@ |
30 | 47 | $wgAuth->printDebug( "Fetching userdn using wiki name: " . $wgUser->getName(), NONSENSITIVE ); |
31 | 48 | } |
32 | 49 | $this->userInfo = $wgAuth->userInfo; |
| 50 | + $wgMemc->set( $key, $this->userInfo, $cacheLength ); |
33 | 51 | } |
34 | 52 | |
35 | 53 | /** |
— | — | @@ -139,24 +157,30 @@ |
140 | 158 | function inProject( $project ) { |
141 | 159 | global $wgAuth; |
142 | 160 | global $wgOpenStackManagerLDAPProjectBaseDN; |
| 161 | + global $wgMemc; |
143 | 162 | |
| 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 | + |
144 | 170 | $filter = "(&(cn=$project)(member=$this->userDN)(owner=*))"; |
145 | 171 | $result = LdapAuthenticationPlugin::ldap_search( $wgAuth->ldapconn, $wgOpenStackManagerLDAPProjectBaseDN, $filter ); |
| 172 | + $ret = false; |
146 | 173 | if ( $result ) { |
147 | 174 | $entries = LdapAuthenticationPlugin::ldap_get_entries( $wgAuth->ldapconn, $result ); |
148 | 175 | if ( $entries ) { |
149 | 176 | if ( $entries['count'] == "0" ) { |
150 | 177 | $wgAuth->printDebug( "Couldn't find the user in project: $project", NONSENSITIVE ); |
151 | | - return false; |
152 | 178 | } else { |
153 | | - return true; |
| 179 | + $ret = true; |
154 | 180 | } |
155 | | - } else { |
156 | | - return false; |
157 | 181 | } |
158 | | - } else { |
159 | | - return false; |
160 | 182 | } |
| 183 | + $wgMemc->set( $key, (int)$ret, $cacheLength ); |
| 184 | + return $ret; |
161 | 185 | } |
162 | 186 | |
163 | 187 | /** |
— | — | @@ -167,23 +191,39 @@ |
168 | 192 | function inRole( $role, $projectname='', $strict=false ) { |
169 | 193 | global $wgAuth; |
170 | 194 | global $wgOpenStackManagerLDAPRolesIntersect; |
| 195 | + global $wgMemc; |
171 | 196 | |
| 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 | + |
172 | 208 | if ( $this->inGlobalRole( $role ) ) { |
173 | 209 | # If roles intersect, or we wish to explicitly check |
174 | 210 | # project role, we can't return here. |
175 | 211 | if ( !$wgOpenStackManagerLDAPRolesIntersect && !$strict ) { |
| 212 | + $wgMemc->set( $key, 1, $cacheLength ); |
176 | 213 | return true; |
177 | 214 | } |
178 | 215 | } else { |
179 | 216 | if ( $wgOpenStackManagerLDAPRolesIntersect ) { |
| 217 | + $wgMemc->set( $key, 0, $cacheLength ); |
180 | 218 | return false; |
181 | 219 | } |
182 | 220 | } |
183 | 221 | |
| 222 | + $ret = false; |
184 | 223 | if ( $projectname ) { |
185 | 224 | # Check project specific role |
186 | 225 | $project = OpenStackNovaProject::getProjectByName( $projectname ); |
187 | 226 | if ( ! $project ) { |
| 227 | + $wgMemc->set( $key, 0, $cacheLength ); |
188 | 228 | return false; |
189 | 229 | } |
190 | 230 | $filter = "(&(cn=$role)(member=$this->userDN))"; |
— | — | @@ -193,18 +233,14 @@ |
194 | 234 | if ( $entries ) { |
195 | 235 | if ( $entries['count'] == "0" ) { |
196 | 236 | $wgAuth->printDebug( "Couldn't find the user in role: $role", NONSENSITIVE ); |
197 | | - return false; |
198 | 237 | } else { |
199 | | - return true; |
| 238 | + $ret = true; |
200 | 239 | } |
201 | | - } else { |
202 | | - return false; |
203 | 240 | } |
204 | | - } else { |
205 | | - return false; |
206 | 241 | } |
207 | 242 | } |
208 | | - return false; |
| 243 | + $wgMemc->set( $key, (int)$ret, $cacheLength ); |
| 244 | + return $ret; |
209 | 245 | } |
210 | 246 | |
211 | 247 | /** |
— | — | @@ -225,11 +261,11 @@ |
226 | 262 | if ( $wgOpenStackManagerLDAPGlobalRoles["$role"] ) { |
227 | 263 | # Check global role |
228 | 264 | $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 ); |
231 | 267 | if ( $result ) { |
232 | 268 | $entries = LdapAuthenticationPlugin::ldap_get_entries( $wgAuth->ldapconn, $result ); |
233 | | - return ( in_array( $this->userDN, $entries[0]['member'] ) ); |
| 269 | + return ( (int)$entries['count'] > 0 ); |
234 | 270 | } |
235 | 271 | } |
236 | 272 | return false; |
— | — | @@ -241,6 +277,7 @@ |
242 | 278 | */ |
243 | 279 | function importKeypair( $key ) { |
244 | 280 | global $wgAuth; |
| 281 | + global $wgMemc; |
245 | 282 | |
246 | 283 | $keypairs = array(); |
247 | 284 | if ( isset( $this->userInfo[0]['sshpublickey'] ) ) { |
— | — | @@ -253,6 +290,9 @@ |
254 | 291 | $success = LdapAuthenticationPlugin::ldap_modify( $wgAuth->ldapconn, $this->userDN, $values ); |
255 | 292 | if ( $success ) { |
256 | 293 | $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 ); |
257 | 297 | $this->fetchUserInfo(); |
258 | 298 | return true; |
259 | 299 | } else { |
— | — | @@ -267,6 +307,7 @@ |
268 | 308 | */ |
269 | 309 | function deleteKeypair( $key ) { |
270 | 310 | global $wgAuth; |
| 311 | + global $wgMemc; |
271 | 312 | |
272 | 313 | if ( isset( $this->userInfo[0]['sshpublickey'] ) ) { |
273 | 314 | $keypairs = $this->userInfo[0]['sshpublickey']; |
— | — | @@ -285,6 +326,9 @@ |
286 | 327 | $success = LdapAuthenticationPlugin::ldap_modify( $wgAuth->ldapconn, $this->userDN, $values ); |
287 | 328 | if ( $success ) { |
288 | 329 | $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 ); |
289 | 333 | $this->fetchUserInfo(); |
290 | 334 | return true; |
291 | 335 | } else { |
Index: trunk/extensions/OpenStackManager/OpenStackNovaImage.php |
— | — | @@ -1,5 +1,12 @@ |
2 | 2 | <?php |
3 | 3 | |
| 4 | +/** |
| 5 | + * todo comment me |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
4 | 11 | # TODO: Make this an abstract class, and make the EC2 API a subclass |
5 | 12 | class OpenStackNovaImage { |
6 | 13 | |
Index: trunk/extensions/OpenStackManager/OpenStackNovaController.php |
— | — | @@ -1,5 +1,12 @@ |
2 | 2 | <?php |
3 | 3 | |
| 4 | +/** |
| 5 | + * todo comment me |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
4 | 11 | # TODO: Make this an abstract class, and make the EC2 API a subclass |
5 | 12 | class OpenStackNovaController { |
6 | 13 | |
— | — | @@ -71,30 +78,40 @@ |
72 | 79 | * @return null|OpenStackNovaInstance |
73 | 80 | */ |
74 | 81 | 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"]; |
78 | 85 | } else { |
79 | 86 | return null; |
80 | 87 | } |
81 | 88 | } |
82 | 89 | |
83 | 90 | /** |
| 91 | + * @param $instanceId string |
| 92 | + * @param $project string|array |
84 | 93 | * @return array |
85 | 94 | */ |
86 | | - function getInstances() { |
| 95 | + function getInstances( $instanceId = null, $project = array() ) { |
87 | 96 | $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 ); |
89 | 105 | $instances = $response->body->reservationSet->item; |
90 | 106 | foreach ( $instances as $instance ) { |
91 | 107 | $instance = new OpenStackNovaInstance( $instance, true ); |
92 | | - $instanceId = $instance->getInstanceId(); |
93 | | - $this->instances["$instanceId"] = $instance; |
| 108 | + $id = $instance->getInstanceId(); |
| 109 | + $this->instances["$id"] = $instance; |
94 | 110 | } |
95 | 111 | return $this->instances; |
96 | 112 | } |
97 | 113 | |
98 | 114 | /** |
| 115 | + * @param $instanceType |
99 | 116 | * @return OpenStackNovaInstanceType |
100 | 117 | */ |
101 | 118 | function getInstanceType( $instanceType ) { |
— | — | @@ -176,6 +193,7 @@ |
177 | 194 | } |
178 | 195 | |
179 | 196 | /** |
| 197 | + * @param $project |
180 | 198 | * @param $groupname |
181 | 199 | * @return OpenStackNovaSecurityGroup |
182 | 200 | */ |
— | — | @@ -197,7 +215,7 @@ |
198 | 216 | $securityGroups = $securityGroups->body->securityGroupInfo->item; |
199 | 217 | foreach ( $securityGroups as $securityGroup ) { |
200 | 218 | $securityGroup = new OpenStackNovaSecurityGroup( $securityGroup ); |
201 | | - $project = $securityGroup->getOwner(); |
| 219 | + $project = $securityGroup->getProject(); |
202 | 220 | $groupname = $securityGroup->getGroupName(); |
203 | 221 | $this->securityGroups["$project-$groupname"] = $securityGroup; |
204 | 222 | } |
— | — | @@ -381,7 +399,7 @@ |
382 | 400 | * @return |
383 | 401 | */ |
384 | 402 | function deleteSecurityGroup( $groupname ) { |
385 | | - $response = $this->novaConnection->delete_security_group( $groupname ); |
| 403 | + $response = $this->novaConnection->delete_security_group( Array( "GroupName" => $groupname ) ); |
386 | 404 | |
387 | 405 | return $response->isOK(); |
388 | 406 | } |
— | — | @@ -504,6 +522,8 @@ |
505 | 523 | } |
506 | 524 | |
507 | 525 | /** |
| 526 | + * Release ip address |
| 527 | + * |
508 | 528 | * @param $ip |
509 | 529 | * @return |
510 | 530 | */ |
— | — | @@ -514,6 +534,8 @@ |
515 | 535 | } |
516 | 536 | |
517 | 537 | /** |
| 538 | + * Attach new ip address to instance |
| 539 | + * |
518 | 540 | * @param $instanceid |
519 | 541 | * @param $ip |
520 | 542 | * @return null|OpenStackNovaAddress |
— | — | @@ -530,6 +552,8 @@ |
531 | 553 | } |
532 | 554 | |
533 | 555 | /** |
| 556 | + * Disassociate address from an instance |
| 557 | + * |
534 | 558 | * @param $ip |
535 | 559 | * @return |
536 | 560 | */ |
Index: trunk/extensions/OpenStackManager/OpenStackNovaArticle.php |
— | — | @@ -1,5 +1,12 @@ |
2 | 2 | <?php |
3 | 3 | |
| 4 | +/** |
| 5 | + * todo comment me |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
4 | 11 | class OpenStackNovaArticle { |
5 | 12 | |
6 | 13 | public static function canCreatePages() { |
Index: trunk/extensions/OpenStackManager/OpenStackNovaSecurityGroup.php |
— | — | @@ -1,5 +1,12 @@ |
2 | 2 | <?php |
3 | 3 | |
| 4 | +/** |
| 5 | + * todo comment me |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
4 | 11 | # TODO: Make this an abstract class, and make the EC2 API a subclass |
5 | 12 | class OpenStackNovaSecurityGroup { |
6 | 13 | |
— | — | @@ -34,7 +41,7 @@ |
35 | 42 | /** |
36 | 43 | * @return string |
37 | 44 | */ |
38 | | - function getOwner() { |
| 45 | + function getProject() { |
39 | 46 | return (string)$this->group->ownerId; |
40 | 47 | } |
41 | 48 | |
Index: trunk/extensions/OpenStackManager/OpenStackNovaAddress.php |
— | — | @@ -1,5 +1,12 @@ |
2 | 2 | <?php |
3 | 3 | |
| 4 | +/** |
| 5 | + * Class for Nova Address |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
| 9 | + */ |
| 10 | + |
4 | 11 | # TODO: Make this an abstract class, and make the EC2 API a subclass |
5 | 12 | class OpenStackNovaAddress { |
6 | 13 | |
Index: trunk/extensions/OpenStackManager/OpenStackManager.php |
— | — | @@ -81,12 +81,10 @@ |
82 | 82 | $wgOpenStackManagerCreateProjectSALPages = true; |
83 | 83 | $wgOpenStackManagerLDAPUseUidAsNamingAttribute = false; |
84 | 84 | $wgOpenStackManagerNovaDefaultProject = ""; |
85 | | - |
86 | 85 | /** |
87 | 86 | * Path to the ssh-keygen utility. Used for converting ssh key formats. False to disable its use. |
88 | 87 | */ |
89 | 88 | $wgSshKeygen = 'ssh-keygen'; |
90 | | - |
91 | 89 | /** |
92 | 90 | * Path to the puttygen utility. Used for converting ssh key formats. False to disable its use. |
93 | 91 | */ |
Index: trunk/extensions/OpenStackManager/OpenStackNovaPuppetGroup.php |
— | — | @@ -2,7 +2,11 @@ |
3 | 3 | |
4 | 4 | /** |
5 | 5 | * Class for interacting with puppet groups, variables and classes |
| 6 | + * |
| 7 | + * @file |
| 8 | + * @ingroup Extensions |
6 | 9 | */ |
| 10 | + |
7 | 11 | class OpenStackNovaPuppetGroup { |
8 | 12 | |
9 | 13 | private $id, $name, $position, $vars, $classes; |