Andrew Bogott has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/343056 )
Change subject: Remove code to manage posix project groups. ...................................................................... Remove code to manage posix project groups. This is handled via keystone callbacks now. Bug: T150091 Change-Id: I125b3e64a7fca1e882766f77ff8efa3319c0141d --- M nova/OpenStackNovaProject.php D nova/OpenStackNovaProjectGroup.php 2 files changed, 15 insertions(+), 382 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/OpenStackManager refs/changes/56/343056/1 diff --git a/nova/OpenStackNovaProject.php b/nova/OpenStackNovaProject.php index 367df11..d530884 100644 --- a/nova/OpenStackNovaProject.php +++ b/nova/OpenStackNovaProject.php @@ -26,7 +26,6 @@ public $roles; public $userrole; public $loaded; - public $projectGroup; // list of roles that are visible in the web UI static $visiblerolenames = array( 'projectadmin' ); @@ -38,6 +37,7 @@ // short-lived cache of project objects static $projectCache = array(); static $projectCacheMaxSize = 200; + static $projectGroupPrefix = 'project-'; /** * @param $projectname @@ -109,9 +109,6 @@ } $this->userrole = OpenStackNovaRole::getProjectRoleByName( self::$userrolename, $this ); - // fetch the associated posix project group (project-$projectname) - $this->fetchProjectGroup(); - $this->fetchServiceGroups(); $this->loaded = true; @@ -167,50 +164,10 @@ } /** - * Initializes the corresponding project group object for this project. - * If the ProjectGroup can't be loaded OR if the existing ProjectGroup - * is a virtual static group, then the ProjectGroup will be recreated - * from scratch and the members will be synced from this Project's - * list of members. - * - * @return void - */ - function fetchProjectGroup() { - $this->projectGroup = new OpenStackNovaProjectGroup( $this->projectname ); - - // If we couldn't find an corresponding Project Group, - // then we should create one now. - if ( !$this->projectGroup->loaded ) { - $ldap = LdapAuthenticationPlugin::getInstance(); - $ldap->printDebug( $this->projectGroup->getProjectGroupName() . " does not exist. Creating it.", NONSENSITIVE ); - - $createSuccess = OpenStackNovaProjectGroup::createProjectGroup( $this->projectname ); - // Aaaaand if we successfully created the group, then finally sync the members from this project now. - if ( $createSuccess ) { - $this->projectGroup = new OpenStackNovaProjectGroup( $this->projectname ); - $this->syncProjectGroupMembers(); - } - } - } - - /** * @return string */ function getProjectName() { return $this->getName(); - } - - /** - * Returns the corresponding ProjectGroup for this Project. - * If necessary, the ProjectGroup will be loaded from LDAP. - * - * @return OpenStackNovaProjectGroup - */ - function getProjectGroup() { - if ( !$this->loaded ) { - $this->fetchProjectGroup(); - } - return $this->projectGroup; } /** @@ -365,8 +322,6 @@ $wgMemc->delete( $key ); if ( $this->userrole->deleteMember( $username ) ) { - $this->projectGroup->deleteMember( $username ); - foreach ( $this->roles as $role ) { $role->deleteMember( $username ); # @todo Find a way to fail gracefully if role member @@ -441,9 +396,6 @@ } if ( $this->userrole->addMember( $username ) ) { - // If we successfully added the member to this Project, then - // also add the member to the corresponding ProjectGroup. - $this->projectGroup->addMember( $username ); $this->deleteRoleCaches( $username ); $ldap->printDebug( "Successfully added $username to $this->projectname", NONSENSITIVE ); $this->editArticle(); @@ -452,39 +404,6 @@ $ldap->printDebug( "Failed to add $username to $this->projectname", NONSENSITIVE ); return false; } - } - - /** - * Compares members between this Project and its - * corresponding ProjectGroup. If they differ, - * Then the entire member list for the ProjectGroup - * will be overwritten with this list of members. - * - * @return int -1 on failure, 0 on nochange, and 1 on a successful sync - */ - function syncProjectGroupMembers() { - $failure = -1; - $nochange = 0; - $synced = 1; - - // These both return a sorted array of Member DNs - $projectMemberDNs = $this->getMemberDNs(); - $projectGroupMemberDNs = $this->projectGroup->getMemberDNs(); - - // These two arrays should be exactly the same, - // so comparing them using == should work. - // If they are not the same, then modify the - // project group member list so that it exactly - // matches the list from the project. - if ( $projectMemberDNs != $projectGroupMemberDNs ) { - $sync_success = $this->projectGroup->setMembers( $projectMemberDNs ); - $retval = $sync_success == true ? $synced : $failure; - } - else { - $retval = $nochange; - } - - return $retval; } /** @@ -620,6 +539,18 @@ return $projects; } + + /** + * Returns a standardized project group name. This needs to + * correspond with the project group name as set in the keystone hook. + * + * @return string + */ + function getProjectGroupName() { + return self::$projectGroupPrefix . $this->projectname; + } + + /** * Create a new project based on project name. This function will also create * all roles needed by the project. @@ -664,22 +595,16 @@ LdapAuthenticationPlugin::ldap_add( $ldap->ldapconn, $sudoerOUdn, $sudoerOU ); # TODO: If sudoerOU creation fails we need to be able to fail gracefully - // 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. - 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(); + $projectGroup = "%" . $project->getProjectGroupName(); if ( OpenStackNovaSudoer::createSudoer( 'default-sudo', $projectname, array( $projectGroup ), array(), array( 'ALL' ), array( '!authenticate' ) ) ) { $ldap->printDebug( "Successfully created default sudo policy for $projectname", NONSENSITIVE ); } // Now, allow all project members to sudo to all other users. - $projectGroup = "%" . $project->getProjectGroup()->getProjectGroupName(); + $projectGroup = "%" . $project->getProjectGroupName(); if ( OpenStackNovaSudoer::createSudoer( 'default-sudo-as', $projectname, array( $projectGroup ), array( "$projectGroup" ), array( 'ALL' ), array( '!authenticate' ) ) ) { @@ -790,7 +715,6 @@ $ldap = LdapAuthenticationPlugin::getInstance(); OpenStackNovaLdapConnection::connect(); - OpenStackNovaProjectGroup::deleteProjectGroup( $project->getProjectName() ); # Projects have a sudo OU and sudoers entries below that OU, we must delete them first $sudoers = OpenStackNovaSudoer::getAllSudoersByProject( $project->getProjectName() ); diff --git a/nova/OpenStackNovaProjectGroup.php b/nova/OpenStackNovaProjectGroup.php deleted file mode 100644 index 70bfa71..0000000 --- a/nova/OpenStackNovaProjectGroup.php +++ /dev/null @@ -1,291 +0,0 @@ -<?php - -/** - * Most OpenStackNovaProjects will have an corresponding - * OpenStackNovaProjectGroup. These are posixgroups that - * are named after the Project Name. This allows for - * management of unix group permissions, without potentially - * conflicting project names with existing unix groups. - * e.g. If someone creates a project named 'root', the - * corresponding posix group will be called 'project-root' - * instead of 'root'. - * - * OpenStackNovaProject should manage the creation and - * addition of members to this group. Its members - * are the canonical source of members for the group. - * If ever the Project member list changes, - * the ProjectGroup member list should be updated to match. - * - * @file - * @ingroup Extensions - */ - -class OpenStackNovaProjectGroup { - public $projectName; - public $projectGroupInfo; - public $projectGroupDN; - public $loaded; - - static $prefix = 'project-'; - - /** - * @param $projectname - * @param bool $load - */ - function __construct( $projectName, $load=true ) { - $this->projectName = $projectName; - if ( $load ) { - OpenStackNovaLdapConnection::connect(); - $this->fetchProjectGroupInfo(); - } else { - $this->loaded = false; - } - } - - /** - * Fetch the project group from LDAP and initialize the object - * @return void - */ - function fetchProjectGroupInfo( $refresh=true ) { - global $wgOpenStackManagerLDAPProjectGroupBaseDN; - - if ( $this->loaded and !$refresh ) { - return; - } - $ldap = LdapAuthenticationPlugin::getInstance(); - $result = LdapAuthenticationPlugin::ldap_search( $ldap->ldapconn, $wgOpenStackManagerLDAPProjectGroupBaseDN, - '(&(cn=' . $this->getProjectGroupName() . ')(objectclass=groupofnames))' ); - $this->projectGroupInfo = LdapAuthenticationPlugin::ldap_get_entries( $ldap->ldapconn, $result ); - if ( !isset( $this->projectGroupInfo[0] ) ) { - $this->loaded = false; - return; - } - - $this->projectGroupDN = $this->projectGroupInfo[0]['dn']; - $this->loaded = true; - } - - /** - * Returns the project group name, which is - * just the corresponding project name prefixed - * by self::$prefix. - * - * @return string - */ - function getProjectGroupName() { - return self::$prefix . $this->projectName; - } - - /** - * Return all users who are a member of this project - * - * @return array - */ - function getMembers() { - global $wgOpenStackManagerLDAPDomain; - - $members = array(); - if ( isset( $this->projectGroupInfo[0]['member'] ) ) { - $ldap = LdapAuthenticationPlugin::getInstance(); - $memberdns = $this->projectGroupInfo[0]['member']; - array_shift( $memberdns ); - foreach ( $memberdns as $memberdn ) { - $searchattr = $ldap->getConf( 'SearchAttribute', $wgOpenStackManagerLDAPDomain ); - if ( $searchattr ) { - // We need to look up the search attr from the user entry - // this is expensive, but must be done. - // TODO: memcache this - $userInfo = $ldap->getUserInfoStateless( $memberdn ); - $members[] = $userInfo[0][$searchattr][0]; - } else { - - $member = explode( '=', $memberdn ); - $member = explode( ',', $member[1] ); - $member = $member[0]; - $members[] = $member; - } - } - } - - return $members; - } - - /** - * Returns an array of all member DNs that belong to this project group. - * - * @return array - */ - function getMemberDNs() { - $memberDNs = array(); - if ( isset( $this->projectGroupInfo[0]['member'] ) ) { - $memberDNs = $this->projectGroupInfo[0]['member']; - array_shift( $memberDNs ); - sort( $memberDNs ); - } - return $memberDNs; - } - - /** - * Remove a member from the project group based on username - * - * @param $username string - * @return bool - */ - function deleteMember( $username ) { - if ( isset( $this->projectGroupInfo[0]['member'] ) ) { - $ldap = LdapAuthenticationPlugin::getInstance(); - $members = $this->projectGroupInfo[0]['member']; - array_shift( $members ); - $user = new OpenStackNovaUser( $username ); - if ( ! $user->userDN ) { - $ldap->printDebug( "Failed to find userDN for username $username in OpenStackNovaProjectGroup deleteMember.", NONSENSITIVE ); - return false; - } - $index = array_search( $user->userDN, $members ); - if ( $index === false ) { - $ldap->printDebug( "Failed to find userDN " . $user->userDN . " in in ProjectGroup " . $this->projectGroupName . " member list", NONSENSITIVE ); - return false; - } - unset( $members[$index] ); - $values = array(); - $values['member'] = array(); - foreach ( $members as $member ) { - $values['member'][] = $member; - } - $success = LdapAuthenticationPlugin::ldap_modify( $ldap->ldapconn, $this->projectGroupDN, $values ); - if ( $success ) { - $this->fetchProjectGroupInfo( true ); - $ldap->printDebug( "Successfully removed $user->userDN from $this->projectGroupDN", NONSENSITIVE ); - return true; - } else { - $ldap->printDebug( "Failed to remove $user->userDN from $this->projectGroupDN: " . ldap_error($ldap->ldapconn), NONSENSITIVE ); - return false; - } - } else { - return false; - } - } - - - /** - * Takes an array of memberDNs and saves it to the project group in LDAP. - * - * @param $memberDNs array as returned by getMemberDNs(). - * @return bool - */ - function setMembers( $memberDNs ) { - $ldap = LdapAuthenticationPlugin::getInstance(); - $values = array( 'member' => $memberDNs ); - $success = LdapAuthenticationPlugin::ldap_modify( $ldap->ldapconn, $this->projectGroupDN, $values ); - - if ( $success ) { - // reload the ProjectGroup from LDAP. - $this->fetchProjectGroupInfo( true ); - $ldap->printDebug( "Successfully set " . count( $memberDNs ) . " members to $this->projectGroupDN", NONSENSITIVE ); - } else { - $ldap->printDebug( "Failed to set " . count( $memberDNs ) . " members to $this->projectGroupDN: " . ldap_error( $ldap->ldapconn ) . ". [" . join( ";", $memberDNs ) . "]", NONSENSITIVE ); - } - - return $success; - } - - /** - * Add a member to this project based on username - * - * @param $username string - * @return bool - */ - function addMember( $username ) { - $ldap = LdapAuthenticationPlugin::getInstance(); - $members = array(); - if ( isset( $this->projectGroupInfo[0]['member'] ) ) { - $members = $this->projectGroupInfo[0]['member']; - array_shift( $members ); - } - $user = new OpenStackNovaUser( $username ); - if ( ! $user->userDN ) { - $ldap->printDebug( "Failed to find userDN in addMember", NONSENSITIVE ); - return false; - } - $members[] = $user->userDN; - $values = array(); - $values['member'] = $members; - $success = LdapAuthenticationPlugin::ldap_modify( $ldap->ldapconn, $this->projectGroupDN, $values ); - if ( $success ) { - $this->fetchProjectGroupInfo( true ); - $ldap->printDebug( "Successfully added $user->userDN to $this->projectGroupDN", NONSENSITIVE ); - return true; - } else { - $ldap->printDebug( "Failed to add $user->userDN to $this->projectGroupDN: " . ldap_error($ldap->ldapconn), NONSENSITIVE ); - return false; - } - } - - - /** - * Create a new project group based on project name. - * - * @static - * @param $projectname - * @return bool - */ - static function createProjectGroup( $projectname ) { - global $wgOpenStackManagerLDAPProjectGroupBaseDN; - global $wgOpenStackManagerLDAPUsername; - - $ldap = LdapAuthenticationPlugin::getInstance(); - OpenStackNovaLdapConnection::connect(); - - $user = new OpenStackNovaUser( $wgOpenStackManagerLDAPUsername ); - - if ( ! $user->userDN ) { - $ldap->printDebug( "Failed to find userDN in createProjectGroup", NONSENSITIVE ); - return false; - } - - $projectGroupName = self::$prefix . $projectname; - $projectGroup = array(); - $projectGroup['member'][] = $user->userDN; - $projectGroup['objectclass'][] = 'posixgroup'; - $projectGroup['objectclass'][] = 'groupofnames'; - $projectGroup['cn'] = $projectGroupName; - $projectGroup['gidnumber'] = OpenStackNovaUser::getNextIdNumber( $ldap, 'gidnumber' ); - $projectGroupDN = 'cn=' . $projectGroupName . ',' . $wgOpenStackManagerLDAPProjectGroupBaseDN; - - # TODO: If project group creation fails we need to be able to fail gracefully - $success = LdapAuthenticationPlugin::ldap_add( $ldap->ldapconn, $projectGroupDN, $projectGroup ); - if ( $success ) { - $ldap->printDebug( "Successfully added project group $projectGroupName", NONSENSITIVE ); - } - else { - $ldap->printDebug( "Failed to add project group $projectGroupName: " . ldap_error( $ldap->ldapconn ), NONSENSITIVE ); - return false; - } - return $success; - } - - /** - * Deletes a project group based on project name. - * - * @param $projectname String - * @return bool - */ - static function deleteProjectGroup( $projectname ) { - global $wgOpenStackManagerLDAPProjectGroupBaseDN; - - $ldap = LdapAuthenticationPlugin::getInstance(); - OpenStackNovaLdapConnection::connect(); - - $projectGroupName = self::$prefix . $projectname; - $projectGroupDN = 'cn=' . $projectGroupName . ',' . $wgOpenStackManagerLDAPProjectGroupBaseDN; - - $success = LdapAuthenticationPlugin::ldap_delete( $ldap->ldapconn, $projectGroupDN ); - if ( $success ){ - $ldap->printDebug( "Successfully deleted project group $projectGroupDN", NONSENSITIVE ); - } else { - $ldap->printDebug( "Failed to delete project group $projectGroupDN: " . ldap_error( $ldap->ldapconn ), NONSENSITIVE ); - } - return $success; - } - -} -- To view, visit https://gerrit.wikimedia.org/r/343056 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I125b3e64a7fca1e882766f77ff8efa3319c0141d Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/OpenStackManager Gerrit-Branch: master Gerrit-Owner: Andrew Bogott <abog...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits