public function execute() { global $wgAuth; global $wgOpenStackManagerLDAPUsername; global $wgOpenStackManagerLDAPUserPassword; $user = new OpenStackNovaUser($wgOpenStackManagerLDAPUsername); $userNova = OpenStackNovaController::newFromUser($user); $projects = OpenStackNovaProject::getAllProjects(); # HACK (please fix): Keystone doesn't deliver services and endpoints unless # a project token is returned, so we need to feed it a project. Ideally this # should be configurable, and not hardcoded like this. $userNova->setProject('bastion'); $userNova->authenticate($wgOpenStackManagerLDAPUsername, $wgOpenStackManagerLDAPUserPassword); $regions = $userNova->getRegions('compute'); foreach ($regions as $region) { $this->output("Running region : " . $region . "\n"); foreach ($projects as $project) { $projectName = $project->getProjectName(); $this->output("Running project : " . $projectName . "\n"); $userNova->setProject($projectName); $userNova->setRegion($region); $instances = $userNova->getInstances(); if (!$instances) { $wgAuth->printDebug("No instance, continuing", NONSENSITIVE); continue; } foreach ($instances as $instance) { $this->output("Updating instance : " . $instance->getInstanceId() . "\n"); $instance->editArticle($userNova); } } } $this->output("Done.\n"); }
function execute() { $this->params = $this->extractRequestParams(); $this->userLDAP = new OpenStackNovaUser(); switch ($this->params['subaction']) { case 'getall': if (isset($this->params['project'])) { $projects = array(OpenStackNovaProject::getProjectByName($this->params['project'])); } else { $projects = OpenStackNovaProject::getAllProjects(); } $data = array(); foreach ($projects as $project) { $project->fetchProjectInfo(); if (!$project->loaded) { continue; } $projectName = $project->getProjectName(); $data[$projectName]['members'] = $project->getMembers(); $data[$projectName]['roles'] = array(); foreach ($project->getRoles() as $role) { $roleName = $role->getRoleName(); $data[$projectName]['roles'][$roleName] = array('members' => $role->getMembers()); $this->getResult()->setIndexedTagName($data[$projectName]['roles'][$roleName]['members'], 'member'); } $this->getResult()->setIndexedTagName($data[$projectName]['members'], 'member'); $this->getResult()->setIndexedTagName($data[$projectName]['roles'], 'roles'); } $this->getResult()->addValue(null, $this->getModuleName(), $data); break; case 'getuser': $data = array(); if ($this->params['username']) { $user = new OpenStackNovaUser($this->params['username']); } else { $user = $this->userLDAP; } $projectNames = $user->getProjects(); foreach ($projectNames as $projectName) { $project = OpenStackNovaProject::getProjectByName($projectName); $project->fetchProjectInfo(); if (!$project->loaded) { continue; } $projectName = $project->getProjectName(); $data[$projectName] = array(); $data[$projectName]['roles'] = array(); foreach ($project->getRoles() as $role) { if ($role->userInRole($user)) { $data[$projectName]['roles'][] = $role->getRoleName(); } } $this->getResult()->setIndexedTagName($data[$projectName]['roles'], 'role'); } $this->getResult()->setIndexedTagName($data, 'project'); $this->getResult()->addValue(null, $this->getModuleName(), $data); break; } }
public function execute() { global $wgAuth; global $wgOpenStackManagerLDAPUsername; global $wgOpenStackManagerLDAPUserPassword; if ($this->hasOption('all-instances')) { if ($this->hasOption('region')) { $this->error("--all-instances cannot be used with --region.\n", true); } $instancelist = array(); $user = new OpenStackNovaUser($wgOpenStackManagerLDAPUsername); $userNova = OpenStackNovaController::newFromUser($user); $projects = OpenStackNovaProject::getAllProjects(); $userNova->setProject('bastion'); $userNova->authenticate($wgOpenStackManagerLDAPUsername, $wgOpenStackManagerLDAPUserPassword); $regions = $userNova->getRegions('compute'); foreach ($regions as $region) { foreach ($projects as $project) { $projectName = $project->getProjectName(); $userNova->setProject($projectName); $userNova->setRegion($region); $instances = $userNova->getInstances(); if ($instances) { foreach ($instances as $instance) { $instancelist[] = array($region, $instance->getInstanceName(), $projectName); } } } } } elseif ($this->hasOption('name')) { if (!$this->hasOption('region')) { $this->error("--name requires --region.\n", true); } if (!$this->hasOption('project')) { $this->error("--name requires --project.\n", true); } $instancelist = array(array($this->getOption('region'), $this->getOption('name'), $this->getOption('project'))); } else { $this->error("Must specify either --name or --all-instances.\n", true); } if (!class_exists('OpenStackNovaHost')) { $this->error("Couldn't find OpenStackNovaHost class.\n", true); } OpenStackNovaLdapConnection::connect(); foreach ($instancelist as $instancepair) { list($instanceregion, $instancename, $instanceproject) = $instancepair; $host = OpenStackNovaHost::getHostByNameAndProject($instancename, $instanceproject, $instanceregion); if (!$host) { print "Skipping {$instancename}.{$instanceproject}.{$instanceregion}; not found.\n"; continue; } print "\nFor instance {$instancename} in region {$instanceregion} and project {$instanceproject}:\n\n"; $namefqdn = $instancename . '.' . $instanceproject . '.' . $instanceregion . '.' . 'wmflabs'; $host->addAssociatedDomain($namefqdn); } }
public function execute() { global $wgOpenStackManagerLDAPUsername; global $wgOpenStackManagerServiceGroupPrefix; $user = new OpenStackNovaUser($wgOpenStackManagerLDAPUsername); $projects = OpenStackNovaProject::getAllProjects(); $failedSync = false; $attempt_count = 0; $synced_count = 0; $failed_count = 0; /** * @var $project OpenStackNovaProject */ foreach ($projects as $project) { // actually load the project info from ldap // (getAllProjects() doesn't do this) $project->fetchProjectInfo(); $projectName = $project->getProjectName(); $serviceGroups = $project->getServiceGroups(); foreach ($serviceGroups as $serviceGroup) { $fullGroupName = $serviceGroup->getGroupName(); if (strpos($fullGroupName, $wgOpenStackManagerServiceGroupPrefix, 0) === 0) { $groupName = substr($fullGroupName, strlen($wgOpenStackManagerServiceGroupPrefix)); } else { $groupName = $fullGroupName; } $groupMembers = $serviceGroup->getMembers(); if (empty($groupMembers)) { continue; } $originalMember = $groupMembers[0]; $retval = OpenStackNovaServiceGroup::createServiceGroup($groupName, $project, $this->updateMemberName($originalMember, $project)); $attempt_count++; if ($retval) { $this->output("Succeeded copying service group {$groupName} in {$projectName}\n"); $synced_count++; foreach ($groupMembers as $member) { if ($member === $originalMember) { continue; } $serviceGroup->addMember($this->updateMemberName($member, $project)); } } else { $this->output("Failed copying service group {$groupName} in {$projectName}\n"); $failedSync = true; $failed_count++; } } } $this->output("{$attempt_count} service groups were synced, {$synced_count} changed, {$failed_count} failed.\n"); $this->output("Done.\n"); // return true if there were no failed syncs return !$failedSync; }
public function execute() { $projects = OpenStackNovaProject::getAllProjects(); foreach ($projects as $project) { $projectName = $project->getProjectName(); $project->fetchProjectInfo(); $this->output("Running project : " . $projectName . "\n"); $project->editArticle(); } $this->output("Done.\n"); }
public function run() { $projects = OpenStackNovaProject::getAllProjects(); foreach ($projects as $project) { $this->getResult()->addValue(array('query', $this->getModuleName()), null, $project->getName()); } if (defined('ApiResult::META_CONTENT')) { $this->getResult()->addIndexedTagName(array('query', $this->getModuleName()), 'project'); } else { $this->getResult()->setIndexedTagName_internal(array('query', $this->getModuleName()), 'project'); } }
public function execute() { global $wgOpenStackManagerLDAPUsername; $user = new OpenStackNovaUser($wgOpenStackManagerLDAPUsername); $projects = OpenStackNovaProject::getAllProjects(); $failedSync = false; $attempt_count = 0; $synced_count = 0; $failed_count = 0; /** * @var $project OpenStackNovaProject */ foreach ($projects as $project) { // actually load the project info from ldap // (getAllProjects() doesn't do this) $project->fetchProjectInfo(); $projectName = $project->getProjectName(); $retval = $project->syncProjectGroupMembers(); $attempt_count++; // -1: failure // 0: no change // 1: successful sync if ($retval != 0) { $this->output(($retval ? "Succeeded" : "Failed") . " syncing members for project {$projectName} and group " . $project->projectGroup->getProjectGroupName()); if ($retval < 0) { $failedSync = true; $failed_count++; } else { $synced_count++; } } // echo "\nproject member DNs:\n"; // print_r( $project->getMemberDNs() ); // echo "\nproject group member DNs:\n"; // print_r( $projectGroup->getMemberDNs() ); } $this->output("{$attempt_count} project groups were synced, {$synced_count} changed, {$failed_count} failed.\n"); $this->output("Done.\n"); // return true if there were no failed syncs return !$failedSync; }
public function execute() { global $wgAuth; global $wgOpenStackManagerLDAPUsername; global $wgOpenStackManagerLDAPUserPassword; $user = new OpenStackNovaUser($wgOpenStackManagerLDAPUsername); $userNova = OpenStackNovaController::newFromUser($user); $projects = OpenStackNovaProject::getAllProjects(); # HACK (please fix): Keystone doesn't deliver services and endpoints unless # a project token is returned, so we need to feed it a project. Ideally this # should be configurable, and not hardcoded like this. $userNova->setProject('bastion'); $userNova->authenticate($wgOpenStackManagerLDAPUsername, $wgOpenStackManagerLDAPUserPassword); $regions = $userNova->getRegions('compute'); foreach ($regions as $region) { $this->output("Running region: " . $region . "\n"); foreach ($projects as $project) { $projectName = $project->getProjectName(); $this->output("Running project: " . $projectName . "\n"); $userNova->setProject($projectName); $userNova->setRegion($region); $instances = $userNova->getInstances(); if (!$instances) { $wgAuth->printDebug("No instance, continuing", NONSENSITIVE); continue; } foreach ($instances as $instance) { $host = $instance->getHost(); if (!$host) { $this->output("Skipping instance due to missing host entry: " . $instance->getInstanceId() . "\n"); continue; } $this->output("Renaming instance: " . $instance->getInstanceId() . "\n"); $ot = Title::newFromText($instance->getInstanceId(), NS_NOVA_RESOURCE); $nt = Title::newFromText($host->getFullyQualifiedHostName(), NS_NOVA_RESOURCE); $ot->moveTo($nt, false, 'Maintenance script move from id to fqdn.'); } } } $this->output("Done.\n"); }
/** * @return void */ function listProjects() { $this->setHeaders(); $this->getOutput()->setPageTitle($this->msg('openstackmanager-projectlist')); $this->getOutput()->addModuleStyles('ext.openstack'); if ($this->getUser()->isAllowed('listall')) { $projects = OpenStackNovaProject::getAllProjects(); $this->showCreateProject(); } else { $projects = OpenStackNovaProject::getProjectsByName($this->userLDAP->getProjects()); } $this->showProjectFilter($projects); $projectfilter = $this->getProjectFilter(); if (!$projectfilter) { $this->getOutput()->addWikiMsg('openstackmanager-setprojectfilter'); return null; } $out = ''; foreach ($projects as $project) { $projectName = $project->getProjectName(); if (!in_array($projectName, $projectfilter)) { continue; } $actions = array(); $out .= $this->createProjectSection($projectName, $actions, $this->getProject($project)); } $this->getOutput()->addHTML($out); }
/** * @return bool */ function listSecurityGroups() { $this->setHeaders(); $this->getOutput()->addModuleStyles('ext.openstack'); $this->getOutput()->setPagetitle($this->msg('openstackmanager-securitygrouplist')); if ($this->userCanExecute($this->getUser())) { $projects = OpenStackNovaProject::getAllProjects(); } else { $projects = OpenStackNovaProject::getProjectsByName($this->userLDAP->getProjects()); } $this->showProjectFilter($projects); $projectfilter = $this->getProjectFilter(); if (!$projectfilter) { $this->getOutput()->addWikiMsg('openstackmanager-setprojectfilter'); return null; } $out = ''; foreach ($projects as $project) { $projectName = $project->getProjectName(); if (!in_array($projectName, $projectfilter)) { continue; } $projectactions = array('projectadmin' => array()); $regions = ''; $this->userNova->setProject($projectName); foreach ($this->userNova->getRegions('compute') as $region) { $this->userNova->setRegion($region); $regionactions = array('projectadmin' => array($this->createActionLink('openstackmanager-createnewsecuritygroup', array('action' => 'create', 'project' => $projectName, 'region' => $region)))); $securityGroups = $this->getSecurityGroups($projectName, $region); $regions .= $this->createRegionSection($region, $projectName, $regionactions, $securityGroups); } $out .= $this->createProjectSection($projectName, $projectactions, $regions); } $this->getOutput()->addHTML($out); return true; }
/** * Default action * @return void */ function listInstances() { global $wgOpenStackManagerReadOnlyRegions; $this->setHeaders(); $this->getOutput()->addModules('ext.openstack.Instance'); $this->getOutput()->setPagetitle($this->msg('openstackmanager-instancelist')); if ($this->getUser()->isAllowed('listall')) { $projects = OpenStackNovaProject::getAllProjects(); } else { $projects = OpenStackNovaProject::getProjectsByName($this->userLDAP->getProjects()); } $this->showProjectFilter($projects); $projectfilter = $this->getProjectFilter(); if (!$projectfilter) { $this->getOutput()->addWikiMsg('openstackmanager-setprojectfilter'); return null; } $out = ''; foreach ($projects as $project) { $projectName = $project->getProjectName(); if (!in_array($projectName, $projectfilter)) { continue; } $projectactions = array('projectadmin' => array()); $regions = ''; $this->userNova->setProject($projectName); foreach ($this->userNova->getRegions('compute') as $region) { if (in_array($region, $wgOpenStackManagerReadOnlyRegions)) { $regionactions = array('projectadmin' => array($this->msg('openstackmanager-creationdisabled'))); } else { $regionactions = array('projectadmin' => array($this->createActionLink('openstackmanager-createinstance', array('action' => 'create', 'project' => $projectName, 'region' => $region)))); } $instances = $this->getInstances($projectName, $region); $regions .= $this->createRegionSection($region, $projectName, $regionactions, $instances); } $out .= $this->createProjectSection($projectName, $projectactions, $regions); } $this->getOutput()->addHTML($out); }
/** * @return void */ function listProjects() { $this->setHeaders(); $this->getOutput()->setPageTitle( wfMsg( 'openstackmanager-projectlist' ) ); $this->getOutput()->addModuleStyles( 'ext.openstack' ); if ( $this->userLDAP->inGlobalRole( 'cloudadmin' ) ) { $projectInfo = array(); $projectInfo['projectname'] = array( 'type' => 'text', 'label-message' => 'openstackmanager-projectname', 'validation-callback' => array( $this, 'validateText' ), 'default' => '', 'section' => 'project', 'name' => 'projectname', ); $projectInfo['member'] = array( 'type' => 'text', 'label-message' => 'openstackmanager-member', 'default' => '', 'section' => 'project', 'name' => 'member', ); $role_keys = array(); foreach ( OpenStackNovaProject::$rolenames as $rolename ) { $role_keys["$rolename"] = $rolename; } $projectInfo['roles'] = array( 'type' => 'multiselect', 'label-message' => 'openstackmanager-roles', 'section' => 'project', 'options' => $role_keys, 'name' => 'roles', ); $projectInfo['action'] = array( 'type' => 'hidden', 'default' => 'create', 'name' => 'action', ); $projectForm = new SpecialNovaProjectForm( $projectInfo, 'openstackmanager-novaproject' ); $projectForm->setTitle( SpecialPage::getTitleFor( 'NovaProject' ) ); $projectForm->setSubmitID( 'novaproject-form-createprojectsubmit' ); $projectForm->setSubmitCallback( array( $this, 'tryCreateSubmit' ) ); $projectForm->show(); } $out = ''; $header = Html::element( 'th', array(), wfMsg( 'openstackmanager-members' ) ); $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-roles' ) ); $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-actions' ) ); $projects = OpenStackNovaProject::getAllProjects(); if ( ! $projects ) { $projectsOut = ''; } foreach ( $projects as $project ) { $projectName = $project->getProjectName(); $projectName = htmlentities( $projectName ); $out .= Html::rawElement( 'h2', array( 'class' => 'mw-customtoggle-' . $projectName, 'id' => 'novaproject' ), $projectName ); $projectMembers = $project->getMembers(); $memberOut = ''; foreach ( $projectMembers as $projectMember ) { $memberOut .= Html::element( 'li', array(), $projectMember ); } if ( $memberOut ) { $memberOut = Html::rawElement( 'ul', array(), $memberOut ); } $projectOut = Html::rawElement( 'td', array(), $memberOut ); $rolesOut = Html::element( 'th', array(), wfMsg( 'openstackmanager-rolename' ) ); $rolesOut .= Html::element( 'th', array(), wfMsg( 'openstackmanager-members' ) ); $rolesOut .= Html::element( 'th', array(), wfMsg( 'openstackmanager-actions' ) ); foreach ( $project->getRoles() as $role ) { $roleOut = Html::element( 'td', array(), $role->getRoleName() ); $roleMembers = ''; $specialRoleTitle = Title::newFromText( 'Special:NovaRole' ); foreach ( $role->getMembers() as $member ) { $roleMembers .= Html::element( 'li', array(), $member ); } $roleMembers = Html::rawElement( 'ul', array(), $roleMembers ); $roleOut .= Html::rawElement( 'td', array(), $roleMembers ); $link = Linker::link( $specialRoleTitle, wfMsgHtml( 'openstackmanager-addrolemember' ), array(), array( 'action' => 'addmember', 'projectname' => $projectName, 'rolename' => $role->getRoleName(), 'returnto' => 'Special:NovaProject' ) ); $actions = Html::rawElement( 'li', array(), $link ); $link = Linker::link( $specialRoleTitle, wfMsgHtml( 'openstackmanager-removerolemember' ), array(), array( 'action' => 'deletemember', 'projectname' => $projectName, 'rolename' => $role->getRoleName(), 'returnto' => 'Special:NovaProject' ) ); $actions .= Html::rawElement( 'li', array(), $link ); $actions = Html::rawElement( 'ul', array(), $actions ); $roleOut .= Html::rawElement( 'td', array(), $actions ); $rolesOut .= Html::rawElement( 'tr', array(), $roleOut ); } $rolesOut = Html::rawElement( 'table', array( 'class' => 'wikitable sortable collapsible' ), $rolesOut ); $projectOut .= Html::rawElement( 'td', array( 'class' => 'Nova_cell' ), $rolesOut ); $link = Linker::link( $this->getTitle(), wfMsgHtml( 'openstackmanager-deleteproject' ), array(), array( 'action' => 'delete', 'projectname' => $projectName ) ); $actions = Html::rawElement( 'li', array(), $link ); $link = Linker::link( $this->getTitle(), wfMsgHtml( 'openstackmanager-addmember' ), array(), array( 'action' => 'addmember', 'projectname' => $projectName ) ); $actions .= Html::rawElement( 'li', array(), $link ); $link = Linker::link( $this->getTitle(), wfMsgHtml( 'openstackmanager-removemember' ), array(), array( 'action' => 'deletemember', 'projectname' => $projectName ) ); $actions .= Html::rawElement( 'li', array(), $link ); $actions = Html::rawElement( 'ul', array(), $actions ); $projectOut .= Html::rawElement( 'td', array(), $actions ); $projectOut = Html::rawElement( 'tr', array(), $projectOut ); $projectOut = $header . $projectOut; $projectOut = Html::rawElement( 'table', array( 'class' => 'wikitable sortable collapsible' ), $projectOut ); $out .= Html::rawElement( 'div', array( 'class' => 'mw-collapsible', 'id' => 'mw-customcollapsible-' . $projectName ), $projectOut ); } $this->getOutput()->addHTML( $out ); }
public function execute() { global $wgOpenStackManagerLDAPUsername; global $wgAuth; $user = new OpenStackNovaUser($wgOpenStackManagerLDAPUsername); $projects = OpenStackNovaProject::getAllProjects(); $failedSync = false; $attempt_count = 0; $synced_count = 0; $failed_count = 0; /** * @var $project OpenStackNovaProject */ foreach ($projects as $project) { // actually load the project info from ldap // (getAllProjects() doesn't do this) $project->fetchProjectInfo(); $projectName = $project->getProjectName(); $oldServiceGroupOUDN = 'ou=groups,' . $project->getProjectDN(); $oldServiceUserOUDN = 'ou=people,' . $project->getProjectDN(); $result = LdapAuthenticationPlugin::ldap_search($wgAuth->ldapconn, $oldServiceGroupOUDN, '(objectclass=groupofnames)'); if ($result) { $this->serviceGroups = array(); $groupList = LdapAuthenticationPlugin::ldap_get_entries($wgAuth->ldapconn, $result); if (isset($groupList)) { array_shift($groupList); foreach ($groupList as $groupEntry) { $deleteme = "cn=" . $groupEntry['cn'][0] . "," . $oldServiceGroupOUDN; print "needs deleting: " . $deleteme . "..."; $attempt_count++; $success = LdapAuthenticationPlugin::ldap_delete($wgAuth->ldapconn, $deleteme); if ($success) { $synced_count++; print "done.\n"; } else { $failed_count++; print "FAILED\n"; } } } } $result = LdapAuthenticationPlugin::ldap_search($wgAuth->ldapconn, $oldServiceUserOUDN, '(objectclass=person)'); if ($result) { $this->serviceGroups = array(); $groupList = LdapAuthenticationPlugin::ldap_get_entries($wgAuth->ldapconn, $result); if (isset($groupList)) { array_shift($groupList); foreach ($groupList as $groupEntry) { $deleteme = "uid=" . $groupEntry['cn'][0] . "," . $oldServiceUserOUDN; print "user needs deleting: " . $deleteme . "..."; $attempt_count++; $success = LdapAuthenticationPlugin::ldap_delete($wgAuth->ldapconn, $deleteme); if ($success) { $synced_count++; print "done.\n"; } else { $failed_count++; print "FAILED\n"; } } } } $deleteme = $oldServiceGroupOUDN; print "ou needs deleting: " . $deleteme . "..."; $attempt_count++; $success = LdapAuthenticationPlugin::ldap_delete($wgAuth->ldapconn, $deleteme); if ($success) { $synced_count++; print "done.\n"; } else { $failed_count++; print "FAILED\n"; } $deleteme = $oldServiceUserOUDN; print "ou needs deleting: " . $deleteme . "..."; $attempt_count++; $success = LdapAuthenticationPlugin::ldap_delete($wgAuth->ldapconn, $deleteme); if ($success) { $synced_count++; print "done.\n"; } else { $failed_count++; print "FAILED\n"; } } $this->output("{$attempt_count} items needed cleanup. {$synced_count} removed, {$failed_count} failed.\n"); $this->output("Done.\n"); return $failed_count == 0; }
/** * @return void */ function listPuppetGroups() { $this->setHeaders(); $this->getOutput()->setPagetitle($this->msg('openstackmanager-puppetgrouplist')); $this->getOutput()->addModuleStyles('ext.openstack'); if ($this->getUser()->isAllowed('listall')) { $projects = OpenStackNovaProject::getAllProjects(); } else { $projects = OpenStackNovaProject::getProjectsByName($this->userLDAP->getProjects()); } $this->showProjectFilter($projects); $projectfilter = $this->getProjectFilter(); if (!$projectfilter) { $this->getOutput()->addWikiMsg('openstackmanager-setprojectfilter'); return null; } $out = ''; foreach ($projects as $project) { $projectName = $project->getProjectName(); if ($projectfilter && !in_array($projectName, $projectfilter)) { continue; } $actions = array('projectadmin' => array()); $actions['projectadmin'][] = $this->createActionLink('openstackmanager-createpuppetgroup', array('action' => 'create', 'project' => $projectName)); $out .= $this->createProjectSection($projectName, $actions, $this->getPuppetGroupOutput(OpenStackNovaPuppetGroup::getGroupList($projectName))); } $action = ''; $showlinks = $this->userCanExecute($this->getUser()); if ($showlinks) { $action = $this->createActionLink('openstackmanager-createpuppetgroup', array('action' => 'create')); $action = Html::rawElement('span', array('id' => 'novaaction'), "[{$action}]"); } $allProjectsMsg = Html::rawElement('span', array('class' => 'mw-customtoggle-allprojects', 'id' => 'novaproject'), $this->msg('openstackmanager-puppetallprojects')->escaped()); $out .= Html::rawElement('h2', array(), "{$allProjectsMsg} {$action}"); $groupsOut = $this->getPuppetGroupOutput(OpenStackNovaPuppetGroup::getGroupList(), $showlinks); $out .= Html::rawElement('div', array('class' => 'mw-collapsible', 'id' => 'mw-customcollapsible-allprojects'), $groupsOut); $this->getOutput()->addHTML($out); }