r80543 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r80542‎ | r80543 | r80544 >
Date:00:42, 19 January 2011
Author:laner
Status:deferred
Tags:
Comment:
* Fixed forms re-showing upon errors, when they should not re-show
* Added Security Group support
* Upped version to 0.7
Modified paths:
  • /trunk/extensions/OpenStackManager/OpenStackManager.i18n.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackManager.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaController.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaSecurityGroup.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaSecurityGroupRule.php (modified) (history)
  • /trunk/extensions/OpenStackManager/special/SpecialNovaAddress.php (modified) (history)
  • /trunk/extensions/OpenStackManager/special/SpecialNovaDomain.php (modified) (history)
  • /trunk/extensions/OpenStackManager/special/SpecialNovaInstance.php (modified) (history)
  • /trunk/extensions/OpenStackManager/special/SpecialNovaKey.php (modified) (history)
  • /trunk/extensions/OpenStackManager/special/SpecialNovaProject.php (modified) (history)
  • /trunk/extensions/OpenStackManager/special/SpecialNovaSecurityGroup.php (added) (history)

Diff [purge]

Index: trunk/extensions/OpenStackManager/special/SpecialNovaInstance.php
@@ -387,7 +387,7 @@
388388 $domain = OpenStackNovaDomain::getDomainByName( $formData['domain'] );
389389 if ( ! $domain ) {
390390 $out = Html::element( 'p', array(), wfMsg( 'openstackmanager-invaliddomain' ) );
391 - return false;
 391+ return true;
392392 }
393393 $instance = $this->userNova->createInstance( $formData['instancename'], $formData['imageType'], '', $formData['instanceType'], $formData['availabilityZone'] );
394394 if ( $instance ) {
Index: trunk/extensions/OpenStackManager/special/SpecialNovaSecurityGroup.php
@@ -0,0 +1,597 @@
 2+<?php
 3+class SpecialNovaSecurityGroup extends SpecialNova {
 4+
 5+ var $adminNova, $userNova;
 6+ var $userLDAP;
 7+
 8+ function __construct() {
 9+ parent::__construct( 'NovaSecurityGroup' );
 10+ }
 11+
 12+ function execute( $par ) {
 13+ global $wgRequest, $wgUser;
 14+ global $wgOpenStackManagerNovaAdminKeys;
 15+
 16+ if ( ! $wgUser->isLoggedIn() ) {
 17+ $this->notLoggedIn();
 18+ return true;
 19+ }
 20+ $this->userLDAP = new OpenStackNovaUser();
 21+ if ( ! $this->userLDAP->exists() ) {
 22+ $this->noCredentials();
 23+ return true;
 24+ }
 25+ $adminCredentials = $wgOpenStackManagerNovaAdminKeys;
 26+ $this->adminNova = new OpenStackNovaController( $adminCredentials );
 27+
 28+ $action = $wgRequest->getVal( 'action' );
 29+
 30+ if ( $action == "create" ) {
 31+ $this->createSecurityGroup();
 32+ } else if ( $action == "delete" ) {
 33+ $this->deleteSecurityGroup();
 34+ } else if ( $action == "configure" ) {
 35+ // Currently unsupported
 36+ #$this->configureSecurityGroup();
 37+ $this->listSecurityGroups();
 38+ } else if ( $action == "addrule" ) {
 39+ $this->addRule();
 40+ } else if ( $action == "removerule" ) {
 41+ $this->removeRule();
 42+ } else {
 43+ $this->listSecurityGroups();
 44+ }
 45+ }
 46+
 47+ function createSecurityGroup() {
 48+ global $wgRequest, $wgOut;
 49+
 50+ $this->setHeaders();
 51+ $wgOut->setPagetitle( wfMsg( 'openstackmanager-createsecuritygroup' ) );
 52+
 53+ $project = $wgRequest->getText( 'project' );
 54+ if ( ! $this->userLDAP->inRole( 'netadmin', $project ) ) {
 55+ $this->notInRole( 'netadmin' );
 56+ return false;
 57+ }
 58+ $securityGroupInfo = Array();
 59+ $securityGroupInfo['groupname'] = array(
 60+ 'type' => 'text',
 61+ 'label-message' => 'openstackmanager-securitygroupname',
 62+ 'default' => '',
 63+ );
 64+ $securityGroupInfo['description'] = array(
 65+ 'type' => 'text',
 66+ 'label-message' => 'openstackmanager-securitygroupdescription',
 67+ 'default' => '',
 68+ );
 69+ $securityGroupInfo['project'] = array(
 70+ 'type' => 'hidden',
 71+ 'default' => $project,
 72+ );
 73+
 74+ $securityGroupInfo['action'] = array(
 75+ 'type' => 'hidden',
 76+ 'default' => 'create',
 77+ );
 78+
 79+ $securityGroupForm = new SpecialNovaSecurityGroupForm( $securityGroupInfo, 'openstackmanager-novasecuritygroup' );
 80+ $securityGroupForm->setTitle( SpecialPage::getTitleFor( 'NovaSecurityGroup' ) );
 81+ $securityGroupForm->setSubmitID( 'openstackmanager-novainstance-createsecuritygroupsubmit' );
 82+ $securityGroupForm->setSubmitCallback( array( $this, 'tryCreateSubmit' ) );
 83+ $securityGroupForm->show();
 84+
 85+ return true;
 86+
 87+ }
 88+
 89+ function configureSecurityGroup() {
 90+ global $wgRequest, $wgOut;
 91+ global $wgOpenStackManagerPuppetOptions;
 92+
 93+ $this->setHeaders();
 94+ $wgOut->setPagetitle( wfMsg( 'openstackmanager-configuresecuritygroup' ) );
 95+
 96+ $securitygroupname = $wgRequest->getText( 'groupname' );
 97+ $securitygroup = $this->adminNova->getSecurityGroup( $securitygroupname );
 98+ $description = $securitygroup->getGroupDescription();
 99+ $project = $wgRequest->getText( 'project' );
 100+ if ( ! $this->userLDAP->inRole( 'netadmin', $project ) ) {
 101+ $this->notInRole( 'netadmin' );
 102+ return false;
 103+ }
 104+ $securityGroupInfo = Array();
 105+ $securityGroupInfo['groupname'] = array(
 106+ 'type' => 'hidden',
 107+ 'default' => $securitygroupname,
 108+ );
 109+ $securityGroupInfo['description'] = array(
 110+ 'type' => 'text',
 111+ 'label-message' => 'openstackmanager-securitygroupdescription',
 112+ 'default' => $description,
 113+ );
 114+ $securityGroupInfo['project'] = array(
 115+ 'type' => 'hidden',
 116+ 'default' => $project,
 117+ );
 118+
 119+ $securityGroupInfo['action'] = array(
 120+ 'type' => 'hidden',
 121+ 'default' => 'configure',
 122+ );
 123+
 124+ $securityGroupForm = new SpecialNovaSecurityGroupForm( $securityGroupInfo, 'openstackmanager-novasecuritygroup' );
 125+ $securityGroupForm->setTitle( SpecialPage::getTitleFor( 'NovaSecurityGroup' ) );
 126+ $securityGroupForm->setSubmitID( 'openstackmanager-novainstance-configuresecuritygroupsubmit' );
 127+ $securityGroupForm->setSubmitCallback( array( $this, 'tryConfigureSubmit' ) );
 128+ $securityGroupForm->show();
 129+
 130+ return true;
 131+
 132+ }
 133+
 134+ function deleteSecurityGroup() {
 135+ global $wgOut, $wgRequest;
 136+
 137+ $this->setHeaders();
 138+ $wgOut->setPagetitle( wfMsg( 'openstackmanager-deletesecuritygroup' ) );
 139+
 140+ $project = $wgRequest->getText( 'project' );
 141+ if ( ! $this->userLDAP->inRole( 'netadmin', $project ) ) {
 142+ $this->notInRole( 'netadmin' );
 143+ return false;
 144+ }
 145+ $securitygroupname = $wgRequest->getText( 'groupname' );
 146+ if ( ! $wgRequest->wasPosted() ) {
 147+ $out = Html::element( 'p', array(), wfMsgExt( 'openstackmanager-deletesecuritygroup-confirm', array(), $securitygroupname ) );
 148+ $wgOut->addHTML( $out );
 149+ }
 150+ $securityGroupInfo = Array();
 151+ $securityGroupInfo['groupname'] = array(
 152+ 'type' => 'hidden',
 153+ 'default' => $securitygroupname,
 154+ );
 155+ $securityGroupInfo['project'] = array(
 156+ 'type' => 'hidden',
 157+ 'default' => $project,
 158+ );
 159+ $securityGroupInfo['action'] = array(
 160+ 'type' => 'hidden',
 161+ 'default' => 'delete',
 162+ );
 163+ $securityGroupForm = new SpecialNovaSecurityGroupForm( $securityGroupInfo, 'openstackmanager-novasecuritygroup' );
 164+ $securityGroupForm->setTitle( SpecialPage::getTitleFor( 'NovaSecurityGroup' ) );
 165+ $securityGroupForm->setSubmitID( 'novainstance-form-deletesecuritygroupsubmit' );
 166+ $securityGroupForm->setSubmitCallback( array( $this, 'tryDeleteSubmit' ) );
 167+ $securityGroupForm->setSubmitText( 'confirm' );
 168+ $securityGroupForm->show();
 169+
 170+ return true;
 171+ }
 172+
 173+ function listSecurityGroups() {
 174+ global $wgOut, $wgUser;
 175+
 176+ $this->setHeaders();
 177+ $wgOut->setPagetitle( wfMsg( 'openstackmanager-securitygrouplist' ) );
 178+
 179+ $userProjects = $this->userLDAP->getProjects();
 180+ $sk = $wgUser->getSkin();
 181+ $out = '';
 182+ $groupheader = Html::element( 'th', array(), wfMsg( 'openstackmanager-securitygroupname' ) );
 183+ $groupheader .= Html::element( 'th', array(), wfMsg( 'openstackmanager-securitygroupdescription' ) );
 184+ $groupheader .= Html::element( 'th', array(), wfMsg( 'openstackmanager-securitygrouprule' ) );
 185+ $groupheader .= Html::element( 'th', array(), wfMsg( 'openstackmanager-actions' ) );
 186+ $ruleheader = Html::element( 'th', array(), wfMsg( 'openstackmanager-securitygrouprule-fromport' ) );
 187+ $ruleheader .= Html::element( 'th', array(), wfMsg( 'openstackmanager-securitygrouprule-toport' ) );
 188+ $ruleheader .= Html::element( 'th', array(), wfMsg( 'openstackmanager-securitygrouprule-protocol' ) );
 189+ $ruleheader .= Html::element( 'th', array(), wfMsg( 'openstackmanager-securitygrouprule-ipranges' ) );
 190+ $ruleheader .= Html::element( 'th', array(), wfMsg( 'openstackmanager-securitygrouprule-groups' ) );
 191+ $ruleheader .= Html::element( 'th', array(), wfMsg( 'openstackmanager-actions' ) );
 192+ $projectArr = array();
 193+ $securityGroups = $this->adminNova->getSecurityGroups();
 194+ foreach ( $securityGroups as $group ) {
 195+ $project = $group->getOwner();
 196+ if ( ! in_array( $project, $userProjects ) ) {
 197+ continue;
 198+ }
 199+ $groupname = $group->getGroupName();
 200+ $groupOut = Html::element( 'td', array(), $groupname );
 201+ $groupOut .= Html::element( 'td', array(), $group->getGroupDescription() );
 202+ # Add rules
 203+ $rules = $group->getRules();
 204+ if ( $rules ) {
 205+ $rulesOut = $ruleheader;
 206+ foreach ( $rules as $rule ) {
 207+ $fromport = $rule->getFromPort();
 208+ $toport = $rule->getToPort();
 209+ $ipprotocol = $rule->getIPProtocol();
 210+ $ruleOut = Html::element( 'td', array(), $fromport );
 211+ $ruleOut .= Html::element( 'td', array(), $toport );
 212+ $ruleOut .= Html::element( 'td', array(), $ipprotocol );
 213+ $ranges = $rule->getIPRanges();
 214+ if ( $ranges ) {
 215+ $rangesOut = '';
 216+ foreach ( $ranges as $range ) {
 217+ $rangesOut .= Html::element( 'li', array(), $range );
 218+ }
 219+ $rangesOut = Html::rawElement( 'ul', array(), $rangesOut );
 220+ $ruleOut .= Html::rawElement( 'td', array(), $rangesOut );
 221+ } else {
 222+ $ruleOut .= Html::rawElement( 'td', array(), '' );
 223+ }
 224+ $sourcegroups = $rule->getGroups();
 225+ $groupinfo = array();
 226+ if ( $sourcegroups ) {
 227+ $sourcegroupsOut = '';
 228+ foreach ( $sourcegroups as $sourcegroup ) {
 229+ $groupinfo[] = $sourcegroup['groupname'] . ':' . $sourcegroup['project'];
 230+ $sourcegroupinfo = $sourcegroup['groupname'] . ' (' . $sourcegroup['project'] . ')';
 231+ $sourcegroupsOut .= Html::element( 'li', array(), $sourcegroupinfo );
 232+ }
 233+ $sourcegroupsOut = Html::rawElement( 'ul', array(), $sourcegroupsOut );
 234+ $ruleOut .= Html::rawElement( 'td', array(), $sourcegroupsOut );
 235+ } else {
 236+ $ruleOut .= Html::rawElement( 'td', array(), '' );
 237+ }
 238+ #TODO: Add actions
 239+ $msg = wfMsg( 'openstackmanager-removerule-action' );
 240+ $args = array( 'action' => 'removerule',
 241+ 'project' => $project,
 242+ 'groupname' => $groupname,
 243+ 'fromport' => $fromport,
 244+ 'toport' => $toport,
 245+ 'protocol' => $ipprotocol,
 246+ 'ranges' => implode( ',', $ranges ),
 247+ 'groups' => implode( ',', $groupinfo ) );
 248+ $link = $sk->link( $this->getTitle(), $msg, array(), $args, array() );
 249+ $actions = Html::rawElement( 'li', array(), $link );
 250+ $actions = Html::rawElement( 'ul', array(), $actions );
 251+ $ruleOut .= Html::rawElement( 'td', array(), $actions );
 252+ $rulesOut .= Html::rawElement( 'tr', array(), $ruleOut );
 253+ }
 254+ $rulesOut = Html::rawElement( 'table', array( 'id' => 'novasecuritygrouplist', 'class' => 'wikitable' ), $rulesOut );
 255+ $groupOut .= Html::rawElement( 'td', array(), $rulesOut );
 256+ } else {
 257+ $groupOut .= Html::rawElement( 'td', array(), '' );
 258+ }
 259+ $msg = wfMsg( 'openstackmanager-delete' );
 260+ $link = $sk->link( $this->getTitle(), $msg, array(),
 261+ array( 'action' => 'delete',
 262+ 'project' => $project,
 263+ 'groupname' => $group->getGroupName() ),
 264+ array() );
 265+ $actions = Html::rawElement( 'li', array(), $link );
 266+ #$msg = wfMsg( 'openstackmanager-configure' );
 267+ #$link = $sk->link( $this->getTitle(), $msg, array(),
 268+ # array( 'action' => 'configure',
 269+ # 'project' => $project,
 270+ # 'groupname' => $group->getGroupName() ),
 271+ # array() );
 272+ #$actions .= Html::rawElement( 'li', array(), $link );
 273+ $msg = wfMsg( 'openstackmanager-addrule-action' );
 274+ $link = $sk->link( $this->getTitle(), $msg, array(),
 275+ array( 'action' => 'addrule',
 276+ 'project' => $project,
 277+ 'groupname' => $group->getGroupName() ),
 278+ array() );
 279+ $actions .= Html::rawElement( 'li', array(), $link );
 280+ $actions = Html::rawElement( 'ul', array(), $actions );
 281+ $groupOut .= Html::rawElement( 'td', array(), $actions );
 282+ if ( isset( $projectArr["$project"] ) ) {
 283+ $projectArr["$project"] .= Html::rawElement( 'tr', array(), $groupOut );
 284+ } else {
 285+ $projectArr["$project"] = Html::rawElement( 'tr', array(), $groupOut );
 286+ }
 287+ }
 288+ foreach ( $userProjects as $project ) {
 289+ $out .= Html::element( 'h2', array(), $project );
 290+ $out .= $sk->link( $this->getTitle(), wfMsg( 'openstackmanager-createnewsecuritygroup' ), array(),
 291+ array( 'action' => 'create', 'project' => $project ), array() );
 292+ if ( isset( $projectArr["$project"] ) ) {
 293+ $projectOut = $groupheader;
 294+ $projectOut .= $projectArr["$project"];
 295+ $out .= Html::rawElement( 'table',
 296+ array( 'id' => 'novainstancelist', 'class' => 'wikitable' ), $projectOut );
 297+ }
 298+ }
 299+
 300+ $wgOut->addHTML( $out );
 301+ return true;
 302+ }
 303+
 304+ function addRule() {
 305+ global $wgOut, $wgRequest;
 306+
 307+ $this->setHeaders();
 308+ $wgOut->setPagetitle( wfMsg( 'openstackmanager-addrule' ) );
 309+
 310+ $project = $wgRequest->getText( 'project' );
 311+ if ( ! $this->userLDAP->inRole( 'netadmin', $project ) ) {
 312+ $this->notInRole( 'netadmin' );
 313+ return false;
 314+ }
 315+ $group_keys = array();
 316+ $securityGroups = $this->adminNova->getSecurityGroups();
 317+ foreach ( $securityGroups as $securityGroup ) {
 318+ $securityGroupName = $securityGroup->getGroupName();
 319+ $securityGroupProject = $securityGroup->getOwner();
 320+ $group_keys["$securityGroupName"] = $securityGroupName . ':' . $securityGroupProject;
 321+ }
 322+ $securitygroupname = $wgRequest->getText( 'groupname' );
 323+ $securityGroupInfo = Array();
 324+ $securityGroupInfo['groupname'] = array(
 325+ 'type' => 'hidden',
 326+ 'default' => $securitygroupname,
 327+ );
 328+ $securityGroupInfo['project'] = array(
 329+ 'type' => 'hidden',
 330+ 'default' => $project,
 331+ );
 332+ $securityGroupInfo['fromport'] = array(
 333+ 'type' => 'text',
 334+ 'label-message' => 'openstackmanager-securitygrouprule-fromport',
 335+ 'default' => '',
 336+ );
 337+ $securityGroupInfo['toport'] = array(
 338+ 'type' => 'text',
 339+ 'label-message' => 'openstackmanager-securitygrouprule-toport',
 340+ 'default' => '',
 341+ );
 342+ $securityGroupInfo['protocol'] = array(
 343+ 'type' => 'select',
 344+ 'label-message' => 'openstackmanager-securitygrouprule-protocol',
 345+ 'options' => array( '' => '', 'icmp' => 'icmp', 'tcp' => 'tcp', 'udp' => 'udp' ),
 346+ );
 347+ $securityGroupInfo['ranges'] = array(
 348+ 'type' => 'text',
 349+ 'label-message' => 'openstackmanager-securitygrouprule-ranges',
 350+ 'help-message' => 'openstackmanager-securitygrouprule-ranges-help',
 351+ 'default' => '',
 352+ );
 353+ $securityGroupInfo['groups'] = array(
 354+ 'type' => 'multiselect',
 355+ 'label-message' => 'openstackmanager-securitygrouprule-groups',
 356+ 'help-message' => 'openstackmanager-securitygrouprule-groups-help',
 357+ 'options' => $group_keys,
 358+ );
 359+ $securityGroupInfo['action'] = array(
 360+ 'type' => 'hidden',
 361+ 'default' => 'addrule',
 362+ );
 363+ $securityGroupForm = new SpecialNovaSecurityGroupForm( $securityGroupInfo, 'openstackmanager-novasecuritygroup' );
 364+ $securityGroupForm->setTitle( SpecialPage::getTitleFor( 'NovaSecurityGroup' ) );
 365+ $securityGroupForm->setSubmitID( 'novainstance-form-removerulesubmit' );
 366+ $securityGroupForm->setSubmitCallback( array( $this, 'tryAddRuleSubmit' ) );
 367+ $securityGroupForm->show();
 368+
 369+ return true;
 370+ }
 371+
 372+ function removeRule() {
 373+ global $wgOut, $wgRequest;
 374+
 375+ $this->setHeaders();
 376+ $wgOut->setPagetitle( wfMsg( 'openstackmanager-removerule' ) );
 377+
 378+ $project = $wgRequest->getText( 'project' );
 379+ if ( ! $this->userLDAP->inRole( 'netadmin', $project ) ) {
 380+ $this->notInRole( 'netadmin' );
 381+ return false;
 382+ }
 383+ $securitygroupname = $wgRequest->getText( 'groupname' );
 384+ if ( ! $wgRequest->wasPosted() ) {
 385+ $out = Html::element( 'p', array(), wfMsgExt( 'openstackmanager-removerule-confirm', array(), $securitygroupname ) );
 386+ $wgOut->addHTML( $out );
 387+ }
 388+ $securityGroupInfo = Array();
 389+ $securityGroupInfo['groupname'] = array(
 390+ 'type' => 'hidden',
 391+ 'default' => $securitygroupname,
 392+ );
 393+ $securityGroupInfo['project'] = array(
 394+ 'type' => 'hidden',
 395+ 'default' => $project,
 396+ );
 397+ $securityGroupInfo['fromport'] = array(
 398+ 'type' => 'hidden',
 399+ 'default' => $wgRequest->getText( 'fromport' ),
 400+ );
 401+ $securityGroupInfo['toport'] = array(
 402+ 'type' => 'hidden',
 403+ 'default' => $wgRequest->getText( 'toport' ),
 404+ );
 405+ $securityGroupInfo['protocol'] = array(
 406+ 'type' => 'hidden',
 407+ 'default' => $wgRequest->getText( 'protocol' ),
 408+ );
 409+ if ( $wgRequest->getText( 'ranges' ) ) {
 410+ $securityGroupInfo['ranges'] = array(
 411+ 'type' => 'hidden',
 412+ 'default' => $wgRequest->getText( 'ranges' ),
 413+ );
 414+ }
 415+ if ( $wgRequest->getText( 'groups' ) ) {
 416+ $securityGroupInfo['groups'] = array(
 417+ 'type' => 'hidden',
 418+ 'default' => $wgRequest->getText( 'groups' ),
 419+ );
 420+ }
 421+ $securityGroupInfo['action'] = array(
 422+ 'type' => 'hidden',
 423+ 'default' => 'removerule',
 424+ );
 425+ $securityGroupForm = new SpecialNovaSecurityGroupForm( $securityGroupInfo, 'openstackmanager-novasecuritygroup' );
 426+ $securityGroupForm->setTitle( SpecialPage::getTitleFor( 'NovaSecurityGroup' ) );
 427+ $securityGroupForm->setSubmitID( 'novainstance-form-removerulesubmit' );
 428+ $securityGroupForm->setSubmitCallback( array( $this, 'tryRemoveRuleSubmit' ) );
 429+ $securityGroupForm->setSubmitText( 'confirm' );
 430+ $securityGroupForm->show();
 431+
 432+ return true;
 433+ }
 434+
 435+ function tryCreateSubmit( $formData, $entryPoint = 'internal' ) {
 436+ global $wgOut, $wgUser;
 437+
 438+ $sk = $wgUser->getSkin();
 439+ $project = $formData['project'];
 440+ $groupname = $formData['groupname'];
 441+ $description = $formData['description'];
 442+ $userCredentials = $this->userLDAP->getCredentials( $project );
 443+ $this->userNova = new OpenStackNovaController( $userCredentials );
 444+ $securitygroup = $this->userNova->createSecurityGroup( $groupname, $description );
 445+ if ( $securitygroup ) {
 446+ $out = Html::element( 'p', array(), wfMsg( 'openstackmanager-createdsecuritygroup' ) );
 447+ } else {
 448+ $out = Html::element( 'p', array(), wfMsg( 'openstackmanager-createsecuritygroupfailed' ) );
 449+ }
 450+ $out .= $sk->link( $this->getTitle(), wfMsg( 'openstackmanager-backsecuritygrouplist' ), array(), array(), array() );
 451+
 452+ $wgOut->addHTML( $out );
 453+ return true;
 454+ }
 455+
 456+ function tryDeleteSubmit( $formData, $entryPoint = 'internal' ) {
 457+ global $wgOut, $wgUser;
 458+
 459+ $sk = $wgUser->getSkin();
 460+ $project = $formData['project'];
 461+ $userCredentials = $this->userLDAP->getCredentials( $project );
 462+ $this->userNova = new OpenStackNovaController( $userCredentials );
 463+ $securitygroup = $this->adminNova->getSecurityGroup( $formData['groupname'] );
 464+ if ( ! $securitygroup ) {
 465+ $out = Html::element( 'p', array(), wfMsg( 'openstackmanager-nonexistantsecuritygroup' ) );
 466+ return true;
 467+ }
 468+ $groupname = $securitygroup->getGroupName();
 469+ $success = $this->userNova->deleteSecurityGroup( $groupname );
 470+ if ( $success ) {
 471+ # TODO: Ensure group isn't being used
 472+ $out = Html::element( 'p', array(), wfMsg( 'openstackmanager-deletedsecuritygroup' ) );
 473+ } else {
 474+ $out = Html::element( 'p', array(), wfMsg( 'openstackmanager-deletesecuritygroupfailed' ) );
 475+ }
 476+ $out .= $sk->link( $this->getTitle(), wfMsg( 'openstackmanager-backsecuritygrouplist' ), array(), array(), array() );
 477+
 478+ $wgOut->addHTML( $out );
 479+ return true;
 480+ }
 481+
 482+ function tryConfigureSubmit( $formData, $entryPoint = 'internal' ) {
 483+ global $wgOut, $wgUser;
 484+ global $wgOpenStackManagerPuppetOptions;
 485+
 486+ $sk = $wgUser->getSkin();
 487+ $groupname = $formData['groupname'];
 488+ $group = $this->adminNova->getSecurityGroup( $groupname );
 489+ if ( $group ) {
 490+ # This isn't a supported function in the API for now. Leave this action out for now
 491+ $success = $this->userNova->modifySecurityGroup( $groupname, array( 'description' => $description )) ;
 492+ if ( $success ) {
 493+ $out = Html::element( 'p', array(), wfMsg( 'openstackmanager-modifiedgroup' ) );
 494+ } else {
 495+ $out = Html::element( 'p', array(), wfMsg( 'openstackmanager-modifygroupfailed' ) );
 496+ }
 497+ } else {
 498+ $out = Html::element( 'p', array(), wfMsg( 'openstackmanager-nonexistantgroup' ) );
 499+ }
 500+ $out .= $sk->link( $this->getTitle(), wfMsg( 'openstackmanager-backsecuritygrouplist' ), array(), array(), array() );
 501+
 502+ $wgOut->addHTML( $out );
 503+ return true;
 504+ }
 505+
 506+ function tryAddRuleSubmit( $formData, $entryPoint = 'internal' ) {
 507+ global $wgOut, $wgUser;
 508+
 509+ $sk = $wgUser->getSkin();
 510+ $project = $formData['project'];
 511+ $fromport = $formData['fromport'];
 512+ $toport = $formData['toport'];
 513+ $protocol = $formData['protocol'];
 514+ if ( isset( $formData['ranges'] ) && $formData['ranges'] ) {
 515+ $ranges = explode( ',', $formData['ranges'] );
 516+ } else {
 517+ $ranges = array();
 518+ }
 519+ $groups = array();
 520+ foreach ( $formData['groups'] as $group ) {
 521+ $group = explode( ':', $group );
 522+ $groups[] = array( 'groupname' => $group[0], 'project' => $group[1] );
 523+ }
 524+ $userCredentials = $this->userLDAP->getCredentials( $project );
 525+ $this->userNova = new OpenStackNovaController( $userCredentials );
 526+ $securitygroup = $this->adminNova->getSecurityGroup( $formData['groupname'] );
 527+ if ( ! $securitygroup ) {
 528+ $out = Html::element( 'p', array(), wfMsg( 'openstackmanager-nonexistantsecuritygroup' ) );
 529+ return false;
 530+ }
 531+ $groupname = $securitygroup->getGroupName();
 532+ $success = $this->userNova->addSecurityGroupRule( $groupname, $fromport, $toport, $protocol, $ranges, $groups );
 533+ if ( $success ) {
 534+ # TODO: Ensure group isn't being used
 535+ $out = Html::element( 'p', array(), wfMsg( 'openstackmanager-addedrule' ) );
 536+ } else {
 537+ $out = Html::element( 'p', array(), wfMsg( 'openstackmanager-addrulefailed' ) );
 538+ }
 539+ $out .= $sk->link( $this->getTitle(), wfMsg( 'openstackmanager-backsecuritygrouplist' ), array(), array(), array() );
 540+
 541+ $wgOut->addHTML( $out );
 542+ return true;
 543+ }
 544+
 545+ function tryRemoveRuleSubmit( $formData, $entryPoint = 'internal' ) {
 546+ global $wgOut, $wgUser;
 547+
 548+ $sk = $wgUser->getSkin();
 549+ $project = $formData['project'];
 550+ $fromport = $formData['fromport'];
 551+ $toport = $formData['toport'];
 552+ $protocol = $formData['protocol'];
 553+ if ( isset( $formData['ranges'] ) ) {
 554+ $ranges = explode( ',', $formData['ranges'] );
 555+ } else {
 556+ $ranges = array();
 557+ }
 558+ $groups = array();
 559+ if ( isset( $formData['groups'] ) ) {
 560+ $rawgroups = explode( ',', $formData['groups'] );
 561+ foreach ( $rawgroups as $rawgroup ) {
 562+ $rawgroup = explode( ':', $rawgroup );
 563+ $groups[] = array( 'groupname' => $rawgroup[0], 'project' => $rawgroup[1] );
 564+ }
 565+ }
 566+ $userCredentials = $this->userLDAP->getCredentials( $project );
 567+ $this->userNova = new OpenStackNovaController( $userCredentials );
 568+ $securitygroup = $this->adminNova->getSecurityGroup( $formData['groupname'] );
 569+ if ( ! $securitygroup ) {
 570+ $out = Html::element( 'p', array(), wfMsg( 'openstackmanager-nonexistantsecuritygroup' ) );
 571+ return false;
 572+ }
 573+ $groupname = $securitygroup->getGroupName();
 574+ $success = $this->userNova->removeSecurityGroupRule( $groupname, $fromport, $toport, $protocol, $ranges, $groups );
 575+ if ( $success ) {
 576+ # TODO: Ensure group isn't being used
 577+ $out = Html::element( 'p', array(), wfMsg( 'openstackmanager-removedrule' ) );
 578+ } else {
 579+ $out = Html::element( 'p', array(), wfMsg( 'openstackmanager-removerulefailed' ) );
 580+ }
 581+ $out .= $sk->link( $this->getTitle(), wfMsg( 'openstackmanager-backsecuritygrouplist' ), array(), array(), array() );
 582+
 583+ $wgOut->addHTML( $out );
 584+ return true;
 585+ }
 586+
 587+ function validateInstanceName( $instancename, $alldata ) {
 588+ if ( ! preg_match( "/^[a-z][a-z0-9\-]*$/", $instancename ) ) {
 589+ return Xml::element( 'span', array( 'class' => 'error' ), wfMsg( 'openstackmanager-badinstancename' ) );
 590+ } else {
 591+ return true;
 592+ }
 593+ }
 594+
 595+}
 596+
 597+class SpecialNovaSecurityGroupForm extends HTMLForm {
 598+}
Property changes on: trunk/extensions/OpenStackManager/special/SpecialNovaSecurityGroup.php
___________________________________________________________________
Added: svn:eol-style
1599 + native
Index: trunk/extensions/OpenStackManager/special/SpecialNovaAddress.php
@@ -412,7 +412,7 @@
413413 if ( ! $address ) {
414414 $out = Html::element( 'p', array(), wfMsg( 'openstackmanager-allocateaddressfailed' ) );
415415 $wgOut->addHTML( $out );
416 - return false;
 416+ return true;
417417 }
418418 $ip = $address->getPublicIP();
419419 $out = Html::element( 'p', array(), wfMsgExt( 'openstackmanager-allocatedaddress' , array(), $ip ) );
@@ -435,13 +435,13 @@
436436 if ( $hosts ) {
437437 $out = Html::element( 'p', array(), wfMsgExt( 'openstackmanager-cannotreleaseaddress', array(), $ip ) );
438438 $wgOut->addHTML( $out );
439 - return false;
 439+ return true;
440440 }
441441 $address = $this->adminNova->getAddress( $ip );
442442 if ( $address->getInstanceId() ) {
443443 $out = Html::element( 'p', array(), wfMsgExt( 'openstackmanager-cannotreleaseaddress', array(), $ip ) );
444444 $wgOut->addHTML( $out );
445 - return false;
 445+ return true;
446446 }
447447 $success = $this->userNova->releaseAddress( $ip );
448448 if ( $success ) {
@@ -503,12 +503,12 @@
504504 if ( ! $address ) {
505505 $out = Html::element( 'p', array(), wfMsgExt( 'openstackmanager-invalidaddress', array(), $ip ) );
506506 $wgOut->addHTML( $out );
507 - return false;
 507+ return true;
508508 }
509509 if ( $address->getProject() != $project ) {
510510 $out = Html::element( 'p', array(), wfMsgExt( 'openstackmanager-invalidaddressforproject', array(), $ip ) );
511511 $wgOut->addHTML( $out );
512 - return false;
 512+ return true;
513513 }
514514 $hostname = $formData['hostname'];
515515 $domain = $formData['domain'];
@@ -556,12 +556,12 @@
557557 if ( ! $address ) {
558558 $out = Html::element( 'p', array(), wfMsgExt( 'openstackmanager-invalidaddress', array(), $ip ) );
559559 $wgOut->addHTML( $out );
560 - return false;
 560+ return true;
561561 }
562562 if ( $address->getProject() != $project ) {
563563 $out = Html::element( 'p', array(), wfMsgExt( 'openstackmanager-invalidaddressforproject', array(), $ip ) );
564564 $wgOut->addHTML( $out );
565 - return false;
 565+ return true;
566566 }
567567 $hostname = $formData['hostname'];
568568 $domain = $formData['domain'];
Index: trunk/extensions/OpenStackManager/special/SpecialNovaProject.php
@@ -220,7 +220,7 @@
221221 if ( ! $success ) {
222222 $out = Html::element( 'p', array(), wfMsg( 'openstackmanager-createprojectfailed' ) );
223223 $wgOut->addHTML( $out );
224 - return false;
 224+ return true;
225225 }
226226 $out = Html::element( 'p', array(), wfMsg( 'openstackmanager-createdproject' ) );
227227 $out .= '<br />';
Index: trunk/extensions/OpenStackManager/special/SpecialNovaDomain.php
@@ -151,7 +151,7 @@
152152 if ( ! $success ) {
153153 $out = Html::element( 'p', array(), wfMsg( 'openstackmanager-createdomainfailed' ) );
154154 $wgOut->addHTML( $out );
155 - return false;
 155+ return true;
156156 }
157157 $out = Html::element( 'p', array(), wfMsg( 'openstackmanager-createddomain' ) );
158158 $out .= '<br />';
Index: trunk/extensions/OpenStackManager/special/SpecialNovaKey.php
@@ -194,7 +194,7 @@
195195 if ( ! $success ) {
196196 $out = Html::element( 'p', array(), wfMsg( 'openstackmanager-keypairimportfailed' ) );
197197 $wgOut->addHTML( $out );
198 - return false;
 198+ return true;
199199 }
200200 $out = Html::element( 'p', array(), wfMsg( 'openstackmanager-keypairimported' ) );
201201 } else if ( $wgOpenStackManagerNovaKeypairStorage == 'nova' ) {
Index: trunk/extensions/OpenStackManager/OpenStackManager.i18n.php
@@ -28,6 +28,7 @@
2929 'novainstance' => 'Manage Instances',
3030 'novakey' => 'Manage your public SSH keys',
3131 'novaproject' => 'Manage OpenStack projects',
 32+ 'novasecuritygroup' => 'Manage Firewall Security Groups',
3233
3334 'openstackmanager-novadomain' => 'Nova Domain',
3435 'openstackmanager-novainstance' => 'Nova Instance',
@@ -174,6 +175,46 @@
175176 'openstackmanager-neednetadminrole' => 'Netadmin Role Required',
176177 'openstackmanager-neednetadminrole2' => 'You must be a member of the netadmin role to perform this action.',
177178
 179+ 'openstackmanager-createsecuritygroup' => 'Create Security Group',
 180+ 'openstackmanager-securitygroupname' => 'Security Group Name',
 181+ 'openstackmanager-securitygroupdescription' => 'Description',
 182+ 'openstackmanager-configuresecuritygroup' => 'Configure Security Group',
 183+ 'openstackmanager-deletesecuritygroup' => 'Delete Security Group',
 184+ 'openstackmanager-deletesecuritygroup-confirm' => 'Are you sure you would like to delete $1?',
 185+ 'openstackmanager-securitygrouplist' => 'Security Group List',
 186+ 'openstackmanager-securitygrouprule' => 'Rules',
 187+ 'openstackmanager-securitygrouprule-toport' => 'To Port',
 188+ 'openstackmanager-securitygrouprule-fromport' => 'From Port',
 189+ 'openstackmanager-securitygrouprule-protocol' => 'Protocol',
 190+ 'openstackmanager-securitygrouprule-ipranges' => 'CIDR Ranges',
 191+ 'openstackmanager-securitygrouprule-groups' => 'Source Group',
 192+ 'openstackmanager-createnewsecuritygroup' => 'Create a new security group',
 193+ 'openstackmanager-addrule-action' => 'add rule',
 194+ 'openstackmanager-removerule-action' => 'remove rule',
 195+ 'openstackmanager-modifiedgroup' => 'Successfully modified security group.',
 196+ 'openstackmanager-modifygroupfailed' => 'Failed to modify security group.',
 197+ 'openstackmanager-nonexistantgroup' => 'The security group requested does not exist.',
 198+ 'openstackmanager-backsecuritygrouplist' => 'Back to the security group list',
 199+ 'openstackmanager-createdsecuritygroup' => 'Successfully created security group.',
 200+ 'openstackmanager-createsecuritygroupfailed' => 'Failed to create security group.',
 201+ 'openstackmanager-nonexistantsecuritygroup' => 'The security group you are trying to delete does not exist.',
 202+ 'openstackmanager-deletedsecuritygroup' => 'Successfully deleted security group.',
 203+ 'openstackmanager-deletesecuritygroupfailed' => 'Failed to delete security group.',
 204+ 'openstackmanager-removerule' => 'Remove Rule',
 205+ 'openstackmanager-removerule-confirm' => 'Are you sure you would like to remove this rule from $1?',
 206+ 'openstackmanager-removedrule' => 'Successfully removed rule.',
 207+ 'openstackmanager-removerulefailed' => 'Failed to remove rule.',
 208+ 'openstackmanager-addrule' => 'Add Rule',
 209+ 'openstackmanager-securitygrouprule-fromport' => 'From Port',
 210+ 'openstackmanager-securitygrouprule-toport' => 'To Port',
 211+ 'openstackmanager-securitygrouprule-protocol' => 'Protocol',
 212+ 'openstackmanager-securitygrouprule-ranges' => 'CIDR Ranges',
 213+ 'openstackmanager-securitygrouprule-groups' => 'Security Groups',
 214+ 'openstackmanager-securitygrouprule-ranges-help' => 'CIDR Ranges is a comma separated list of ranges.',
 215+ 'openstackmanager-securitygrouprule-groups-help' => 'Instances in added security groups will be allowed ingress of all ports and protocols.',
 216+ 'openstackmanager-addedrule' => 'Successfully added rule.',
 217+ 'openstackmanager-addrulefailed' => 'Failed to add rule.',
 218+
178219 );
179220
180221 /** Message documentation (Message documentation)
Index: trunk/extensions/OpenStackManager/OpenStackNovaSecurityGroupRule.php
@@ -10,20 +10,20 @@
1111 }
1212
1313 function getToPort() {
14 - return $this->toPort;
 14+ return $this->rule->toPort;
1515 }
1616
1717 function getFromPort() {
18 - return $this->fromPort;
 18+ return $this->rule->fromPort;
1919 }
2020
2121 function getIPProtocol() {
22 - return $this->ipProtocol;
 22+ return $this->rule->ipProtocol;
2323 }
2424
2525 function getIPRanges() {
2626 $ranges = array();
27 - foreach ( $this->ipRanges as $iprange ) {
 27+ foreach ( $this->rule->ipRanges->item as $iprange ) {
2828 $ranges[] = $iprange->cidrIp;
2929 }
3030 return $ranges;
@@ -31,7 +31,7 @@
3232
3333 function getGroups() {
3434 $groups = array();
35 - foreach ( $this->groups as $group ) {
 35+ foreach ( $this->rule->groups->item as $group ) {
3636 $properties = array();
3737 $properties['groupname'] = $group->groupName;
3838 $properties['project'] = $group->userId;
Index: trunk/extensions/OpenStackManager/OpenStackNovaController.php
@@ -5,7 +5,7 @@
66
77 var $novaConnection;
88 var $instances, $images, $keypairs, $availabilityZones;
9 - var $addresses;
 9+ var $addresses, $securityGroups;
1010
1111 var $instanceTypes = array( 'm1.tiny', 'm1.small', 'm1.large', 'm1.xlarge', 'm2.xlarge', 'm2.2xlarge',
1212 'm2.4xlarge', 'c1.medium', 'c1.xlarge', 'cc1.4xlarge' );
@@ -106,6 +106,27 @@
107107 return $this->availabilityZones;
108108 }
109109
 110+ function getSecurityGroup( $groupname ) {
 111+ $this->getSecurityGroups();
 112+ if ( isset( $this->securityGroups["$groupname"] ) ) {
 113+ return $this->securityGroups["$groupname"];
 114+ } else {
 115+ return null;
 116+ }
 117+ }
 118+
 119+ function getSecurityGroups() {
 120+ $this->securityGroups = array();
 121+ $securityGroups = $this->novaConnection->describe_security_groups();
 122+ $securityGroups = $securityGroups->body->securityGroupInfo->item;
 123+ foreach ( $securityGroups as $securityGroup ) {
 124+ $securityGroup = new OpenStackNovaSecurityGroup( $securityGroup );
 125+ $groupname = $securityGroup->getGroupName();
 126+ $this->securityGroups["$groupname"] = $securityGroup;
 127+ }
 128+ return $this->securityGroups;
 129+ }
 130+
110131 function createInstance( $instanceName, $image, $key, $instanceType, $availabilityZone ) {
111132 # 1, 1 is min and max number of instances to create.
112133 # We never want to make more than one at a time.
@@ -133,6 +154,91 @@
134155 return $response->isOK();
135156 }
136157
 158+ function createSecurityGroup( $groupname, $description ) {
 159+ $response = $this->novaConnection->create_security_group( $groupname, $description );
 160+ if ( ! $response->isOK() ) {
 161+ return null;
 162+ }
 163+ $securityGroup = new OpenStackNovaSecurityGroup( $response->body->securityGroupSet->item );
 164+ $groupname = $securityGroup->getGroupName();
 165+ $this->securityGroups["$groupname"] = $securityGroup;
 166+
 167+ return $securityGroup;
 168+ }
 169+
 170+ function deleteSecurityGroup( $groupname ) {
 171+ $response = $this->novaConnection->delete_security_group( $groupname );
 172+
 173+ return $response->isOK();
 174+ }
 175+
 176+ function addSecurityGroupRule( $groupname, $fromport='', $toport='', $protocol='', $ranges=array(), $groups=array() ) {
 177+ # TODO: Currently this method had commented out sections that use the AWS SDK
 178+ # recommended method of adding security group rules. When lp704645 is fixed, switch
 179+ # to using this method.
 180+ $rule = array();
 181+ if ( $fromport ) {
 182+ $rule['FromPort'] = $fromport;
 183+ }
 184+ if ( $toport ) {
 185+ $rule['ToPort'] = $toport;
 186+ }
 187+ if ( $protocol ) {
 188+ $rule['IpProtocol'] = $protocol;
 189+ }
 190+ if ( $ranges ) {
 191+ foreach ( $ranges as $range ) {
 192+ #$rule['IpRanges'][] = array( 'CidrIp' => $range );
 193+ $rule['CidrIp'] = $range;
 194+ }
 195+ }
 196+ if ( $groups ) {
 197+ foreach ( $groups as $group ) {
 198+ #$rule['Groups'][] = array( 'GroupName' => $group['groupname'], 'UserId' => $group['project'] );
 199+ $rule['SourceSecurityGroupName'] = $group['groupname'];
 200+ $rule['SourceSecurityGroupOwnerId'] = $group['project'];
 201+ }
 202+ }
 203+ #$permissions = array( 'IpPermissions' => array( $rule ) );
 204+ #$response = $this->novaConnection->authorize_security_group_ingress( $groupname, $permissions );
 205+ $response = $this->novaConnection->authorize_security_group_ingress( $groupname, $rule );
 206+
 207+ return $response->isOK();
 208+ }
 209+
 210+ function removeSecurityGroupRule( $groupname, $fromport='', $toport='', $protocol='', $ranges=array(), $groups=array() ) {
 211+ # TODO: Currently this method had commented out sections that use the AWS SDK
 212+ # recommended method of removing security group rules. When lp704645 is fixed, switch
 213+ # to using this method.
 214+ $rule = array();
 215+ if ( $fromport ) {
 216+ $rule['FromPort'] = $fromport;
 217+ }
 218+ if ( $toport ) {
 219+ $rule['ToPort'] = $toport;
 220+ }
 221+ if ( $protocol ) {
 222+ $rule['IpProtocol'] = $protocol;
 223+ }
 224+ if ( $ranges ) {
 225+ foreach ( $ranges as $range ) {
 226+ #$rule['IpRanges'][] = array( 'CidrIp' => $range );
 227+ $rule['CidrIp'] = $range;
 228+ }
 229+ }
 230+ if ( $groups ) {
 231+ foreach ( $groups as $group ) {
 232+ #$rule['Groups'][] = array( 'GroupName' => $group['groupname'], 'UserId' => $group['project'] );
 233+ $rule['SourceSecurityGroupName'] = $group['groupname'];
 234+ $rule['SourceSecurityGroupOwnerId'] = $group['project'];
 235+ }
 236+ }
 237+ #$permissions = array( 'IpPermissions' => array( $rule ) );
 238+ #$response = $this->novaConnection->revoke_security_group_ingress( $groupname, $permissions );
 239+ $response = $this->novaConnection->revoke_security_group_ingress( $groupname, $rule );
 240+ return $response->isOK();
 241+ }
 242+
137243 function importKeyPair( $keyName, $key ) {
138244 $response = $this->novaConnection->import_key_pair( $keyName, $key );
139245
Index: trunk/extensions/OpenStackManager/OpenStackNovaSecurityGroup.php
@@ -9,7 +9,7 @@
1010 function __construct( $apiInstanceResponse ) {
1111 $this->group = $apiInstanceResponse;
1212 $this->rules = array();
13 - foreach ( $this->group->ipPermissions as $permission ) {
 13+ foreach ( $this->group->ipPermissions->item as $permission ) {
1414 $this->rules[] = new OpenStackNovaSecurityGroupRule( $permission );
1515 }
1616 }
Index: trunk/extensions/OpenStackManager/OpenStackManager.php
@@ -21,7 +21,7 @@
2222 'path' => __FILE__,
2323 'name' => 'OpenStackManager',
2424 'author' => 'Ryan Lane',
25 - 'version' => '0.6',
 25+ 'version' => '0.7',
2626 'url' => 'http://mediawiki.org/wiki/Extension:OpenStackManager',
2727 'descriptionmsg' => 'openstackmanager-desc',
2828 );
@@ -73,11 +73,14 @@
7474 $wgAutoloadClasses['OpenStackNovaDomain'] = $dir . 'OpenStackNovaDomain.php';
7575 $wgAutoloadClasses['OpenStackNovaHost'] = $dir . 'OpenStackNovaHost.php';
7676 $wgAutoloadClasses['OpenStackNovaAddress'] = $dir . 'OpenStackNovaAddress.php';
 77+$wgAutoloadClasses['OpenStackNovaSecurityGroup'] = $dir . 'OpenStackNovaSecurityGroup.php';
 78+$wgAutoloadClasses['OpenStackNovaSecurityGroupRule'] = $dir . 'OpenStackNovaSecurityGroupRule.php';
7779 $wgAutoloadClasses['SpecialNovaInstance'] = $dir . 'special/SpecialNovaInstance.php';
7880 $wgAutoloadClasses['SpecialNovaKey'] = $dir . 'special/SpecialNovaKey.php';
7981 $wgAutoloadClasses['SpecialNovaProject'] = $dir . 'special/SpecialNovaProject.php';
8082 $wgAutoloadClasses['SpecialNovaDomain'] = $dir . 'special/SpecialNovaDomain.php';
8183 $wgAutoloadClasses['SpecialNovaAddress'] = $dir . 'special/SpecialNovaAddress.php';
 84+$wgAutoloadClasses['SpecialNovaSecurityGroup'] = $dir . 'special/SpecialNovaSecurityGroup.php';
8285 $wgAutoloadClasses['SpecialNova'] = $dir . 'special/SpecialNova.php';
8386 $wgAutoloadClasses['OpenStackNovaHostJob'] = $dir . 'OpenStackNovaHostJob.php';
8487 $wgAutoloadClasses['AmazonEC2'] = $dir . 'aws-sdk/sdk.class.php';
@@ -91,6 +94,8 @@
9295 $wgSpecialPageGroups['NovaDomain'] = 'nova';
9396 $wgSpecialPages['NovaAddress'] = 'SpecialNovaAddress';
9497 $wgSpecialPageGroups['NovaAddress'] = 'nova';
 98+$wgSpecialPages['NovaSecurityGroup'] = 'SpecialNovaSecurityGroup';
 99+$wgSpecialPageGroups['NovaSecurityGroup'] = 'nova';
95100 $wgJobClasses['addDNSHostToLDAP'] = 'OpenStackNovaHostJob';
96101
97102 $wgHooks['LDAPSetCreationValues'][] = 'OpenStackNovaUser::LDAPSetCreationValues';

Status & tagging log