r107036 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r107035‎ | r107036 | r107037 >
Date:02:30, 22 December 2011
Author:laner
Status:ok (Comments)
Tags:openstack 
Comment:
Adding support for managing puppet classes and variables through the interface, rather than LocalSettings.php. Resolves bug 32221 and bug 32222.
Modified paths:
  • /trunk/extensions/OpenStackManager/OpenStackManager.i18n.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackManager.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaPuppetGroup.php (added) (history)
  • /trunk/extensions/OpenStackManager/openstack.sql (added) (history)
  • /trunk/extensions/OpenStackManager/special/SpecialNovaInstance.php (modified) (history)
  • /trunk/extensions/OpenStackManager/special/SpecialNovaPuppetGroup.php (added) (history)

Diff [purge]

Index: trunk/extensions/OpenStackManager/special/SpecialNovaInstance.php
@@ -155,11 +155,14 @@
156156 }
157157 $image_keys["$imageLabel"] = $image->getImageId();
158158 }
 159+ if ( isset( $image_keys["$default"] ) ) {
 160+ $default = $image_keys["$default"];
 161+ }
159162 $instanceInfo['imageType'] = array(
160163 'type' => 'select',
161164 'section' => 'instance/info',
162165 'options' => $image_keys,
163 - 'default' => $image_keys["$default"],
 166+ 'default' => $default,
164167 'label-message' => 'openstackmanager-imagetype',
165168 'name' => 'imageType',
166169 );
@@ -216,30 +219,7 @@
217220 );
218221
219222 if ( $wgOpenStackManagerPuppetOptions['enabled'] ) {
220 - if ( $wgOpenStackManagerPuppetOptions['availableclasses'] ) {
221 - $classes = array();
222 - foreach ( $wgOpenStackManagerPuppetOptions['availableclasses'] as $class ) {
223 - $classes["$class"] = $class;
224 - }
225 - $instanceInfo['puppetclasses'] = array(
226 - 'type' => 'multiselect',
227 - 'section' => 'instance/puppetinfo',
228 - 'options' => $classes,
229 - 'label-message' => 'openstackmanager-puppetclasses',
230 - 'name' => 'puppetclasses',
231 - );
232 - }
233 -
234 - if ( $wgOpenStackManagerPuppetOptions['availablevariables'] ) {
235 - foreach ( $wgOpenStackManagerPuppetOptions['availablevariables'] as $variable ) {
236 - $instanceInfo["$variable"] = array(
237 - 'type' => 'text',
238 - 'section' => 'instance/puppetinfo',
239 - 'label' => $variable,
240 - 'name' => "$variable",
241 - );
242 - }
243 - }
 223+ $this->setPuppetInfo( $instanceInfo );
244224 }
245225
246226 $instanceInfo['action'] = array(
@@ -293,40 +273,7 @@
294274 }
295275 $puppetinfo = $host->getPuppetConfiguration();
296276
297 - if ( $wgOpenStackManagerPuppetOptions['availableclasses'] ) {
298 - $classes = array();
299 - $defaults = array();
300 - foreach ( $wgOpenStackManagerPuppetOptions['availableclasses'] as $class ) {
301 - $classes["$class"] = $class;
302 - if ( in_array( $class, $puppetinfo['puppetclass'] ) ) {
303 - $defaults["$class"] = $class;
304 - }
305 - }
306 - $instanceInfo['puppetclasses'] = array(
307 - 'type' => 'multiselect',
308 - 'section' => 'instance/puppetinfo',
309 - 'options' => $classes,
310 - 'default' => $defaults,
311 - 'label-message' => 'openstackmanager-puppetclasses',
312 - 'name' => 'puppetclasses',
313 - );
314 - }
315 -
316 - if ( $wgOpenStackManagerPuppetOptions['availablevariables'] ) {
317 - foreach ( $wgOpenStackManagerPuppetOptions['availablevariables'] as $variable ) {
318 - $default = '';
319 - if ( array_key_exists( $variable, $puppetinfo['puppetvar'] ) ) {
320 - $default = $puppetinfo['puppetvar']["$variable"];
321 - }
322 - $instanceInfo["$variable"] = array(
323 - 'type' => 'text',
324 - 'section' => 'instance/puppetinfo',
325 - 'label' => $variable,
326 - 'default' => $default,
327 - 'name' => "$variable",
328 - );
329 - }
330 - }
 277+ $this->setPuppetInfo( $instanceInfo, $puppetinfo );
331278 }
332279
333280 $instanceInfo['action'] = array(
@@ -344,6 +291,48 @@
345292 return true;
346293 }
347294
 295+ function setPuppetInfo( &$instanceInfo, $puppetinfo=array() ) {
 296+ $puppetGroups = OpenStackNovaPuppetGroup::getGroupList();
 297+ foreach ( $puppetGroups as $puppetGroup ) {
 298+ $classes = array();
 299+ $defaults = array();
 300+ $puppetgroupname = $puppetGroup->getName();
 301+ foreach ( $puppetGroup->getClasses() as $class ) {
 302+ $classname = $class["name"];
 303+ $classes["$classname"] = $classname;
 304+ if ( $puppetinfo && in_array( $classname, $puppetinfo['puppetclass'] ) ) {
 305+ $defaults["$classname"] = $classname;
 306+ }
 307+ }
 308+ $instanceInfo["${puppetgroupname}"] = array(
 309+ 'type' => 'info',
 310+ 'section' => "instance/puppetinfo",
 311+ 'label' => Html::element( 'h3', array(), "$puppetgroupname:" ),
 312+ );
 313+ $instanceInfo["${puppetgroupname}-puppetclasses"] = array(
 314+ 'type' => 'multiselect',
 315+ 'section' => "instance/puppetinfo",
 316+ 'options' => $classes,
 317+ 'default' => $defaults,
 318+ 'name' => "${puppetgroupname}-puppetclasses",
 319+ );
 320+ foreach ( $puppetGroup->getVars() as $variable ) {
 321+ $variablename = $variable["name"];
 322+ $default = '';
 323+ if ( $puppetinfo && array_key_exists( $variablename, $puppetinfo['puppetvar'] ) ) {
 324+ $default = $puppetinfo['puppetvar']["$variablename"];
 325+ }
 326+ $instanceInfo["${puppetgroupname}-${variablename}"] = array(
 327+ 'type' => 'text',
 328+ 'section' => "instance/puppetinfo",
 329+ 'label' => $variablename,
 330+ 'default' => $default,
 331+ 'name' => "${puppetgroupname}-${variablename}",
 332+ );
 333+ }
 334+ }
 335+ }
 336+
348337 /**
349338 * @return bool
350339 */
@@ -569,20 +558,7 @@
570559 }
571560 $instance = $this->userNova->createInstance( $formData['instancename'], $formData['imageType'], '', $formData['instanceType'], $formData['availabilityZone'], $formData['groups'] );
572561 if ( $instance ) {
573 - $puppetinfo = array();
574 - if ( $wgOpenStackManagerPuppetOptions['enabled'] ) {
575 - foreach ( $formData['puppetclasses'] as $class ) {
576 - if ( in_array( $class, $wgOpenStackManagerPuppetOptions['availableclasses'] ) ) {
577 - $puppetinfo['classes'][] = $class;
578 - }
579 - }
580 - foreach ( $wgOpenStackManagerPuppetOptions['availablevariables'] as $variable ) {
581 - if ( isset ( $formData["$variable"] ) ) {
582 - $puppetinfo['variables']["$variable"] = $formData["$variable"];
583 - }
584 - }
585 - }
586 - $host = OpenStackNovaHost::addHost( $instance, $domain, $puppetinfo );
 562+ $host = OpenStackNovaHost::addHost( $instance, $domain, $this->getPuppetInfo( $formData ) );
587563
588564 if ( $host ) {
589565 $title = Title::newFromText( $wgOut->getPageTitle() );
@@ -674,20 +650,7 @@
675651 $instance = $this->adminNova->getInstance( $formData['instanceid'] );
676652 $host = $instance->getHost();
677653 if ( $host ) {
678 - $puppetinfo = array();
679 - if ( $wgOpenStackManagerPuppetOptions['enabled'] ) {
680 - foreach ( $formData['puppetclasses'] as $class ) {
681 - if ( in_array( $class, $wgOpenStackManagerPuppetOptions['availableclasses'] ) ) {
682 - $puppetinfo['classes'][] = $class;
683 - }
684 - }
685 - foreach ( $wgOpenStackManagerPuppetOptions['availablevariables'] as $variable ) {
686 - if ( isset ( $formData["$variable"] ) ) {
687 - $puppetinfo['variables']["$variable"] = $formData["$variable"];
688 - }
689 - }
690 - }
691 - $success = $host->modifyPuppetConfiguration( $puppetinfo );
 654+ $success = $host->modifyPuppetConfiguration( $this->getPuppetInfo( $formData ) );
692655 if ( $success ) {
693656 $instance->editArticle();
694657 $wgOut->addWikiMsg( 'openstackmanager-modifiedinstance' );
@@ -704,6 +667,30 @@
705668 $wgOut->addHTML( $out );
706669 return true;
707670 }
 671+
 672+ function getPuppetInfo( $formData ) {
 673+ global $wgOpenStackManagerPuppetOptions;
 674+
 675+ $puppetinfo = array();
 676+ if ( $wgOpenStackManagerPuppetOptions['enabled'] ) {
 677+ $puppetGroups = OpenStackNovaPuppetGroup::getGroupList();
 678+ foreach ( $puppetGroups as $puppetGroup ) {
 679+ $puppetgroupname = $puppetGroup->getName();
 680+ foreach ( $puppetGroup->getClasses() as $class ) {
 681+ if ( in_array( $class["name"], $formData["$puppetgroupname-puppetclasses"] ) ) {
 682+ $puppetinfo['classes'][] = $class["name"];
 683+ }
 684+ }
 685+ foreach ( $puppetGroup->getVars() as $variable ) {
 686+ $variablename = $variable["name"];
 687+ if ( isset ( $formData["$puppetgroupname-$variablename"] ) && trim( $formData["$puppetgroupname-$variablename"] ) ) {
 688+ $puppetinfo['variables']["$variablename"] = $formData["$puppetgroupname-$variablename"];
 689+ }
 690+ }
 691+ }
 692+ }
 693+ return $puppetinfo;
 694+ }
708695 }
709696
710697 class SpecialNovaInstanceForm extends HTMLForm {
Index: trunk/extensions/OpenStackManager/special/SpecialNovaPuppetGroup.php
@@ -0,0 +1,704 @@
 2+<?php
 3+class SpecialNovaPuppetGroup extends SpecialNova {
 4+
 5+ function __construct() {
 6+ parent::__construct( 'NovaPuppetGroup', 'manageproject' );
 7+ }
 8+
 9+ function execute( $par ) {
 10+ global $wgRequest, $wgUser;
 11+
 12+ if ( ! $wgUser->isLoggedIn() ) {
 13+ $this->notLoggedIn();
 14+ return false;
 15+ }
 16+ $action = $wgRequest->getVal( 'action' );
 17+ if ( $action == "create" ) {
 18+ $this->createPuppetGroup();
 19+ } elseif ( $action == "delete" ) {
 20+ $this->deletePuppetGroup();
 21+ } elseif ( $action == "addvar" ) {
 22+ $this->addPuppetVar();
 23+ } elseif ( $action == "deletevar" ) {
 24+ $this->deletePuppetVar();
 25+ } elseif ( $action == "addclass" ) {
 26+ $this->addPuppetClass();
 27+ } elseif ( $action == "deleteclass" ) {
 28+ $this->deletePuppetClass();
 29+ } elseif ( $action == "modifyclass" ) {
 30+ $this->modifyPuppetClass();
 31+ } elseif ( $action == "modifyvar" ) {
 32+ $this->modifyPuppetVar();
 33+ } elseif ( $action == "modify" ) {
 34+ $this->modifyPuppetGroup();
 35+ } else {
 36+ $this->listPuppetGroups();
 37+ }
 38+ }
 39+
 40+ /**
 41+ * @return bool
 42+ */
 43+ function createPuppetGroup() {
 44+ global $wgOut, $wgUser;
 45+
 46+ $this->setHeaders();
 47+ if ( !$this->userCanExecute( $wgUser ) ) {
 48+ $this->displayRestrictionError();
 49+ return false;
 50+ }
 51+ $wgOut->setPagetitle( wfMsg( 'openstackmanager-createpuppetgroup' ) );
 52+
 53+ $puppetGroupInfo = array();
 54+ $puppetGroupInfo['puppetgroupname'] = array(
 55+ 'type' => 'text',
 56+ 'label-message' => 'openstackmanager-puppetgroupname',
 57+ 'validation-callback' => array( $this, 'validateText' ),
 58+ 'default' => '',
 59+ 'name' => 'puppetgroupname',
 60+ );
 61+ $puppetGroupInfo['puppetgroupposition'] = array(
 62+ 'type' => 'int',
 63+ 'label-message' => 'openstackmanager-puppetgroupposition',
 64+ 'default' => '',
 65+ 'name' => 'puppetgroupposition',
 66+ );
 67+
 68+ $puppetGroupInfo['action'] = array(
 69+ 'type' => 'hidden',
 70+ 'default' => 'create',
 71+ 'name' => 'action',
 72+ );
 73+
 74+ $puppetGroupForm = new SpecialNovaPuppetGroupForm( $puppetGroupInfo, 'openstackmanager-novapuppetgroup' );
 75+ $puppetGroupForm->setTitle( SpecialPage::getTitleFor( 'NovaPuppetGroup' ) );
 76+ $puppetGroupForm->setSubmitID( 'novapuppetgroup-form-createpuppetgroupsubmit' );
 77+ $puppetGroupForm->setSubmitCallback( array( $this, 'tryCreateSubmit' ) );
 78+ $puppetGroupForm->show();
 79+
 80+ return true;
 81+ }
 82+
 83+ /**
 84+ * @return bool
 85+ */
 86+ function addPuppetClass() {
 87+ global $wgRequest, $wgOut;
 88+ global $wgUser;
 89+
 90+ $this->setHeaders();
 91+ if ( !$this->userCanExecute( $wgUser ) ) {
 92+ $this->displayRestrictionError();
 93+ return false;
 94+ }
 95+ $wgOut->setPagetitle( wfMsg( 'openstackmanager-addpuppetclass' ) );
 96+
 97+ $puppetGroupId = $wgRequest->getInt( 'puppetgroupid' );
 98+ $puppetGroupInfo = array();
 99+ $puppetGroupInfo['puppetclassname'] = array(
 100+ 'type' => 'text',
 101+ 'label-message' => 'openstackmanager-puppetclassname',
 102+ 'default' => '',
 103+ 'name' => 'puppetclassname',
 104+ );
 105+ $puppetGroupInfo['puppetclassposition'] = array(
 106+ 'type' => 'int',
 107+ 'label-message' => 'openstackmanager-puppetclassposition',
 108+ 'name' => 'puppetclassposition',
 109+ );
 110+ $puppetGroupInfo['action'] = array(
 111+ 'type' => 'hidden',
 112+ 'default' => 'addclass',
 113+ 'name' => 'action',
 114+ );
 115+ $puppetGroupInfo['puppetgroupid'] = array(
 116+ 'type' => 'hidden',
 117+ 'default' => $puppetGroupId,
 118+ 'name' => 'puppetGroupId',
 119+ );
 120+
 121+ $puppetGroupForm = new SpecialNovaPuppetGroupForm( $puppetGroupInfo, 'openstackmanager-novapuppetgroup' );
 122+ $puppetGroupForm->setTitle( SpecialPage::getTitleFor( 'NovaPuppetGroup' ) );
 123+ $puppetGroupForm->setSubmitID( 'novapuppetgroup-form-addclasssubmit' );
 124+ $puppetGroupForm->setSubmitCallback( array( $this, 'tryAddClassSubmit' ) );
 125+ $puppetGroupForm->show();
 126+
 127+ return true;
 128+ }
 129+
 130+ /**
 131+ * @return bool
 132+ */
 133+ function deletePuppetClass() {
 134+ global $wgRequest, $wgOut;
 135+ global $wgUser;
 136+
 137+ $this->setHeaders();
 138+ if ( !$this->userCanExecute( $wgUser ) ) {
 139+ $this->displayRestrictionError();
 140+ return false;
 141+ }
 142+ $wgOut->setPagetitle( wfMsg( 'openstackmanager-removepuppetclass' ) );
 143+ if ( ! $wgRequest->wasPosted() ) {
 144+ $wgOut->addWikiMsg( 'openstackmanager-removepuppetclassconfirm' );
 145+ }
 146+ $puppetClassId = $wgRequest->getInt( 'puppetclassid' );
 147+ $puppetGroupInfo = array();
 148+ $puppetGroupInfo['puppetclassid'] = array(
 149+ 'type' => 'hidden',
 150+ 'default' => $puppetClassId,
 151+ 'name' => 'puppetclassid',
 152+ );
 153+ $puppetGroupInfo['action'] = array(
 154+ 'type' => 'hidden',
 155+ 'default' => 'deleteclass',
 156+ 'name' => 'action',
 157+ );
 158+
 159+ $puppetGroupForm = new SpecialNovaPuppetGroupForm( $puppetGroupInfo, 'openstackmanager-novapuppetgroup' );
 160+ $puppetGroupForm->setTitle( SpecialPage::getTitleFor( 'NovaPuppetGroup' ) );
 161+ $puppetGroupForm->setSubmitID( 'novapuppetgroup-form-deletepuppetclasssubmit' );
 162+ $puppetGroupForm->setSubmitCallback( array( $this, 'tryDeleteClassSubmit' ) );
 163+ $puppetGroupForm->show();
 164+
 165+ return true;
 166+ }
 167+
 168+ /**
 169+ * @return bool
 170+ */
 171+ function addPuppetVar() {
 172+ global $wgRequest, $wgOut;
 173+ global $wgUser;
 174+
 175+ $this->setHeaders();
 176+ if ( !$this->userCanExecute( $wgUser ) ) {
 177+ $this->displayRestrictionError();
 178+ return false;
 179+ }
 180+ $wgOut->setPagetitle( wfMsg( 'openstackmanager-addpuppetvar' ) );
 181+
 182+ $puppetGroupId = $wgRequest->getInt( 'puppetgroupid' );
 183+ $puppetGroupInfo = array();
 184+ $puppetGroupInfo['puppetvarname'] = array(
 185+ 'type' => 'text',
 186+ 'label-message' => 'openstackmanager-puppetvarname',
 187+ 'default' => '',
 188+ 'name' => 'puppetvarname',
 189+ );
 190+ $puppetGroupInfo['puppetvarposition'] = array(
 191+ 'type' => 'int',
 192+ 'label-message' => 'openstackmanager-puppetvarposition',
 193+ 'name' => 'puppetvarposition',
 194+ );
 195+ $puppetGroupInfo['action'] = array(
 196+ 'type' => 'hidden',
 197+ 'default' => 'addvar',
 198+ 'name' => 'action',
 199+ );
 200+ $puppetGroupInfo['puppetgroupid'] = array(
 201+ 'type' => 'hidden',
 202+ 'default' => $puppetGroupId,
 203+ 'name' => 'puppetGroupId',
 204+ );
 205+
 206+ $puppetGroupForm = new SpecialNovaPuppetGroupForm( $puppetGroupInfo, 'openstackmanager-novapuppetgroup' );
 207+ $puppetGroupForm->setTitle( SpecialPage::getTitleFor( 'NovaPuppetGroup' ) );
 208+ $puppetGroupForm->setSubmitID( 'novapuppetGroup-form-addvarsubmit' );
 209+ $puppetGroupForm->setSubmitCallback( array( $this, 'tryAddVarSubmit' ) );
 210+ $puppetGroupForm->show();
 211+
 212+ return true;
 213+ }
 214+
 215+ /**
 216+ * @return bool
 217+ */
 218+ function deletePuppetVar() {
 219+ global $wgRequest, $wgOut;
 220+ global $wgUser;
 221+
 222+ $this->setHeaders();
 223+ if ( !$this->userCanExecute( $wgUser ) ) {
 224+ $this->displayRestrictionError();
 225+ return false;
 226+ }
 227+ $wgOut->setPagetitle( wfMsg( 'openstackmanager-removepuppetvar' ) );
 228+
 229+ $puppetVarId = $wgRequest->getText( 'puppetvarid' );
 230+ if ( ! $wgRequest->wasPosted() ) {
 231+ $wgOut->addWikiMsg( 'openstackmanager-removepuppetvarconfirm' );
 232+ }
 233+ $puppetGroupInfo = array();
 234+ $puppetGroupInfo['puppetvarid'] = array(
 235+ 'type' => 'hidden',
 236+ 'default' => $puppetVarId,
 237+ 'name' => 'puppetvarid',
 238+ );
 239+ $puppetGroupInfo['action'] = array(
 240+ 'type' => 'hidden',
 241+ 'default' => 'deletevar',
 242+ 'name' => 'action',
 243+ );
 244+
 245+ $puppetGroupForm = new SpecialNovaPuppetGroupForm( $puppetGroupInfo, 'openstackmanager-novapuppetgroup' );
 246+ $puppetGroupForm->setTitle( SpecialPage::getTitleFor( 'NovaPuppetGroup' ) );
 247+ $puppetGroupForm->setSubmitID( 'novapuppetgroup-form-deletepuppetvarsubmit' );
 248+ $puppetGroupForm->setSubmitCallback( array( $this, 'tryDeleteVarSubmit' ) );
 249+ $puppetGroupForm->show();
 250+
 251+ return true;
 252+ }
 253+
 254+ /**
 255+ * @return bool
 256+ */
 257+ function deletePuppetGroup() {
 258+ global $wgOut, $wgRequest;
 259+ global $wgUser;
 260+
 261+ $this->setHeaders();
 262+ if ( !$this->userCanExecute( $wgUser ) ) {
 263+ $this->displayRestrictionError();
 264+ return false;
 265+ }
 266+ $wgOut->setPagetitle( wfMsg( 'openstackmanager-deletepuppetgroup' ) );
 267+
 268+ $puppetGroupId = $wgRequest->getInt( 'puppetgroupid' );
 269+ if ( ! $wgRequest->wasPosted() ) {
 270+ $wgOut->addWikiMsg( 'openstackmanager-removepuppetgroupconfirm' );
 271+ }
 272+ $puppetGroupInfo = array();
 273+ $puppetGroupInfo['puppetgroupid'] = array(
 274+ 'type' => 'hidden',
 275+ 'default' => $puppetGroupId,
 276+ 'name' => 'puppetgroupid',
 277+ );
 278+ $puppetGroupInfo['action'] = array(
 279+ 'type' => 'hidden',
 280+ 'default' => 'delete',
 281+ 'name' => 'action',
 282+ );
 283+ $puppetGroupForm = new SpecialNovaPuppetGroupForm( $puppetGroupInfo, 'openstackmanager-novapuppetgroup' );
 284+ $puppetGroupForm->setTitle( SpecialPage::getTitleFor( 'NovaPuppetGroup' ) );
 285+ $puppetGroupForm->setSubmitID( 'novapuppetGroup-form-deletepuppetgroupsubmit' );
 286+ $puppetGroupForm->setSubmitCallback( array( $this, 'tryDeleteSubmit' ) );
 287+ $puppetGroupForm->show();
 288+
 289+ return true;
 290+ }
 291+
 292+ /**
 293+ * @return bool
 294+ */
 295+ function modifyPuppetClass() {
 296+ global $wgRequest, $wgOut;
 297+ global $wgUser;
 298+
 299+ $this->setHeaders();
 300+ if ( !$this->userCanExecute( $wgUser ) ) {
 301+ $this->displayRestrictionError();
 302+ return false;
 303+ }
 304+ $wgOut->setPagetitle( wfMsg( 'openstackmanager-modifypuppetclass' ) );
 305+
 306+ $puppetGroupId = $wgRequest->getInt( 'puppetgroupid' );
 307+ $puppetClassId = $wgRequest->getInt( 'puppetclassid' );
 308+ $puppetClassPosition = $wgRequest->getInt( 'puppetclassposition' );
 309+ $puppetGroupInfo = array();
 310+ $puppetGroupInfo['puppetclassid'] = array(
 311+ 'type' => 'hidden',
 312+ 'default' => $puppetClassId,
 313+ 'name' => 'puppetclassid',
 314+ );
 315+ $puppetGroupInfo['puppetclassposition'] = array(
 316+ 'type' => 'int',
 317+ 'label-message' => 'openstackmanager-puppetclassposition',
 318+ 'default' => $puppetClassPosition,
 319+ 'name' => 'puppetclassposition',
 320+ );
 321+ $groups = OpenStackNovaPuppetGroup::getGroupList();
 322+ $groupKeys = array();
 323+ foreach ( $groups as $group ) {
 324+ $groupname = htmlentities( $group->getName() );
 325+ $groupKeys["$groupname"] = $group->getId();
 326+ }
 327+ $puppetGroupInfo['puppetgroupid'] = array(
 328+ 'type' => 'select',
 329+ 'label-message' => 'openstackmanager-puppetgroup',
 330+ 'options' => $groupKeys,
 331+ 'default' => $puppetGroupId,
 332+ 'name' => 'puppetgroupid',
 333+ );
 334+ $puppetGroupInfo['action'] = array(
 335+ 'type' => 'hidden',
 336+ 'default' => 'modifyclass',
 337+ 'name' => 'action',
 338+ );
 339+
 340+ $puppetGroupForm = new SpecialNovaPuppetGroupForm( $puppetGroupInfo, 'openstackmanager-novapuppetgroup' );
 341+ $puppetGroupForm->setTitle( SpecialPage::getTitleFor( 'NovaPuppetGroup' ) );
 342+ $puppetGroupForm->setSubmitID( 'novapuppetgroup-form-modifypuppetclasssubmit' );
 343+ $puppetGroupForm->setSubmitCallback( array( $this, 'tryModifyClassSubmit' ) );
 344+ $puppetGroupForm->show();
 345+
 346+ return true;
 347+ }
 348+
 349+ /**
 350+ * @return bool
 351+ */
 352+ function modifyPuppetVar() {
 353+ global $wgRequest, $wgOut;
 354+ global $wgUser;
 355+
 356+ $this->setHeaders();
 357+ if ( !$this->userCanExecute( $wgUser ) ) {
 358+ $this->displayRestrictionError();
 359+ return false;
 360+ }
 361+ $wgOut->setPagetitle( wfMsg( 'openstackmanager-modifypuppetvar' ) );
 362+
 363+ $puppetGroupId = $wgRequest->getInt( 'puppetgroupid' );
 364+ $puppetVarId = $wgRequest->getInt( 'puppetvarid' );
 365+ $puppetVarPosition = $wgRequest->getInt( 'puppetvarposition' );
 366+ $puppetGroupInfo = array();
 367+ $puppetGroupInfo['puppetvarid'] = array(
 368+ 'type' => 'hidden',
 369+ 'default' => $puppetVarId,
 370+ 'name' => 'puppetvarid',
 371+ );
 372+ $puppetGroupInfo['puppetvarposition'] = array(
 373+ 'type' => 'int',
 374+ 'label-message' => 'openstackmanager-puppetvarposition',
 375+ 'default' => $puppetVarPosition,
 376+ 'name' => 'puppetvarposition',
 377+ );
 378+ $groups = OpenStackNovaPuppetGroup::getGroupList();
 379+ $groupKeys = array();
 380+ foreach ( $groups as $group ) {
 381+ $groupname = htmlentities( $group->getName() );
 382+ $groupKeys["$groupname"] = $group->getId();
 383+ }
 384+ $puppetGroupInfo['puppetgroupid'] = array(
 385+ 'type' => 'select',
 386+ 'label-message' => 'openstackmanager-puppetgroup',
 387+ 'options' => $groupKeys,
 388+ 'default' => $puppetGroupId,
 389+ 'name' => 'puppetgroupid',
 390+ );
 391+ $puppetGroupInfo['action'] = array(
 392+ 'type' => 'hidden',
 393+ 'default' => 'modifyvar',
 394+ 'name' => 'action',
 395+ );
 396+
 397+ $puppetGroupForm = new SpecialNovaPuppetGroupForm( $puppetGroupInfo, 'openstackmanager-novapuppetgroup' );
 398+ $puppetGroupForm->setTitle( SpecialPage::getTitleFor( 'NovaPuppetGroup' ) );
 399+ $puppetGroupForm->setSubmitID( 'novapuppetgroup-form-modifypuppetvarsubmit' );
 400+ $puppetGroupForm->setSubmitCallback( array( $this, 'tryModifyVarSubmit' ) );
 401+ $puppetGroupForm->show();
 402+
 403+ return true;
 404+ }
 405+
 406+ /**
 407+ * @return bool
 408+ */
 409+ function modifyPuppetGroup() {
 410+ global $wgRequest, $wgOut;
 411+ global $wgUser;
 412+
 413+ $this->setHeaders();
 414+ if ( !$this->userCanExecute( $wgUser ) ) {
 415+ $this->displayRestrictionError();
 416+ return false;
 417+ }
 418+ $wgOut->setPagetitle( wfMsg( 'openstackmanager-modifypuppetgroup' ) );
 419+
 420+ $puppetGroupId = $wgRequest->getInt( 'puppetgroupid' );
 421+ $puppetGroupPosition = $wgRequest->getInt( 'puppetgroupposition' );
 422+ $puppetGroupInfo = array();
 423+ $puppetGroupInfo['puppetgroupid'] = array(
 424+ 'type' => 'hidden',
 425+ 'default' => $puppetGroupId,
 426+ 'name' => 'puppetgroupid',
 427+ );
 428+ $puppetGroupInfo['puppetgroupposition'] = array(
 429+ 'type' => 'int',
 430+ 'label-message' => 'openstackmanager-puppetgroupposition',
 431+ 'default' => $puppetGroupPosition,
 432+ 'name' => 'puppetgroupposition',
 433+ );
 434+ $puppetGroupInfo['action'] = array(
 435+ 'type' => 'hidden',
 436+ 'default' => 'modify',
 437+ 'name' => 'action',
 438+ );
 439+
 440+ $puppetGroupForm = new SpecialNovaPuppetGroupForm( $puppetGroupInfo, 'openstackmanager-novapuppetgroup' );
 441+ $puppetGroupForm->setTitle( SpecialPage::getTitleFor( 'NovaPuppetGroup' ) );
 442+ $puppetGroupForm->setSubmitID( 'novapuppetgroup-form-modifypuppetgroupsubmit' );
 443+ $puppetGroupForm->setSubmitCallback( array( $this, 'tryModifyGroupSubmit' ) );
 444+ $puppetGroupForm->show();
 445+
 446+ return true;
 447+ }
 448+
 449+ /**
 450+ * @return void
 451+ */
 452+ function listPuppetGroups() {
 453+ global $wgOut;
 454+
 455+ $this->setHeaders();
 456+ $wgOut->setPagetitle( wfMsg( 'openstackmanager-puppetgrouplist' ) );
 457+ $wgOut->addModuleStyles( 'ext.openstack' );
 458+
 459+ $out = '';
 460+ $sk = $wgOut->getSkin();
 461+ $out .= $sk->link( $this->getTitle(), wfMsgHtml( 'openstackmanager-createpuppetgroup' ), array(), array( 'action' => 'create' ) );
 462+ $puppetGroups = OpenStackNovaPuppetGroup::getGroupList();
 463+ foreach ( $puppetGroups as $puppetGroup ) {
 464+ $puppetGroupId = $puppetGroup->getId();
 465+ $puppetGroupPosition = $puppetGroup->getPosition();
 466+ $puppetGroupName = $puppetGroup->getName();
 467+ $puppetGroupName = "[$puppetGroupPosition] " . htmlentities( $puppetGroupName );
 468+ $specialPuppetGroupTitle = Title::newFromText( 'Special:NovaPuppetGroup' );
 469+ $modify = $sk->link( $specialPuppetGroupTitle, wfMsgHtml( 'openstackmanager-modify' ), array(), array( 'action' => 'modify', 'puppetgroupid' => $puppetGroupId, 'puppetgroupposition' => $puppetGroupPosition, 'returnto' => 'Special:NovaPuppetGroup' ) );
 470+ $delete = $sk->link( $specialPuppetGroupTitle, wfMsgHtml( 'openstackmanager-delete' ), array(), array( 'action' => 'delete', 'puppetgroupid' => $puppetGroupId, 'returnto' => 'Special:NovaPuppetGroup' ) );
 471+ $out .= Html::rawElement( 'h2', array(), "$puppetGroupName ($modify, $delete)" );
 472+ $out .= Html::element( 'h3', array(), wfMsg( 'openstackmanager-puppetclasses' ) );
 473+ $out .= $sk->link( $specialPuppetGroupTitle, wfMsgHtml( 'openstackmanager-addpuppetclass' ), array(), array( 'action' => 'addclass', 'puppetgroupid' => $puppetGroupId, 'returnto' => 'Special:NovaPuppetGroup' ) );
 474+ $puppetGroupClasses = $puppetGroup->getClasses();
 475+ $puppetGroupVars = $puppetGroup->getVars();
 476+ if ( $puppetGroupClasses ) {
 477+ $classesOut = '';
 478+ foreach ( $puppetGroupClasses as $puppetGroupClass ) {
 479+ $modify = $sk->link( $specialPuppetGroupTitle, wfMsgHtml( 'openstackmanager-modify' ), array(), array( 'action' => 'modifyclass', 'puppetclassid' => $puppetGroupClass["id"], 'puppetclassposition' => $puppetGroupClass["position"], 'puppetgroupid' => $puppetGroupId, 'returnto' => 'Special:NovaPuppetGroup' ) );
 480+ $delete = $sk->link( $specialPuppetGroupTitle, wfMsgHtml( 'openstackmanager-delete' ), array(), array( 'action' => 'deleteclass', 'puppetclassid' => $puppetGroupClass["id"], 'returnto' => 'Special:NovaPuppetGroup' ) );
 481+ $classname = '[' . $puppetGroupClass["position"] . '] ' . htmlentities( $puppetGroupClass["name"] );
 482+ $classesOut .= Html::rawElement( 'li', array(), "$classname ($modify, $delete)" );
 483+ }
 484+ $out .= Html::rawElement( 'ul', array(), $classesOut );
 485+ }
 486+ $out .= Html::element( 'h3', array(), wfMsg( 'openstackmanager-puppetvars' ) );
 487+ $out .= $sk->link( $specialPuppetGroupTitle, wfMsgHtml( 'openstackmanager-addpuppetvar' ), array(), array( 'action' => 'addvar', 'puppetgroupid' => $puppetGroupId, 'returnto' => 'Special:NovaPuppetGroup' ) );
 488+ if ( $puppetGroupVars ) {
 489+ $varsOut = '';
 490+ foreach ( $puppetGroupVars as $puppetGroupVar ) {
 491+ $modify = $sk->link( $specialPuppetGroupTitle, wfMsgHtml( 'openstackmanager-modify' ), array(), array( 'action' => 'modifyvar', 'puppetvarid' => $puppetGroupVar["id"], 'puppetvarposition' => $puppetGroupVar["position"], 'puppetgroupid' => $puppetGroupId, 'returnto' => 'Special:NovaPuppetGroup' ) );
 492+ $delete = $sk->link( $specialPuppetGroupTitle, wfMsgHtml( 'openstackmanager-delete' ), array(), array( 'action' => 'deletevar', 'puppetvarid' => $puppetGroupVar["id"], 'returnto' => 'Special:NovaPuppetGroup' ) );
 493+ $varname = '[' . $puppetGroupVar["position"] . '] ' . htmlentities( $puppetGroupVar["name"] );
 494+ $varsOut .= Html::rawElement( 'li', array(), "$varname ($modify, $delete)" );
 495+ }
 496+ $out .= Html::rawElement( 'ul', array(), $varsOut );
 497+ }
 498+ }
 499+
 500+ $wgOut->addHTML( $out );
 501+ }
 502+
 503+ /**
 504+ * @param $formData
 505+ * @param string $entryPoint
 506+ * @return bool
 507+ */
 508+ function tryCreateSubmit( $formData, $entryPoint = 'internal' ) {
 509+ global $wgOut;
 510+ global $wgOpenStackManagerDefaultSecurityGroupRules;
 511+
 512+ $success = OpenStackNovaPuppetGroup::addGroup( $formData['puppetgroupname'], $formData['puppetgroupposition'] );
 513+ if ( $success ) {
 514+ $wgOut->addWikiMsg( 'openstackmanager-createdpuppetgroup' );
 515+ } else {
 516+ $wgOut->addWikiMsg( 'openstackmanager-createpuppetgroupfailed' );
 517+ }
 518+ $sk = $wgOut->getSkin();
 519+ $out = '<br />';
 520+ $out .= $sk->link( $this->getTitle(), wfMsgHtml( 'openstackmanager-backpuppetgrouplist' ) );
 521+ $wgOut->addHTML( $out );
 522+
 523+ return true;
 524+ }
 525+
 526+ /**
 527+ * @param $formData
 528+ * @param string $entryPoint
 529+ * @return bool
 530+ */
 531+ function tryDeleteSubmit( $formData, $entryPoint = 'internal' ) {
 532+ global $wgOut;
 533+
 534+ $success = OpenStackNovaPuppetGroup::deleteGroup( $formData['puppetgroupid'] );
 535+ if ( $success ) {
 536+ $wgOut->addWikiMsg( 'openstackmanager-deletedpuppetgroup' );
 537+ } else {
 538+ $wgOut->addWikiMsg( 'openstackmanager-deletepuppetgroupfailed' );
 539+ }
 540+ $sk = $wgOut->getSkin();
 541+ $out = '<br />';
 542+ $out .= $sk->link( $this->getTitle(), wfMsgHtml( 'openstackmanager-backpuppetgrouplist' ) );
 543+ $wgOut->addHTML( $out );
 544+
 545+ return true;
 546+ }
 547+
 548+ /**
 549+ * @param $formData
 550+ * @param string $entryPoint
 551+ * @return bool
 552+ */
 553+ function tryAddClassSubmit( $formData, $entryPoint = 'internal' ) {
 554+ global $wgOut;
 555+
 556+ $success = OpenStackNovaPuppetGroup::addClass( $formData['puppetclassname'], $formData['puppetclassposition'], $formData['puppetgroupid'] );
 557+ if ( $success ) {
 558+ $wgOut->addWikiMsg( 'openstackmanager-addedpuppetclass' );
 559+ } else {
 560+ $wgOut->addWikiMsg( 'openstackmanager-failedtoaddpuppetclass' );
 561+ }
 562+ $sk = $wgOut->getSkin();
 563+ $out = '<br />';
 564+ $out .= $sk->link( $this->getTitle(), wfMsgHtml( 'openstackmanager-backpuppetgrouplist' ) );
 565+ $wgOut->addHTML( $out );
 566+
 567+ return true;
 568+ }
 569+
 570+ /**
 571+ * @param $formData
 572+ * @param string $entryPoint
 573+ * @return bool
 574+ */
 575+ function tryDeleteClassSubmit( $formData, $entryPoint = 'internal' ) {
 576+ global $wgOut;
 577+
 578+ $success = OpenStackNovaPuppetGroup::deleteClass( $formData['puppetclassid'] );
 579+ if ( $success ) {
 580+ $wgOut->addWikiMsg( 'openstackmanager-deletedpuppetclass' );
 581+ } else {
 582+ $wgOut->addWikiMsg( 'openstackmanager-failedtodeletepuppetclass' );
 583+ }
 584+ $out = '<br />';
 585+ $sk = $wgOut->getSkin();
 586+ $out .= $sk->link( $this->getTitle(), wfMsgHtml( 'openstackmanager-backpuppetgrouplist' ) );
 587+ $wgOut->addHTML( $out );
 588+
 589+ return true;
 590+ }
 591+
 592+ /**
 593+ * @param $formData
 594+ * @param string $entryPoint
 595+ * @return bool
 596+ */
 597+ function tryAddVarSubmit( $formData, $entryPoint = 'internal' ) {
 598+ global $wgOut;
 599+
 600+ $success = OpenStackNovaPuppetGroup::addVar( $formData['puppetvarname'], $formData['puppetvarposition'], $formData['puppetgroupid'] );
 601+ if ( $success ) {
 602+ $wgOut->addWikiMsg( 'openstackmanager-addedpuppetvar' );
 603+ } else {
 604+ $wgOut->addWikiMsg( 'openstackmanager-failedtoaddpuppetvar' );
 605+ }
 606+ $sk = $wgOut->getSkin();
 607+ $out = '<br />';
 608+ $out .= $sk->link( $this->getTitle(), wfMsgHtml( 'openstackmanager-backpuppetgrouplist' ) );
 609+ $wgOut->addHTML( $out );
 610+
 611+ return true;
 612+ }
 613+
 614+ /**
 615+ * @param $formData
 616+ * @param string $entryPoint
 617+ * @return bool
 618+ */
 619+ function tryDeleteVarSubmit( $formData, $entryPoint = 'internal' ) {
 620+ global $wgOut;
 621+
 622+ $success = OpenStackNovaPuppetGroup::deleteVar( $formData['puppetvarid'] );
 623+ if ( $success ) {
 624+ $wgOut->addWikiMsg( 'openstackmanager-deletedpuppetvar' );
 625+ } else {
 626+ $wgOut->addWikiMsg( 'openstackmanager-failedtodeletepuppetvar' );
 627+ }
 628+ $out = '<br />';
 629+ $sk = $wgOut->getSkin();
 630+ $out .= $sk->link( $this->getTitle(), wfMsgHtml( 'openstackmanager-backpuppetgrouplist' ) );
 631+ $wgOut->addHTML( $out );
 632+
 633+ return true;
 634+ }
 635+
 636+ /**
 637+ * @param $formData
 638+ * @param string $entryPoint
 639+ * @return bool
 640+ */
 641+ function tryModifyClassSubmit( $formData, $entryPoint = 'internal' ) {
 642+ global $wgOut;
 643+
 644+ $success = OpenStackNovaPuppetGroup::updateClass( $formData['puppetclassid'], $formData['puppetgroupid'], $formData['puppetclassposition'] );
 645+ if ( $success ) {
 646+ $wgOut->addWikiMsg( 'openstackmanager-modifiedpuppetclass' );
 647+ } else {
 648+ $wgOut->addWikiMsg( 'openstackmanager-failedtomodifypuppetclass' );
 649+ }
 650+ $out = '<br />';
 651+ $sk = $wgOut->getSkin();
 652+ $out .= $sk->link( $this->getTitle(), wfMsgHtml( 'openstackmanager-backpuppetgrouplist' ) );
 653+ $wgOut->addHTML( $out );
 654+
 655+ return true;
 656+ }
 657+
 658+ /**
 659+ * @param $formData
 660+ * @param string $entryPoint
 661+ * @return bool
 662+ */
 663+ function tryModifyVarSubmit( $formData, $entryPoint = 'internal' ) {
 664+ global $wgOut;
 665+
 666+ $success = OpenStackNovaPuppetGroup::updateVar( $formData['puppetvarid'], $formData['puppetgroupid'], $formData['puppetvarposition'] );
 667+ if ( $success ) {
 668+ $wgOut->addWikiMsg( 'openstackmanager-modifiedpuppetvar' );
 669+ } else {
 670+ $wgOut->addWikiMsg( 'openstackmanager-failedtomodifypuppetvar' );
 671+ }
 672+ $out = '<br />';
 673+ $sk = $wgOut->getSkin();
 674+ $out .= $sk->link( $this->getTitle(), wfMsgHtml( 'openstackmanager-backpuppetgrouplist' ) );
 675+ $wgOut->addHTML( $out );
 676+
 677+ return true;
 678+ }
 679+
 680+ /**
 681+ * @param $formData
 682+ * @param string $entryPoint
 683+ * @return bool
 684+ */
 685+ function tryModifyGroupSubmit( $formData, $entryPoint = 'internal' ) {
 686+ global $wgOut;
 687+
 688+ $success = OpenStackNovaPuppetGroup::updateGroupPosition( $formData['puppetgroupid'], $formData['puppetgroupposition'] );
 689+ if ( $success ) {
 690+ $wgOut->addWikiMsg( 'openstackmanager-modifiedpuppetgroup' );
 691+ } else {
 692+ $wgOut->addWikiMsg( 'openstackmanager-failedtomodifypuppetgroup' );
 693+ }
 694+ $out = '<br />';
 695+ $sk = $wgOut->getSkin();
 696+ $out .= $sk->link( $this->getTitle(), wfMsgHtml( 'openstackmanager-backpuppetgrouplist' ) );
 697+ $wgOut->addHTML( $out );
 698+
 699+ return true;
 700+ }
 701+
 702+}
 703+
 704+class SpecialNovaPuppetGroupForm extends HTMLForm {
 705+}
Index: trunk/extensions/OpenStackManager/openstack.sql
@@ -0,0 +1,44 @@
 2+CREATE TABLE /*_*/openstack_puppet_groups (
 3+ -- ID for groups. Puppet variables and classes
 4+ -- may be grouped, and can share the same group.
 5+ group_id int not null primary key auto_increment,
 6+
 7+ -- User-presentable name of the group
 8+ group_name varchar(255) binary not null,
 9+
 10+ -- Position of group when displayed
 11+ group_position int not null
 12+
 13+) /*$wgDBTableOptions*/;
 14+
 15+CREATE INDEX /*i*/group_name on /*_*/openstack_puppet_groups (group_name);
 16+
 17+CREATE TABLE /*_*/openstack_puppet_vars (
 18+ -- ID for puppet variable
 19+ var_id int not null primary key auto_increment,
 20+
 21+ -- User-presentable name of puppet variable
 22+ var_name varchar(255) binary not null,
 23+
 24+ -- Group to which this variable belongs
 25+ var_group_id int not null,
 26+
 27+ -- Position of variable inside its group
 28+ var_position int not null
 29+
 30+) /*$wgDBTableOptions*/;
 31+
 32+CREATE TABLE /*_*/openstack_puppet_classes (
 33+ -- IF for puppet class
 34+ class_id int not null primary key auto_increment,
 35+
 36+ -- User-presentable name of puppet class
 37+ class_name varchar(255) binary not null,
 38+
 39+ -- Group to which this class belongs
 40+ class_group_id int not null,
 41+
 42+ -- Position of class inside its group
 43+ class_position int not null
 44+
 45+) /*$wgDBTableOptions*/;
Index: trunk/extensions/OpenStackManager/OpenStackManager.i18n.php
@@ -74,7 +74,7 @@
7575 'openstackmanager-configureinstance' => 'Configure instance',
7676 'openstackmanager-nonexistanthost' => 'The host requested does not exist.',
7777 'openstackmanager-dnsdomain' => 'DNS domain',
78 - 'openstackmanager-puppetclasses' => 'Puppet classes',
 78+ 'openstackmanager-puppetclasses' => 'Classes:',
7979 'openstackmanager-novainstance-info' => 'Instance information',
8080 'openstackmanager-novainstance-puppetinfo' => 'Puppet information',
8181
@@ -303,6 +303,48 @@
304304 'openstackmanager-modifiedsudoer' => 'Successfully modified sudo policy.',
305305 'openstackmanager-nonexistantsudoer' => 'Requested sudo policy does not exist.',
306306
 307+ 'openstackmanager-novapuppetgroup' => 'Nova Puppet Group',
 308+ 'openstackmanager-puppetgrouplist' => 'Puppet Group List',
 309+ 'openstackmanager-createpuppetgroup' => 'Create puppet group',
 310+ 'openstackmanager-createdpuppetgroup' => 'Created puppet group.',
 311+ 'openstackmanager-createpuppetgroupfailed' => 'Failed to create puppet group.',
 312+ 'openstackmanager-backpuppetgrouplist' => 'Back to puppet group list.',
 313+ 'openstackmanager-addpuppetclass' => 'Add puppet class',
 314+ 'openstackmanager-addedpuppetclass' => 'Added puppet class.',
 315+ 'openstackmanager-failedtoaddpuppetclass' => 'Failed to add puppet class.',
 316+ 'openstackmanager-puppetclassname' => 'Class name',
 317+ 'openstackmanager-removepuppetgroupconfirm' => 'Are you sure you would like to delete this puppet group?',
 318+ 'openstackmanager-deletepuppetgroup' => 'Delete Puppet Group',
 319+ 'openstackmanager-deletedpuppetgroup' => 'Deleted puppet group.',
 320+ 'openstackmanager-deletepuppetgroupfailed' => 'Failed to delete puppet group.',
 321+ 'openstackmanager-modifypuppetgroup' => 'Modify Puppet Group',
 322+ 'openstackmanager-modifiedpuppetgroup' => 'Modified puppet group.',
 323+ 'openstackmanager-failedtomodifypuppetgroup' => 'Failed to modify puppet group.',
 324+ 'openstackmanager-puppetvars' => 'Variables:',
 325+ 'openstackmanager-addpuppetvar' => 'Add puppet variable',
 326+ 'openstackmanager-puppetvarname' => 'Variable name',
 327+ 'openstackmanager-puppetvarposition' => 'Variable Position',
 328+ 'openstackmanager-addedpuppetvar' => 'Added puppet variable.',
 329+ 'openstackmanager-failedtoaddpuppetvar' => 'Failed to add puppet variable.',
 330+ 'openstackmanager-modifypuppetvar' => 'Modify Puppet Variable',
 331+ 'openstackmanager-modifiedpuppetvar' => 'Modified puppet variable.',
 332+ 'openstackmanager-failedtomodifypuppetvar' => 'Failed to modify puppet variable.',
 333+ 'openstackmanager-puppetgroupname' => 'Puppet group name',
 334+ 'openstackmanager-puppetgroupposition' => 'Puppet group position',
 335+ 'openstackmanager-modifypuppetclass' => 'Modify Puppet Class',
 336+ 'openstackmanager-failedtomodifypuppetclass' => 'Failed to modify puppet class.',
 337+ 'openstackmanager-puppetclassposition' => 'Class position',
 338+ 'openstackmanager-puppetgroup' => 'Puppet Group',
 339+ 'openstackmanager-modifiedpuppetclass' => 'Modified puppet class.',
 340+ 'openstackmanager-removepuppetclass' => 'Delete Puppet Class',
 341+ 'openstackmanager-removepuppetclassconfirm' => 'Are you sure you would like to delete this puppet class?',
 342+ 'openstackmanager-deletedpuppetclass' => 'Deleted puppet class.',
 343+ 'openstackmanager-failedtodeletepuppetclass' => 'Failed to delete puppet class.',
 344+ 'openstackmanager-removepuppetvar' => 'Delete puppet variable',
 345+ 'openstackmanager-removepuppetvarconfirm' => 'Are you sure you would like to delete this puppet variable?',
 346+ 'openstackmanager-deletedpuppetvar' => 'Deleted puppet variable.',
 347+ 'openstackmanager-failedtodeletepuppetvar' => 'Failed to delete puppet variable',
 348+
307349 'openstackmanager-email-subject' => 'Your instance is ready to be logged into.',
308350 'openstackmanager-email-body' => 'The following instance has been created, and is ready to be logged into:',
309351 'right-manageproject' => 'Manage Openstack projects and roles',
Index: trunk/extensions/OpenStackManager/OpenStackManager.php
@@ -101,6 +101,8 @@
102102 $wgAutoloadClasses['OpenStackNovaVolume'] = $dir . 'OpenStackNovaVolume.php';
103103 $wgAutoloadClasses['OpenStackNovaSudoer'] = $dir . 'OpenStackNovaSudoer.php';
104104 $wgAutoloadClasses['OpenStackNovaArticle'] = $dir . 'OpenStackNovaArticle.php';
 105+$wgAutoloadClasses['OpenStackNovaHostJob'] = $dir . 'OpenStackNovaHostJob.php';
 106+$wgAutoloadClasses['OpenStackNovaPuppetGroup'] = $dir . 'OpenStackNovaPuppetGroup.php';
105107 $wgAutoloadClasses['SpecialNovaInstance'] = $dir . 'special/SpecialNovaInstance.php';
106108 $wgAutoloadClasses['SpecialNovaKey'] = $dir . 'special/SpecialNovaKey.php';
107109 $wgAutoloadClasses['SpecialNovaProject'] = $dir . 'special/SpecialNovaProject.php';
@@ -110,8 +112,8 @@
111113 $wgAutoloadClasses['SpecialNovaRole'] = $dir . 'special/SpecialNovaRole.php';
112114 $wgAutoloadClasses['SpecialNovaVolume'] = $dir . 'special/SpecialNovaVolume.php';
113115 $wgAutoloadClasses['SpecialNovaSudoer'] = $dir . 'special/SpecialNovaSudoer.php';
 116+$wgAutoloadClasses['SpecialNovaPuppetGroup'] = $dir . 'special/SpecialNovaPuppetGroup.php';
114117 $wgAutoloadClasses['SpecialNova'] = $dir . 'special/SpecialNova.php';
115 -$wgAutoloadClasses['OpenStackNovaHostJob'] = $dir . 'OpenStackNovaHostJob.php';
116118 $wgAutoloadClasses['AmazonEC2'] = $dir . 'aws-sdk/sdk.class.php';
117119 $wgAutoloadClasses['Spyc'] = $dir . 'Spyc.php';
118120 $wgSpecialPages['NovaInstance'] = 'SpecialNovaInstance';
@@ -133,6 +135,8 @@
134136 $wgSpecialPages['NovaSudoer'] = 'SpecialNovaSudoer';
135137 $wgSpecialPageGroups['NovaSudoer'] = 'nova';
136138 $wgJobClasses['addDNSHostToLDAP'] = 'OpenStackNovaHostJob';
 139+$wgSpecialPageGroups['NovaPuppetGroup'] = 'nova';
 140+$wgSpecialPages['NovaPuppetGroup'] = 'SpecialNovaPuppetGroup';
137141
138142 $wgHooks['LDAPSetCreationValues'][] = 'OpenStackNovaUser::LDAPSetCreationValues';
139143 $wgHooks['LDAPModifyUITemplate'][] = 'OpenStackNovaUser::LDAPModifyUITemplate';
@@ -148,3 +152,22 @@
149153 ) + $commonModuleInfo;
150154
151155 require_once( $dir . 'OpenStackNovaProject.php' );
 156+
 157+# Schema changes
 158+$wgHooks['LoadExtensionSchemaUpdates'][] = 'efOpenStackSchemaUpdates';
 159+
 160+/**
 161+ * @param $updater DatabaseUpdater
 162+ * @return bool
 163+ */
 164+function efOpenStackSchemaUpdates( $updater ) {
 165+ $base = dirname( __FILE__ );
 166+ switch ( $updater->getDB()->getType() ) {
 167+ case 'mysql':
 168+ $updater->addExtensionTable( 'openstack_puppet_groups', "$base/openstack.sql" );
 169+ $updater->addExtensionTable( 'openstack_puppet_vars', "$base/openstack.sql" );
 170+ $updater->addExtensionTable( 'openstack_puppet_classes', "$base/openstack.sql" );
 171+ break;
 172+ }
 173+ return true;
 174+}
Index: trunk/extensions/OpenStackManager/OpenStackNovaPuppetGroup.php
@@ -0,0 +1,291 @@
 2+<?php
 3+
 4+/**
 5+ * Class for interacting with puppet groups, variables and classes
 6+ */
 7+class OpenStackNovaPuppetGroup {
 8+
 9+ private $id, $name, $position, $vars, $classes;
 10+
 11+ /**
 12+ * Constructor. Can't be called directly. Call one of the static NewFrom* methods
 13+ * @param $id Int Database id for the group
 14+ * @param $name String User-defined name of the group
 15+ */
 16+ public function __construct( $id, $name, $position ) {
 17+ $this->id = $id;
 18+ $this->name = $name;
 19+ $this->position = $position;
 20+ $this->loadVars( $id );
 21+ $this->loadClasses( $id );
 22+ }
 23+
 24+ public function getName() {
 25+ return $this->name;
 26+ }
 27+
 28+ public function getId() {
 29+ return $this->id;
 30+ }
 31+
 32+ public function getPosition() {
 33+ return $this->position;
 34+ }
 35+
 36+ public function getVars() {
 37+ return $this->vars;
 38+ }
 39+
 40+ public function getClasses() {
 41+ return $this->classes;
 42+ }
 43+
 44+ /**
 45+ * @param $name string
 46+ * @return OpenStackNovaPuppetGroup|null
 47+ */
 48+ public static function newFromName( $name ) {
 49+ $dbr = wfGetDB( DB_SLAVE );
 50+ $row = $dbr->selectRow(
 51+ 'openstack_puppet_groups',
 52+ array(
 53+ 'group_id',
 54+ 'group_name',
 55+ 'group_position' ),
 56+ array( 'group_name' => $name ),
 57+ __METHOD__ );
 58+
 59+ if ( $row ) {
 60+ return self::newFromRow( $row );
 61+ } else {
 62+ return null;
 63+ }
 64+ }
 65+
 66+ /**
 67+ * @param $id int
 68+ * @return OpenStackNovaPuppetGroup|null
 69+ */
 70+ public static function newFromId( $id ) {
 71+ $dbr = wfGetDB( DB_SLAVE );
 72+ $row = $dbr->selectRow(
 73+ 'openstack_puppet_groups',
 74+ array(
 75+ 'group_id',
 76+ 'group_name',
 77+ 'group_position' ),
 78+ array( 'group_id' => intval( $id ) ),
 79+ __METHOD__ );
 80+
 81+ if ( $row ) {
 82+ return self::newFromRow( $row );
 83+ } else {
 84+ return null;
 85+ }
 86+ }
 87+
 88+ /**
 89+ * @param $row
 90+ * @return OpenStackNovaPuppetGroup
 91+ */
 92+ static function newFromRow( $row ) {
 93+ return new OpenStackNovaPuppetGroup(
 94+ intval( $row->group_id ),
 95+ $row->group_name,
 96+ $row->group_position
 97+ );
 98+ }
 99+
 100+ /**
 101+ * @return array
 102+ */
 103+ public static function getGroupList() {
 104+ $dbr = wfGetDB( DB_SLAVE );
 105+ $rows = $dbr->select(
 106+ 'openstack_puppet_groups',
 107+ array(
 108+ 'group_id',
 109+ 'group_name',
 110+ 'group_position'
 111+ ),
 112+ '',
 113+ __METHOD__,
 114+ array( 'ORDER BY' => 'group_position ASC' )
 115+ );
 116+ $groups = array();
 117+ foreach ( $rows as $row ) {
 118+ $groups[] = self::newFromRow( $row );
 119+ }
 120+ return $groups;
 121+ }
 122+
 123+ /**
 124+ * @param $group_id Int Group id of puppet variables
 125+ */
 126+ function loadVars( $groupid ) {
 127+ $dbr = wfGetDB( DB_SLAVE );
 128+ $rows = $dbr->select(
 129+ 'openstack_puppet_vars',
 130+ array(
 131+ 'var_id',
 132+ 'var_name',
 133+ 'var_position' ),
 134+ array( 'var_group_id' => $groupid ),
 135+ __METHOD__,
 136+ array( 'ORDER BY' => 'var_position ASC' )
 137+ );
 138+
 139+ $this->vars = array();
 140+ if ( $rows ) {
 141+ foreach ( $rows as $row ) {
 142+ $this->vars[] = array(
 143+ "name" => $row->var_name,
 144+ "id" => intval( $row->var_id ),
 145+ "position" => intval( $row->var_position )
 146+ );
 147+ }
 148+ }
 149+ }
 150+
 151+ /**
 152+ * @param $group_id Int Group id of puppet classes
 153+ */
 154+ function loadClasses( $groupid ) {
 155+ $dbr = wfGetDB( DB_SLAVE );
 156+ $rows = $dbr->select(
 157+ 'openstack_puppet_classes',
 158+ array(
 159+ 'class_id',
 160+ 'class_name',
 161+ 'class_position' ),
 162+ array( 'class_group_id' => $groupid ),
 163+ __METHOD__,
 164+ array( 'ORDER BY' => 'class_position ASC' )
 165+ );
 166+
 167+ $this->classes = array();
 168+ if ( $rows ) {
 169+ foreach ( $rows as $row ) {
 170+ $this->classes[] = array(
 171+ "name" => $row->class_name,
 172+ "id" => intval( $row->class_id ),
 173+ "position" => intval( $row->class_position )
 174+ );
 175+ }
 176+ }
 177+ }
 178+
 179+ public static function addGroup( $name, $position ) {
 180+ $dbw = wfGetDB( DB_MASTER );
 181+ return $dbw->insert(
 182+ 'openstack_puppet_groups',
 183+ array( 'group_name' => $name,
 184+ 'group_position' => $position
 185+ ),
 186+ __METHOD__
 187+ );
 188+ }
 189+
 190+ public static function addVar( $name, $position, $groupid ) {
 191+ $dbw = wfGetDB( DB_MASTER );
 192+ return $dbw->insert(
 193+ 'openstack_puppet_vars',
 194+ array( 'var_name' => $name,
 195+ 'var_position' => $position,
 196+ 'var_group_id' => $groupid
 197+ ),
 198+ __METHOD__
 199+ );
 200+ }
 201+
 202+ public static function addClass( $name, $position, $groupid ) {
 203+ $dbw = wfGetDB( DB_MASTER );
 204+ return $dbw->insert(
 205+ 'openstack_puppet_classes',
 206+ array( 'class_name' => $name,
 207+ 'class_position' => $position,
 208+ 'class_group_id' => $groupid
 209+ ),
 210+ __METHOD__
 211+ );
 212+ }
 213+
 214+ public static function deleteVar( $id ) {
 215+ $dbw = wfGetDB( DB_MASTER );
 216+ return $dbw->delete(
 217+ 'openstack_puppet_vars',
 218+ array( 'var_id' => $id ),
 219+ __METHOD__
 220+ );
 221+ }
 222+
 223+ public static function deleteClass( $id ) {
 224+ $dbw = wfGetDB( DB_MASTER );
 225+ return $dbw->delete(
 226+ 'openstack_puppet_classes',
 227+ array( 'class_id' => $id ),
 228+ __METHOD__
 229+ );
 230+ }
 231+
 232+ public static function deleteGroup( $id ) {
 233+ $dbw = wfGetDB( DB_MASTER );
 234+ // TODO: stuff this into a transaction
 235+ $dbw->delete(
 236+ 'openstack_puppet_vars',
 237+ array( 'var_group_id' => $id ),
 238+ __METHOD__
 239+ );
 240+ $dbw->delete(
 241+ 'openstack_puppet_classes',
 242+ array( 'class_group_id' => $id ),
 243+ __METHOD__
 244+ );
 245+ return $dbw->delete(
 246+ 'openstack_puppet_groups',
 247+ array( 'group_id' => $id ),
 248+ __METHOD__
 249+ );
 250+ }
 251+
 252+ public static function updateVar( $id, $groupid, $position ) {
 253+ $dbw = wfGetDB( DB_MASTER );
 254+ return $dbw->update(
 255+ 'openstack_puppet_vars',
 256+ array(
 257+ 'var_position' => $position,
 258+ 'var_group_id' => $groupid
 259+ ),
 260+ array( 'var_id' => $id ),
 261+ __METHOD__
 262+ );
 263+ }
 264+
 265+ public static function updateClass( $id, $groupid, $position ) {
 266+ $dbw = wfGetDB( DB_MASTER );
 267+ return $dbw->update(
 268+ 'openstack_puppet_classes',
 269+ array(
 270+ 'class_position' => $position,
 271+ 'class_group_id' => $groupid
 272+ ),
 273+ array( 'class_id' => $id ),
 274+ __METHOD__
 275+ );
 276+ }
 277+
 278+ public static function updateGroupPosition( $id, $position ) {
 279+ $dbw = wfGetDB( DB_MASTER );
 280+ return $dbw->update(
 281+ 'openstack_puppet_groups',
 282+ array(
 283+ 'group_position' => $position,
 284+ ),
 285+ array(
 286+ 'group_id' => $id,
 287+ ),
 288+ __METHOD__
 289+ );
 290+ }
 291+
 292+}

Comments

#Comment by Siebrand (talk | contribs)   08:41, 22 December 2011

Please add message documentation for the newly added messages. Thanks.

#Comment by Ryan lane (talk | contribs)   17:25, 22 December 2011

Yeah. Was going to do that in a follow up.

Status & tagging log