/** * @return void */ function listVolumes() { $this->setHeaders(); $this->getOutput()->addModuleStyles('ext.openstack'); $this->getOutput()->setPagetitle($this->msg('openstackmanager-volumelist')); 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) { $regionactions = array('projectadmin' => array($this->createActionLink('openstackmanager-createvolume', array('action' => 'create', 'project' => $projectName, 'region' => $region)))); $volumes = $this->getVolumes($projectName, $region); $regions .= $this->createRegionSection($region, $projectName, $regionactions, $volumes); } $out .= $this->createProjectSection($projectName, $projectactions, $regions); } $this->getOutput()->addHTML($out); }
/** * @return bool */ function removeRule() { $this->setHeaders(); $this->getOutput()->setPagetitle($this->msg('openstackmanager-removerule')); $project = $this->getRequest()->getText('project'); $region = $this->getRequest()->getText('region'); if (!$this->userLDAP->inRole('projectadmin', $project)) { $this->notInRole('projectadmin', $project); return false; } $groupid = $this->getRequest()->getText('groupid'); $ruleid = $this->getRequest()->getText('ruleid'); if (!$this->getRequest()->wasPosted()) { $securitygroup = $this->userNova->getSecurityGroup($groupid); if ($securitygroup) { $securitygroupname = $securitygroup->getGroupName(); $this->getOutput()->addWikiMsg('openstackmanager-removerule-confirm', $securitygroupname); } else { $this->getOutput()->addWikiMsg('openstackmanager-nonexistantsecuritygroup'); return false; } } $securityGroupInfo = array(); $securityGroupInfo['groupid'] = array('type' => 'hidden', 'default' => $groupid, 'name' => 'groupid'); $securityGroupInfo['ruleid'] = array('type' => 'hidden', 'default' => $ruleid, 'name' => 'ruleid'); $securityGroupInfo['project'] = array('type' => 'hidden', 'default' => $project, 'name' => 'project'); $securityGroupInfo['region'] = array('type' => 'hidden', 'default' => $region, 'name' => 'region'); $securityGroupInfo['action'] = array('type' => 'hidden', 'default' => 'removerule', 'name' => 'action'); $securityGroupForm = new HTMLForm($securityGroupInfo, $this->getContext(), 'openstackmanager-novasecuritygroup'); $securityGroupForm->setSubmitID('novainstance-form-removerulesubmit'); $securityGroupForm->setSubmitCallback(array($this, 'tryRemoveRuleSubmit')); $securityGroupForm->show(); return true; }
/** * @param $formData * @param string $entryPoint * @return bool */ function tryDeleteSubmit($formData, $entryPoint = 'internal') { $success = $this->userLDAP->deleteKeypair($formData['key']); if ($success) { $this->getOutput()->addWikiMsg('openstackmanager-deletedkey'); } else { $this->getOutput()->addWikiMsg('openstackmanager-deletedkeyfailed'); } $out = '<br />'; $out .= Linker::link($this->getTitle(), wfMsgHtml('openstackmanager-backkeylist')); $this->getOutput()->addHTML($out); return true; }
/** * getUserPermissionsErrors hook * * @param Title $title * @param User $user * @param string $action * @param $result * @return bool */ public static function getUserPermissionsErrors(Title $title, User $user, $action, &$result) { if (!$title->inNamespace(NS_HIERA)) { return true; } if ($action === 'create' || $action === 'edit') { if (!$user->isLoggedIn()) { $result = array('openstackmanager-notloggedin'); return false; } $userLDAP = new OpenStackNovaUser(); if (!$userLDAP->exists()) { $result = array('openstackmanager-nonovacred-admincreate'); } $project = $title->getText(); if (!$userLDAP->inRole('projectadmin', $project) && !$user->isAllowed('editallhiera')) { $result = array('openstackmanager-hiera-noadmin', $project); return false; } } return true; }
/** * @param $formData * @param string $entryPoint * @return bool */ function tryDeleteSubmit($formData, $entryPoint = 'internal') { $success = $this->userLDAP->deleteKeypair($formData['key']); if ($success) { $this->getOutput()->addWikiMsg('openstackmanager-deletedkey'); } else { $this->getOutput()->addWikiMsg('openstackmanager-deletedkeyfailed'); } $returnto = Title::newFromText($formData['returnto']); if ($returnto) { $this->getOutput()->addReturnTo($returnto); } return true; }
function getInstances($projectName, $region, &$instanceCount) { global $wgMemc; $this->userNova->setRegion($region); $headers = array('openstackmanager-instancename', 'openstackmanager-instanceid', 'openstackmanager-instancestate', 'openstackmanager-instanceip', 'openstackmanager-projectname', 'openstackmanager-launchtime', 'openstackmanager-instancecreator'); $instances = $this->userNova->getInstances(); $instanceRows = array(); $instanceCount = 0; /** * @var $instance OpenStackNovaInstance */ foreach ($instances as $instance) { # Only display instances created by the current user. if ($instance->getInstanceCreator() != $this->userLDAP->getUid()) { continue; } $instanceRow = array(); $this->pushResourceColumn($instanceRow, $instance->getInstanceName(), array('class' => 'novainstancename')); $host = $instance->getHost(); if ($host) { $this->pushRawResourceColumn($instanceRow, $this->createResourceLink($host->getFullyQualifiedHostName()), array('class' => 'novainstanceid')); } else { $this->pushResourceColumn($instanceRow, $instance->getInstanceId(), array('class' => 'novainstanceid')); } $state = $instance->getInstanceState(); $taskState = $instance->getInstanceTaskState(); if ($taskState) { $stateDisplay = "{$state} ({$taskState})"; } else { $stateDisplay = $state; } $this->pushResourceColumn($instanceRow, $stateDisplay, array('class' => 'novainstancestate')); $this->pushRawResourceColumn($instanceRow, $this->createResourceList($instance->getInstancePrivateIPs())); $this->pushResourceColumn($instanceRow, $projectName); $this->pushResourceColumn($instanceRow, $instance->getLaunchTime()); $this->pushResourceColumn($instanceRow, $instance->getInstanceCreator()); $actions = array(); $instanceDataAttributes = array('data-osid' => $instance->getInstanceOSId(), 'data-id' => $instance->getInstanceId(), 'data-name' => $instance->getInstanceName(), 'data-project' => $projectName, 'data-region' => $region, 'class' => 'novainstanceaction'); $instanceRows[] = $instanceRow; $instanceCount += 1; } if ($instanceRows) { return $this->createResourceTable($headers, $instanceRows); } return ''; }
/** * @param $formData * @param string $entryPoint * @return bool */ function tryRemoveRuleSubmit( $formData, $entryPoint = 'internal' ) { $project = $formData['project']; $fromport = $formData['fromport']; $toport = $formData['toport']; $protocol = $formData['protocol']; if ( isset( $formData['ranges'] ) ) { $ranges = explode( ',', $formData['ranges'] ); } else { $ranges = array(); } $groups = array(); if ( isset( $formData['groups'] ) ) { $rawgroups = explode( ',', $formData['groups'] ); foreach ( $rawgroups as $rawgroup ) { $rawgroup = explode( ':', $rawgroup ); $groups[] = array( 'groupname' => $rawgroup[0], 'project' => $rawgroup[1] ); } } $userCredentials = $this->userLDAP->getCredentials(); $this->userNova = new OpenStackNovaController( $userCredentials, $project ); $securitygroup = $this->adminNova->getSecurityGroup( $formData['groupname'], $project ); if ( ! $securitygroup ) { $this->getOutput()->addWikiMsg( 'openstackmanager-nonexistantsecuritygroup' ); return false; } $groupname = $securitygroup->getGroupName(); $success = $this->userNova->removeSecurityGroupRule( $groupname, $fromport, $toport, $protocol, $ranges, $groups ); if ( $success ) { # TODO: Ensure group isn't being used $this->getOutput()->addWikiMsg( 'openstackmanager-removedrule' ); } else { $this->getOutput()->addWikiMsg( 'openstackmanager-removerulefailed' ); } $out = '<br />'; $out .= Linker::link( $this->getTitle(), wfMsgHtml( 'openstackmanager-backsecuritygrouplist' ) ); $this->getOutput()->addHTML( $out ); return true; }
/** * @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); }
/** * @static * @param $groupName * @param $project OpenStackNovaProject * @param $initialUser * @return null|OpenStackNovaServiceGroup */ static function createServiceGroup($inGroupName, $project, $initialUser) { global $wgAuth; global $wgOpenStackManagerLDAPUser; global $wgOpenStackManagerLDAPDefaultShell; global $wgOpenStackManagerLDAPServiceGroupBaseDN; global $wgMemc; OpenStackNovaLdapConnection::connect(); $projectPrefix = $project->getProjectName() . '.'; # We don't want naming collisions between service groups and actual groups # or users. So, prepend $projectPrefix to the requested group name. if (strpos($inGroupName, $projectPrefix, 0) === 0) { # The user was clever and already added the prefix. $groupName = $inGroupName; $simpleGroupName = substr($inGroupName, strlen($projectPrefix)); } else { $groupName = $projectPrefix . $inGroupName; $simpleGroupName = $inGroupName; } if ($initialUser) { $user = new OpenStackNovaUser($initialUser); if (!$user->userDN) { $wgAuth->printDebug("Unable to find initial user {$initialUser} for new group {$groupName}", NONSENSITIVE); return null; } $initialUserDN = $user->userDN; } $key = wfMemcKey('openstackmanager', 'servicegroup', $groupName); $wgMemc->delete($key); $group = array(); $group['objectclass'][] = 'posixgroup'; $group['objectclass'][] = 'groupofnames'; $group['cn'] = $groupName; $groupdn = 'cn=' . $groupName . ',' . $wgOpenStackManagerLDAPServiceGroupBaseDN; $group['gidnumber'] = OpenStackNovaUser::getNextIdNumber($wgAuth, 'gidnumber'); $group['member'] = array(); if ($initialUser) { $group['member'][] = $initialUserDN; } $success = LdapAuthenticationPlugin::ldap_add($wgAuth->ldapconn, $groupdn, $group); if ($success) { $wgAuth->printDebug("Successfully added service group {$groupdn}", NONSENSITIVE); } else { $wgAuth->printDebug("Failed to add service group {$groupdn}", NONSENSITIVE); return null; } # stamp out regular expressions! $homeDir = $project->getServiceGroupHomedirPattern(); $homeDir = str_ireplace('%u', $simpleGroupName, $homeDir); $homeDir = str_ireplace('%p', $projectPrefix, $homeDir); # Now create the special SG member $newGroup = self::getServiceGroupByName($groupName, $project); $userdn = $newGroup->getSpecialUserDN(); $user = array(); $user['objectclass'][] = 'shadowaccount'; $user['objectclass'][] = 'posixaccount'; $user['objectclass'][] = 'person'; $user['objectclass'][] = 'top'; $user['loginshell'] = $wgOpenStackManagerLDAPDefaultShell; $user['homedirectory'] = $homeDir; $user['uidnumber'] = $group['gidnumber']; $user['gidnumber'] = $group['gidnumber']; $user['uid'] = $groupName; $user['sn'] = $groupName; $user['cn'] = $groupName; $success = LdapAuthenticationPlugin::ldap_add($wgAuth->ldapconn, $userdn, $user); if ($success) { $wgAuth->printDebug("Successfully created service user {$userdn}", NONSENSITIVE); } else { $wgAuth->printDebug("Failed to create service user {$userdn}", NONSENSITIVE); return null; } # Create Sudo policy so that the service user can chown files in its homedir if (OpenStackNovaSudoer::createSudoer($groupName . '-chmod', $project->getProjectName(), array($groupName), array(), array('/bin/chown -R ' . $groupName . '\\:' . $groupName . ' ' . $homeDir), array('!authenticate'))) { $wgAuth->printDebug("Successfully created chmod sudo policy for {$groupName}", NONSENSITIVE); } else { $wgAuth->printDebug("Failed to creat chmod sudo policy for {$groupName}", NONSENSITIVE); } # Create Sudo policy so that members of the group can sudo as the service user if (OpenStackNovaSudoer::createSudoer('runas-' . $groupName, $project->getProjectName(), array("%" . $groupName), array($groupName), array('ALL'), array('!authenticate'))) { $wgAuth->printDebug("Successfully created run-as sudo policy for {$groupName}", NONSENSITIVE); } else { $wgAuth->printDebug("Failed to creat run-as sudo policy for {$groupName}", NONSENSITIVE); } return $newGroup; }
/** * @return void */ function listInstances() { $this->setHeaders(); $this->getOutput()->addModuleStyles('ext.openstack'); $this->getOutput()->setPagetitle(wfMsg('openstackmanager-instancelist')); $userProjects = $this->userLDAP->getProjects(); $out = ''; $instances = $this->adminNova->getInstances(); $header = Html::element('th', array(), wfMsg('openstackmanager-instancename')); $header .= Html::element('th', array(), wfMsg('openstackmanager-instanceid')); $header .= Html::element('th', array(), wfMsg('openstackmanager-instancestate')); $header .= Html::element('th', array(), wfMsg('openstackmanager-instancetype')); $header .= Html::element('th', array(), wfMsg('openstackmanager-instanceip')); $header .= Html::element('th', array(), wfMsg('openstackmanager-instancepublicip')); $header .= Html::element('th', array(), wfMsg('openstackmanager-securitygroups')); $header .= Html::element('th', array(), wfMsg('openstackmanager-availabilityzone')); $header .= Html::element('th', array(), wfMsg('openstackmanager-imageid')); $header .= Html::element('th', array(), wfMsg('openstackmanager-launchtime')); $header .= Html::element('th', array(), wfMsg('openstackmanager-actions')); $projectArr = array(); /** * @var $instance OpenStackNovaInstance */ foreach ($instances as $instance) { $project = $instance->getOwner(); if (!in_array($project, $userProjects)) { continue; } $instanceOut = Html::element('td', array(), $instance->getInstanceName()); $instanceId = $instance->getInstanceId(); $instanceId = htmlentities($instanceId); $title = Title::newFromText($instanceId, NS_NOVA_RESOURCE); $instanceIdLink = Linker::link($title, $instanceId); $instanceOut .= Html::rawElement('td', array(), $instanceIdLink); $instanceOut .= Html::element('td', array(), $instance->getInstanceState()); $instanceOut .= Html::element('td', array(), $instance->getInstanceType()); $privateip = $instance->getInstancePrivateIP(); $publicip = $instance->getInstancePublicIP(); $instanceOut .= Html::element('td', array(), $privateip); if ($privateip != $publicip) { $instanceOut .= Html::element('td', array(), $publicip); } else { $instanceOut .= Html::element('td', array(), ''); } $groupsOut = ''; foreach ($instance->getSecurityGroups() as $group) { $groupsOut .= Html::element('li', array(), $group); } $groupsOut = Html::rawElement('ul', array(), $groupsOut); $instanceOut .= Html::rawElement('td', array(), $groupsOut); $instanceOut .= Html::element('td', array(), $instance->getAvailabilityZone()); $instanceOut .= Html::element('td', array(), $instance->getImageId()); $instanceOut .= Html::element('td', array(), $instance->getLaunchTime()); $actions = ''; if ($this->userLDAP->inRole('sysadmin', $project)) { $msg = wfMsgHtml('openstackmanager-delete'); $link = Linker::link($this->getTitle(), $msg, array(), array('action' => 'delete', 'project' => $project, 'instanceid' => $instance->getInstanceId())); $actions = Html::rawElement('li', array(), $link); $msg = wfMsgHtml('openstackmanager-reboot'); $link = Linker::link($this->getTitle(), $msg, array(), array('action' => 'reboot', 'project' => $project, 'instanceid' => $instance->getInstanceId())); $actions .= Html::rawElement('li', array(), $link); $msg = wfMsgHtml('openstackmanager-configure'); $link = Linker::link($this->getTitle(), $msg, array(), array('action' => 'configure', 'project' => $project, 'instanceid' => $instance->getInstanceId())); $actions .= Html::rawElement('li', array(), $link); $msg = wfMsgHtml('openstackmanager-getconsoleoutput'); $link = Linker::link($this->getTitle(), $msg, array(), array('action' => 'consoleoutput', 'project' => $project, 'instanceid' => $instance->getInstanceId())); $actions .= Html::rawElement('li', array(), $link); $actions = Html::rawElement('ul', array(), $actions); } $instanceOut .= Html::rawElement('td', array(), $actions); if (isset($projectArr["{$project}"])) { $projectArr["{$project}"] .= Html::rawElement('tr', array(), $instanceOut); } else { $projectArr["{$project}"] = Html::rawElement('tr', array(), $instanceOut); } } foreach ($userProjects as $project) { $action = ''; if ($this->userLDAP->inRole('sysadmin', $project)) { $action = Linker::link($this->getTitle(), wfMsgHtml('openstackmanager-createinstance'), array(), array('action' => 'create', 'project' => $project)); $action = Html::rawElement('span', array('id' => 'novaaction'), "[{$action}]"); } $projectName = Html::rawElement('span', array('class' => 'mw-customtoggle-' . $project, 'id' => 'novaproject'), $project); $out .= Html::rawElement('h2', array(), "{$projectName} {$action}"); $projectOut = ''; if (isset($projectArr["{$project}"])) { $projectOut .= $header; $projectOut .= $projectArr["{$project}"]; $projectOut = Html::rawElement('table', array('id' => 'novainstancelist', 'class' => 'wikitable sortable'), $projectOut); } $out .= Html::rawElement('div', array('class' => 'mw-collapsible', 'id' => 'mw-customcollapsible-' . $project), $projectOut); } $this->getOutput()->addHTML($out); }
/** * Hook to add objectclasses and attributes for users that already exist, but have * missing information. * * @static * @param $auth * @return bool */ static function LDAPSetNovaInfo( $auth ) { global $wgMemc; OpenStackNovaLdapConnection::connect(); $result = LdapAuthenticationPlugin::ldap_read( $auth->ldapconn, $auth->userInfo[0]['dn'], '(objectclass=*)', array( 'secretkey', 'accesskey', 'objectclass' ) ); $userInfo = LdapAuthenticationPlugin::ldap_get_entries( $auth->ldapconn, $result ); if ( !isset( $userInfo[0]['accesskey'] ) or !isset( $userInfo[0]['secretkey'] ) ) { $objectclasses = $userInfo[0]['objectclass']; # First entry is a count array_shift( $objectclasses ); if ( !in_array( 'novauser', $objectclasses ) ) { $values['objectclass'] = array(); # ldap_modify for objectclasses requires the array indexes be sequential. # It is stupid, yes. foreach ( $objectclasses as $objectclass ) { $values['objectclass'][] = $objectclass; } $values['objectclass'][] = 'novauser'; } $values['accesskey'] = OpenStackNovaUser::uuid4(); $values['secretkey'] = OpenStackNovaUser::uuid4(); $values['isnovaadmin'] = 'FALSE'; $success = LdapAuthenticationPlugin::ldap_modify( $auth->ldapconn, $auth->userdn, $values ); if ( $success ) { $key = wfMemcKey( 'ldapauthentication', 'userinfo', $auth->userdn ); $wgMemc->delete( $key ); $auth->printDebug( "Successfully modified the user's nova attributes", NONSENSITIVE ); return true; } else { $auth->printDebug( "Failed to modify the user's nova attributes.", NONSENSITIVE ); # Always return true, other hooks should still run, even if this fails return true; } } else { $auth->printDebug( "User has accesskey and secretkey set.", NONSENSITIVE ); return true; } }
function getInstances($projectName, $region) { global $wgMemc; $this->userNova->setRegion($region); $headers = array('openstackmanager-instancename', 'openstackmanager-instanceid', 'openstackmanager-instancestate', 'openstackmanager-instanceip', 'openstackmanager-instancepublicip', 'openstackmanager-securitygroups', 'openstackmanager-imageid', 'openstackmanager-launchtime', 'openstackmanager-actions'); $instances = $this->userNova->getInstances(); $instanceRows = array(); /** * @var $instance OpenStackNovaInstance */ foreach ($instances as $instance) { $instanceRow = array(); $this->pushResourceColumn($instanceRow, $instance->getInstanceName(), array('class' => 'novainstancename')); $host = $instance->getHost(); if ($host) { $this->pushRawResourceColumn($instanceRow, $this->createResourceLink($host->getFullyQualifiedHostName()), array('class' => 'novainstanceid')); } else { $this->pushResourceColumn($instanceRow, $instance->getInstanceId(), array('class' => 'novainstanceid')); } $state = $instance->getInstanceState(); $taskState = $instance->getInstanceTaskState(); if ($taskState) { $stateDisplay = "{$state} ({$taskState})"; } else { $stateDisplay = $state; } $this->pushResourceColumn($instanceRow, $stateDisplay, array('class' => 'novainstancestate')); $this->pushRawResourceColumn($instanceRow, $this->createResourceList($instance->getInstancePrivateIPs())); $this->pushRawResourceColumn($instanceRow, $this->createResourceList($instance->getInstancePublicIPs())); $this->pushRawResourceColumn($instanceRow, $this->createResourceList($instance->getSecurityGroups())); $imageId = $instance->getImageId(); $key = wfMemcKey('openstackmanager', "imagename", $imageId); $imageNameRet = $wgMemc->get($key); if (is_string($imageNameRet)) { $imageName = $imageNameRet; } else { $image = $this->userNova->getImage($imageId); if ($image) { $imageName = $image->getImageName(); $wgMemc->set($key, $imageName, 86400); } else { $imageName = $this->msg('openstackmanager-missingimage')->text(); } } $this->pushResourceColumn($instanceRow, $imageName); $this->pushResourceColumn($instanceRow, $instance->getLaunchTime()); $actions = array(); $instanceDataAttributes = array('data-osid' => $instance->getInstanceOSId(), 'data-id' => $instance->getInstanceId(), 'data-name' => $instance->getInstanceName(), 'data-project' => $projectName, 'data-region' => $region, 'class' => 'novainstanceaction'); if ($this->userLDAP->inRole('projectadmin', $projectName)) { $actions[] = $this->createActionLink('openstackmanager-delete', array('action' => 'delete', 'instanceid' => $instance->getInstanceOSId(), 'project' => $projectName, 'region' => $region), null, $instanceDataAttributes); $actions[] = $this->createActionLink('openstackmanager-reboot', array('action' => 'reboot', 'instanceid' => $instance->getInstanceOSId(), 'project' => $projectName, 'region' => $region), null, $instanceDataAttributes); $actions[] = $this->createActionLink('openstackmanager-configure', array('action' => 'configure', 'instanceid' => $instance->getInstanceOSId(), 'project' => $projectName, 'region' => $region)); $actions[] = $this->createActionLink('openstackmanager-getconsoleoutput', array('action' => 'consoleoutput', 'instanceid' => $instance->getInstanceOSId(), 'project' => $projectName, 'region' => $region), null, $instanceDataAttributes); } $this->pushRawResourceColumn($instanceRow, $this->createResourceList($actions)); $instanceRows[] = $instanceRow; } if ($instanceRows) { return $this->createResourceTable($headers, $instanceRows); } else { return ''; } }
/** * @return void */ function listVolumes() { $this->setHeaders(); $this->getOutput()->setPagetitle( wfMsg( 'openstackmanager-volumelist' ) ); $userProjects = $this->userLDAP->getProjects(); $out = ''; $volumes = $this->adminNova->getVolumes(); $header = Html::element( 'th', array(), wfMsg( 'openstackmanager-volumename' ) ); $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-volumeid' ) ); $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-volumedescription' ) ); $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-volumestate' ) ); $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-volumeattachmentinstance' ) ); $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-volumeattachmentdevice' ) ); $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-volumeattachmentstatus' ) ); $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-volumesize' ) ); $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-volumedeleteonvolumedelete' ) ); $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-availabilityzone' ) ); $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-volumecreationtime' ) ); $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-actions' ) ); $projectArr = array(); foreach ( $volumes as $volume ) { $project = $volume->getOwner(); if ( ! in_array( $project, $userProjects ) ) { continue; } $volumeOut = Html::element( 'td', array(), $volume->getVolumeName() ); $volumeId = $volume->getVolumeId(); $volumeId = htmlentities( $volumeId ); $title = Title::newFromText( $volumeId, NS_NOVA_RESOURCE ); $volumeIdLink = Linker::link( $title, $volumeId ); $volumeOut .= Html::rawElement( 'td', array(), $volumeIdLink ); $volumeOut .= Html::element( 'td', array(), $volume->getVolumeDescription() ); $volumeOut .= Html::element( 'td', array(), $volume->getVolumeStatus() ); $volumeOut .= Html::element( 'td', array(), $volume->getAttachedInstanceId() ); $volumeOut .= Html::element( 'td', array(), $volume->getAttachedDevice() ); $volumeOut .= Html::element( 'td', array(), $volume->getAttachmentStatus() ); $volumeOut .= Html::element( 'td', array(), $volume->getVolumeSize() ); $volumeOut .= Html::element( 'td', array(), $volume->deleteOnInstanceDeletion() ); $volumeOut .= Html::element( 'td', array(), $volume->getVolumeAvailabilityZone() ); $volumeOut .= Html::element( 'td', array(), $volume->getVolumeCreationTime() ); $msg = wfMsgHtml( 'openstackmanager-delete' ); $link = Linker::link( $this->getTitle(), $msg, array(), array( 'action' => 'delete', 'project' => $project, 'volumeid' => $volume->getVolumeId() ) ); $actions = Html::rawElement( 'li', array(), $link ); #$msg = wfMsgHtml( 'openstackmanager-rename' ); #$actions .= Linker::link( $this->getTitle(), $msg, array(), # array( 'action' => 'rename', # 'project' => $project, # 'volumeid' => $volume->getVolumeId() ) ); $msg = wfMsgHtml( 'openstackmanager-attach' ); $link = Linker::link( $this->getTitle(), $msg, array(), array( 'action' => 'attach', 'project' => $project, 'volumeid' => $volume->getVolumeId() ) ); $actions .= Html::rawElement( 'li', array(), $link ); $msg = wfMsgHtml( 'openstackmanager-detach' ); $link = Linker::link( $this->getTitle(), $msg, array(), array( 'action' => 'detach', 'project' => $project, 'volumeid' => $volume->getVolumeId() ) ); $actions .= Html::rawElement( 'li', array(), $link ); $actions = Html::rawElement( 'ul', array(), $actions ); $volumeOut .= Html::rawElement( 'td', array(), $actions ); if ( isset( $projectArr["$project"] ) ) { $projectArr["$project"] .= Html::rawElement( 'tr', array(), $volumeOut ); } else { $projectArr["$project"] = Html::rawElement( 'tr', array(), $volumeOut ); } } foreach ( $userProjects as $project ) { $out .= Html::element( 'h2', array(), $project ); $out .= Linker::link( $this->getTitle(), wfMsgHtml( 'openstackmanager-createvolume' ), array(), array( 'action' => 'create', 'project' => $project ) ); if ( isset( $projectArr["$project"] ) ) { $projectOut = $header; $projectOut .= $projectArr["$project"]; $out .= Html::rawElement( 'table', array( 'id' => 'novavolumelist', 'class' => 'wikitable sortable collapsible' ), $projectOut ); } } $this->getOutput()->addHTML( $out ); }
/** * @param $user User * @param $preferences array * @return bool True */ public static function novaUserPreferences(User $user, array &$preferences) { $link = Linker::link(SpecialPage::getTitleFor('NovaKey'), wfMessage('novakey')->escaped(), array(), array('returnto' => SpecialPage::getTitleFor('Preferences')->getPrefixedText())); $novaUser = new OpenStackNovaUser($user->getName()); $preferences['shellusername'] = array('type' => 'info', 'label-message' => 'openstackmanager-shellaccountname-pref', 'default' => $novaUser->getUid(), 'section' => 'personal/info'); $preferences['openstack-sshkeylist'] = array('type' => 'info', 'raw' => true, 'default' => self::getKeyList($novaUser), 'label-message' => 'openstackmanager-prefs-novapublickey', 'section' => 'openstack/openstack-keys'); return true; }
/** * Create a new project based on project name. This function will also create * all roles needed by the project. * * @static * @param $projectname * @return bool */ static function createProject($projectname) { global $wgAuth; global $wgOpenStackManagerLDAPUser; global $wgOpenStackManagerLDAPProjectBaseDN; OpenStackNovaLdapConnection::connect(); $project = array(); $project['objectclass'][] = 'groupofnames'; $project['objectclass'][] = 'posixgroup'; $project['cn'] = $projectname; $project['owner'] = $wgOpenStackManagerLDAPUser; $project['gidnumber'] = OpenStackNovaUser::getNextIdNumber($wgAuth, 'gidnumber'); $projectdn = 'cn=' . $projectname . ',' . $wgOpenStackManagerLDAPProjectBaseDN; $success = LdapAuthenticationPlugin::ldap_add($wgAuth->ldapconn, $projectdn, $project); $project = new OpenStackNovaProject($projectname); if ($success) { foreach (self::$rolenames as $rolename) { $role = OpenStackNovaRole::createRole($rolename, $project); # TODO: If role addition fails, find a way to fail gracefully # Though, if the project was added successfully, it is unlikely # that role addition will fail. } $wgAuth->printDebug("Successfully added project {$projectname}", NONSENSITIVE); return true; } else { $wgAuth->printDebug("Failed to add project {$projectname}", NONSENSITIVE); return false; } }
/** * Create a new project group based on project name. * * @static * @param $projectname * @return bool */ static function createProjectGroup($projectname) { global $wgAuth; global $wgOpenStackManagerLDAPProjectGroupBaseDN; OpenStackNovaLdapConnection::connect(); $projectGroupName = self::$prefix . $projectname; $projectGroup = array(); $projectGroup['objectclass'][] = 'posixgroup'; $projectGroup['objectclass'][] = 'groupofnames'; $projectGroup['cn'] = $projectGroupName; $projectGroup['gidnumber'] = OpenStackNovaUser::getNextIdNumber($wgAuth, 'gidnumber'); $projectGroupDN = 'cn=' . $projectGroupName . ',' . $wgOpenStackManagerLDAPProjectGroupBaseDN; # TODO: If project group creation fails we need to be able to fail gracefully $success = LdapAuthenticationPlugin::ldap_add($wgAuth->ldapconn, $projectGroupDN, $projectGroup); if ($success) { $wgAuth->printDebug("Successfully added project group {$projectGroupName}", NONSENSITIVE); } else { $wgAuth->printDebug("Failed to add project group {$projectGroupName}: " . ldap_error($wgAuth->ldapconn), NONSENSITIVE); } return $success; }
/** * @return bool */ function listAddresses() { $this->setHeaders(); $this->getOutput()->addModuleStyles( 'ext.openstack' ); $this->getOutput()->setPagetitle( wfMsg( 'openstackmanager-addresslist' ) ); $userProjects = $this->userLDAP->getProjects(); $out = ''; $header = Html::element( 'th', array(), wfMsg( 'openstackmanager-address' ) ); $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-instanceid' ) ); $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-instancename' ) ); $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-hostnames' ) ); $header .= Html::element( 'th', array(), wfMsg( 'openstackmanager-actions' ) ); $addresses = $this->adminNova->getAddresses(); $projectArr = array(); foreach ( $addresses as $address ) { $ip = $address->getPublicIP(); $instanceid = $address->getInstanceId(); $project = $address->getProject(); $addressOut = Html::element( 'td', array(), $ip ); if ( $instanceid ) { $addressOut .= Html::element( 'td', array(), $instanceid ); $instance = $this->adminNova->getInstance( $instanceid ); $instancename = $instance->getInstanceName(); $addressOut .= Html::element( 'td', array(), $instancename ); } else { $addressOut .= Html::element( 'td', array(), '' ); $addressOut .= Html::element( 'td', array(), '' ); } $hosts = OpenStackNovaHost::getHostsByIP( $ip ); if ( $hosts ) { $hostsOut = ''; $msg = wfMsgHtml( 'openstackmanager-removehost-action' ); foreach ( $hosts as $host ) { $domain = $host->getDomain(); $fqdns = $host->getAssociatedDomains(); foreach ( $fqdns as $fqdn ) { $hostname = explode( '.', $fqdn ); $hostname = $hostname[0]; $link = Linker::link( $this->getTitle(), $msg, array(), array( 'action' => 'removehost', 'ip' => $ip, 'project' => $project, 'domain' => $domain->getDomainName(), 'hostname' => $hostname ) ); $hostOut = htmlentities( $fqdn ) . ' ' . $link; $hostsOut .= Html::rawElement( 'li', array(), $hostOut ); } } $hostsOut = Html::rawElement( 'ul', array(), $hostsOut ); $addressOut .= Html::rawElement( 'td', array(), $hostsOut ); } else { $addressOut .= Html::element( 'td', array(), '' ); } $actions = ''; if ( $instanceid ) { $msg = wfMsgHtml( 'openstackmanager-reassociateaddress' ); } else { $msg = wfMsgHtml( 'openstackmanager-releaseaddress' ); $link = Linker::link( $this->getTitle(), $msg, array(), array( 'action' => 'release', 'ip' => $ip, 'project' => $project ) ); $actions = Html::rawElement( 'li', array(), $link ); $msg = wfMsgHtml( 'openstackmanager-associateaddress' ); } $link = Linker::link( $this->getTitle(), $msg, array(), array( 'action' => 'associate', 'ip' => $ip, 'project' => $project ) ); $actions .= Html::rawElement( 'li', array(), $link ); if ( $instanceid ) { $msg = wfMsgHtml( 'openstackmanager-disassociateaddress' ); $link = Linker::link( $this->getTitle(), $msg, array(), array( 'action' => 'disassociate', 'ip' => $ip, 'project' => $project ) ); $actions .= Html::rawElement( 'li', array(), $link ); } $msg = wfMsgHtml( 'openstackmanager-addhost' ); $link = Linker::link( $this->getTitle(), $msg, array(), array( 'action' => 'addhost', 'ip' => $ip, 'project' => $project ) ); $actions .= Html::rawElement( 'li', array(), $link ); $actions = Html::rawElement( 'ul', array(), $actions ); $addressOut .= Html::rawElement( 'td', array(), $actions ); if ( isset( $projectArr["$project"] ) ) { $projectArr["$project"] .= Html::rawElement( 'tr', array(), $addressOut ); } else { $projectArr["$project"] = Html::rawElement( 'tr', array(), $addressOut ); } } foreach ( $userProjects as $project ) { $action = Linker::link( $this->getTitle(), wfMsgHtml( 'openstackmanager-allocateaddress' ), array(), array( 'action' => 'allocate', 'project' => $project ) ); $action = Html::rawElement( 'span', array( 'id' => 'novaaction' ), "[$action]" ); $projectName = Html::rawElement( 'span', array( 'class' => 'mw-customtoggle-' . $project, 'id' => 'novaproject' ), $project ); $out .= Html::rawElement( 'h2', array(), "$projectName $action" ); $projectOut = ''; if ( isset( $projectArr["$project"] ) ) { $projectOut = $header; $projectOut .= $projectArr["$project"]; $projectOut = Html::rawElement( 'table', array( 'id' => 'novainstancelist', 'class' => 'wikitable sortable collapsible' ), $projectOut ); } $out .= Html::rawElement( 'div', array( 'class' => 'mw-collapsible', 'id' => 'mw-customcollapsible-' . $project ), $projectOut ); } $this->getOutput()->addHTML( $out ); return true; }
function getUnscopedToken() { global $wgMemc; $token = ''; $key = wfMemcKey('openstackmanager', "fulltoken", $this->username); $fulltoken = $wgMemc->get($key); if (is_string($fulltoken)) { $token = $fulltoken; } else { if (!$this->token) { $wikiuser = User::newFromName($this->user->getUsername()); $token = OpenStackNovaUser::loadToken($wikiuser); if (!$token) { // Log this user out! $wikiuser->doLogout(); return ''; } $wgMemc->set($key, $token); } else { $token = $this->token; } } return $token; }
/** * @param $formData * @param string $entryPoint * @return bool */ function tryCreateSubmit($formData, $entryPoint = 'internal') { global $wgOpenStackManagerDefaultSecurityGroupRules; $success = OpenStackNovaProject::createProject($formData['projectname']); if (!$success) { $this->getOutput()->addWikiMsg('openstackmanager-createprojectfailed'); return false; } $project = OpenStackNovaProject::getProjectByName($formData['projectname']); $username = $this->userLDAP->getUsername(); $project->addMember($username); $members = explode(',', $formData['member']); foreach ($members as $member) { $project->addMember($member); } $roles = $project->getRoles(); foreach ($roles as $role) { if (in_array($role->getRoleName(), $formData['roles'])) { foreach ($members as $member) { $role->addMember($member); } } // We also need to ensure the project creator is in all roles $role->addMember($username); } # Change the connection to reference this project $this->userNova->setProject($formData['projectname']); $regions = $this->userNova->getRegions('compute'); foreach ($regions as $region) { $this->userNova->setRegion($region); $securityGroups = $this->userNova->getSecurityGroups(); $groupid = ''; foreach ($securityGroups as $securityGroup) { if ($securityGroup->getGroupName() === 'default') { $groupid = $securityGroup->getGroupId(); } } if (!$groupid) { continue; } foreach ($wgOpenStackManagerDefaultSecurityGroupRules as $rule) { $fromport = ''; $toport = ''; $protocol = ''; $range = ''; $sourcegroupid = ''; if (array_key_exists('fromport', $rule)) { $fromport = $rule['fromport']; } if (array_key_exists('toport', $rule)) { $toport = $rule['toport']; } if (array_key_exists('protocol', $rule)) { $protocol = $rule['protocol']; } if (array_key_exists('range', $rule)) { $range = $rule['range']; } if (array_key_exists('group', $rule)) { foreach ($securityGroups as $securityGroup) { if ($rule['group'] === $securityGroup->getGroupName()) { $sourcegroupid = $securityGroup->getGroupId(); } } } $this->userNova->addSecurityGroupRule($groupid, $fromport, $toport, $protocol, $range, $sourcegroupid); } } $project->setVolumeSettings(array('home', 'project')); $project->editArticle(); $this->getOutput()->addWikiMsg('openstackmanager-createdproject'); $out = '<br />'; $out .= Linker::link($this->getPageTitle(), $this->msg('openstackmanager-addadditionalproject')->escaped()); $this->getOutput()->addHTML($out); return true; }
/** * Create a new project based on project name. This function will also create * all roles needed by the project. * * @static * @param $projectname * @return bool */ static function createProject($projectname) { global $wgAuth; global $wgOpenStackManagerLDAPUser; global $wgOpenStackManagerLDAPProjectBaseDN; OpenStackNovaLdapConnection::connect(); $project = array(); $project['objectclass'][] = 'extensibleobject'; $project['objectclass'][] = 'groupofnames'; $project['cn'] = $projectname; $project['member'] = $wgOpenStackManagerLDAPUser; $projectdn = 'cn=' . $projectname . ',' . $wgOpenStackManagerLDAPProjectBaseDN; // if we're not going to use project groups, // then create this project as a posixgroup if (!OpenStackNovaProject::useProjectGroup()) { $project['gidnumber'] = OpenStackNovaUser::getNextIdNumber($wgAuth, 'gidnumber'); $project['objectclass'][] = 'posixgroup'; } $success = LdapAuthenticationPlugin::ldap_add($wgAuth->ldapconn, $projectdn, $project); $project = new OpenStackNovaProject($projectname); if ($success) { foreach (self::$rolenames as $rolename) { OpenStackNovaRole::createRole($rolename, $project); # TODO: If role addition fails, find a way to fail gracefully # Though, if the project was added successfully, it is unlikely # that role addition will fail. } $sudoerOU = array(); $sudoerOU['objectclass'][] = 'organizationalunit'; $sudoerOU['ou'] = 'sudooers'; $sudoerOUdn = 'ou=sudoers,' . $projectdn; LdapAuthenticationPlugin::ldap_add($wgAuth->ldapconn, $sudoerOUdn, $sudoerOU); # TODO: If sudoerOU creation fails we need to be able to fail gracefully $wgAuth->printDebug("Successfully added project {$projectname}", NONSENSITIVE); // Now that we've created the Project, if we // are supposed to use a corresponding Project Group // to manage posix group permissions, do so now. if (OpenStackNovaProject::useProjectGroup()) { OpenStackNovaProjectGroup::createProjectGroup($projectname); # TODO: If project group creation fails we need to be able to fail gracefully } // Create two default, permissive sudo policies. First, // allow sudo (as root) for all members... $projectGroup = "%" . $project->getProjectGroup()->getProjectGroupName(); if (OpenStackNovaSudoer::createSudoer('default-sudo', $projectname, array($projectGroup), array(), array('ALL'), array('!authenticate'))) { $wgAuth->printDebug("Successfully created default sudo policy for {$projectname}", NONSENSITIVE); } // Now, allow all project members to sudo to all other users. $projectGroup = "%" . $project->getProjectGroup()->getProjectGroupName(); if (OpenStackNovaSudoer::createSudoer('default-sudo-as', $projectname, array($projectGroup), array("{$projectGroup}"), array('ALL'), array('!authenticate'))) { $wgAuth->printDebug("Successfully created default sudo-as policy for {$projectname}", NONSENSITIVE); } } else { $wgAuth->printDebug("Failed to add project {$projectname}", NONSENSITIVE); return false; } OpenStackNovaProject::createServiceGroupOUs($projectname); return true; }