r78241 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r78240‎ | r78241 | r78242 >
Date:11:23, 12 December 2010
Author:laner
Status:deferred
Tags:
Comment:
Fixing SpecialNovaInstance, and adding initial support for key importing and listing.
Modified paths:
  • /trunk/extensions/OpenStackManager/OpenStackManager.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaController.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaKeypair.php (added) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaUser.php (modified) (history)
  • /trunk/extensions/OpenStackManager/SpecialNovaInstance.php (modified) (history)
  • /trunk/extensions/OpenStackManager/SpecialNovaKey.php (added) (history)

Diff [purge]

Index: trunk/extensions/OpenStackManager/SpecialNovaInstance.php
@@ -13,11 +13,11 @@
1414
1515 wfLoadExtensionMessages('OpenStackManager');
1616 $user = new OpenStackNovaUser();
17 - $project = $wgRequest->getVal('project');
1817 if ( ! $user->exists() ) {
1918 $this->noCredentials();
2019 return true;
2120 }
 21+ $project = $wgRequest->getVal('project');
2222 $userCredentials = $user->getCredentials( $project );
2323 $this->userNova = new OpenStackNovaController( $userCredentials );
2424 $adminCredentials = $wgOpenStackManagerNovaAdminKeys;
@@ -64,7 +64,7 @@
6565 $this->setHeaders();
6666 $wgOut->setPagetitle("Create Instance");
6767
68 - $instanceid = $wgRequest->getVal('instanceid');
 68+ $project = $wgRequest->getVal('project');
6969
7070 # TODO: Add project name field
7171
@@ -131,11 +131,21 @@
132132 'label-message' => 'keypair',
133133 );
134134
 135+ $instanceInfo['action'] = array(
 136+ 'type' => 'hidden',
 137+ 'default' => 'create',
 138+ );
 139+
 140+ $instanceInfo['project'] = array(
 141+ 'type' => 'hidden',
 142+ 'default' => htmlentities( $project ),
 143+ );
 144+
135145 #TODO: Add availablity zone field
136146
137 - $instanceForm = new OpenStackCreateInstanceForm( $instanceInfo, 'openstackmanager-form' );
138 - $instanceForm->setTitle( SpecialPage::getTitleFor( 'OpenStackCreateInstance' ));
139 - $instanceForm->setSubmitID( 'openstackmanager-form-createinstancesubmit' );
 147+ $instanceForm = new OpenStackCreateInstanceForm( $instanceInfo, 'novainstance-form' );
 148+ $instanceForm->setTitle( SpecialPage::getTitleFor( 'NovaInstance' ));
 149+ $instanceForm->setSubmitID( 'novainstance-form-createinstancesubmit' );
140150 $instanceForm->setSubmitCallback( array( $this, 'tryCreateSubmit' ) );
141151 $instanceForm->show();
142152
Index: trunk/extensions/OpenStackManager/OpenStackNovaUser.php
@@ -48,7 +48,7 @@
4949 }
5050 }
5151
52 - function hasProjects() {
 52+ function getProjects() {
5353 global $wgAuth;
5454 global $wgOpenStackManagerLDAPProjectBaseDN;
5555
@@ -60,19 +60,21 @@
6161 $filter = "(&(projectManager=*)(member=$this->userDN))";
6262 $result = ldap_search( $wgAuth->ldapconn, $wgOpenStackManagerLDAPProjectBaseDN, $filter );
6363 if ( $result ) {
64 - $entries = ldap_get_entries( $wgAuth->ldapconn, $entry );
 64+ $entries = ldap_get_entries( $wgAuth->ldapconn, $result );
6565 if ( $entries ) {
6666 # First entry is always a count
6767 array_shift($entries);
6868 foreach ( $entries as $entry ) {
69 - array_push( $projects, $entry['cn'] );
 69+ array_push( $projects, $entry['cn'][0] );
7070 }
7171 }
 72+ } else {
 73+ $wgAuth->printDebug( "No result found when searching for user's projects", NONSENSITIVE );
7274 }
7375 return $projects;
7476 }
7577
76 - function hasRoles( $project='' ) {
 78+ function getRoles( $project='' ) {
7779 # Currently unsupported
7880 return array();
7981 }
@@ -115,6 +117,24 @@
116118 $wgAuth->bindAs( $wgOpenStackManagerLDAPUser, $wgOpenStackManagerLDAPUserPassword );
117119 }
118120
 121+ function importKeypair( $key ) {
 122+ global $wgAuth;
 123+ global $wgOpenStackManagerLDAPUser, $wgOpenStackManagerLDAPUserPassword;
 124+
 125+ $wgAuth->connect();
 126+ $wgAuth->bindAs( $wgOpenStackManagerLDAPUser, $wgOpenStackManagerLDAPUserPassword );
 127+
 128+ $values['sshpublickey'] = $key;
 129+ $success = @ldap_modify( $wgAuth->ldapconn, $this->userDN, $values );
 130+ if ( $success ) {
 131+ $wgAuth->printDebug( "Successfully imported the user's sshpublickey", NONSENSITIVE );
 132+ return true;
 133+ } else {
 134+ $wgAuth->printDebug( "Failed to import the user's sshpublickey", NONSENSITIVE );
 135+ return false;
 136+ }
 137+ }
 138+
119139 static function uuid4() {
120140 uuid_create( &$uuid );
121141 uuid_make( $uuid, UUID_MAKE_V4 );
Index: trunk/extensions/OpenStackManager/SpecialNovaKey.php
@@ -0,0 +1,164 @@
 2+<?php
 3+class SpecialNovaKey extends SpecialPage {
 4+
 5+ var $userNova, $userLDAP;
 6+
 7+ function __construct() {
 8+ parent::__construct( 'NovaKey' );
 9+ }
 10+
 11+ function execute( $par ) {
 12+ global $wgRequest;
 13+
 14+ wfLoadExtensionMessages('OpenStackManager');
 15+ $this->userLDAP = new OpenStackNovaUser();
 16+ if ( ! $this->userLDAP->exists() ) {
 17+ $this->noCredentials();
 18+ return true;
 19+ }
 20+
 21+ $project = $wgRequest->getVal('project');
 22+ $action = $wgRequest->getVal('action');
 23+ if ( $action == "import" ) {
 24+ $this->importKey();
 25+ } else if ( $action == "delete" ) {
 26+ if ( ! $this->userLDAP->inProject( $project ) ) {
 27+ $this->notInProject();
 28+ return true;
 29+ }
 30+ $this->deleteKey();
 31+ } else {
 32+ $this->listKeys();
 33+ }
 34+ }
 35+
 36+ function noCredentials() {
 37+ global $wgOut;
 38+
 39+ $this->setHeaders();
 40+ $wgOut->setPagetitle("No Nova credentials found for your account");
 41+ $wgOut->addHTML('<p>There were no Nova credentials found for your user account. Please ask a Nova administrator to create credentials for you.</p>');
 42+ }
 43+
 44+ function notInProject() {
 45+ global $wgOut;
 46+
 47+ $this->setHeaders();
 48+ $wgOut->setPagetitle("Your account is not in the project requested");
 49+ $wgOut->addHTML('<p>You can not complete the action requested as your user account is not in the project requested.</p>');
 50+ }
 51+
 52+ function importKey() {
 53+ global $wgRequest, $wgOut;
 54+
 55+ $project = $wgRequest->getVal('project');
 56+ if ( $project && ! $this->userLDAP->inProject( $project ) ) {
 57+ $this->notInProject();
 58+ return true;
 59+ }
 60+ $userCredentials = $this->userLDAP->getCredentials( $project );
 61+ $this->userNova = new OpenStackNovaController( $userCredentials );
 62+
 63+ $this->setHeaders();
 64+ $wgOut->setPagetitle("Import Key");
 65+
 66+ # TODO: Add project name field
 67+
 68+ $keyInfo = Array();
 69+ $keyInfo['keyName'] = array(
 70+ 'type' => 'text',
 71+ 'label-message' => 'keyname',
 72+ 'default' => '',
 73+ 'section' => 'key/info',
 74+ );
 75+
 76+ $keyInfo['key'] = array(
 77+ 'type' => 'textarea',
 78+ 'section' => 'key/info',
 79+ 'default' => '',
 80+ 'label-message' => 'key',
 81+ );
 82+
 83+ $keyInfo['action'] = array(
 84+ 'type' => 'hidden',
 85+ 'default' => 'import',
 86+ );
 87+
 88+ $keyInfo['project'] = array(
 89+ 'type' => 'hidden',
 90+ 'default' => htmlentities( $project ),
 91+ );
 92+
 93+ #TODO: Add availablity zone field
 94+
 95+ $keyForm = new SpecialNovaKeyForm( $keyInfo, 'novakey-form' );
 96+ $keyForm->setTitle( SpecialPage::getTitleFor( 'NovaKey' ));
 97+ $keyForm->setSubmitID( 'novakey-form-createkeysubmit' );
 98+ $keyForm->setSubmitCallback( array( $this, 'tryImportSubmit' ) );
 99+ $keyForm->show();
 100+
 101+ }
 102+
 103+ function deleteKey() {
 104+ global $wgOut;
 105+
 106+ $project = $wgRequest->getVal('project');
 107+ if ( $project && ! $this->userLDAP->inProject( $project ) ) {
 108+ $this->notInProject();
 109+ return true;
 110+ }
 111+ $this->setHeaders();
 112+ $wgOut->setPagetitle("Confirm key deletion");
 113+ return true;
 114+ }
 115+
 116+ function listKeys() {
 117+ global $wgOut;
 118+
 119+ $this->setHeaders();
 120+ $wgOut->setPagetitle("Key list");
 121+
 122+ $out = '';
 123+ $projects = $this->userLDAP->getProjects();
 124+ foreach( $projects as $project ) {
 125+ $userCredentials = $this->userLDAP->getCredentials( $project );
 126+ $this->userNova = new OpenStackNovaController( $userCredentials );
 127+ $keypairs = $this->userNova->getKeypairs();
 128+ if ( ! $keypairs ) {
 129+ continue;
 130+ }
 131+ $out .= Html::element( 'h2', array(), $project );
 132+ $projectOut = Html::element( 'th', array(), 'Name' );
 133+ $projectOut .= Html::element( 'th', array(), 'Fingerprint' );
 134+ foreach ( $keypairs as $keypair ) {
 135+ $keyOut = Html::element( 'td', array(), $keypair->getKeyName() );
 136+ $keyOut .= Html::element( 'td', array(), $keypair->getKeyFingerprint() );
 137+ $projectOut .= Html::rawElement( 'tr', array(), $keyOut );
 138+ }
 139+ $out .= Html::rawElement( 'table', array( 'id' => 'novainstancelist', 'class' => 'wikitable' ), $projectOut );
 140+ }
 141+
 142+ $wgOut->addHTML( $out );
 143+ }
 144+
 145+ function tryImportSubmit( $formData, $entryPoint = 'internal' ) {
 146+ global $wgOut;
 147+
 148+ $success = $this->userLDAP->importKeypair( $formData['key'] );
 149+ if ( ! $success ) {
 150+ $out = Html::element( 'p', array(), 'Failed to import keypair' );
 151+ return false;
 152+ }
 153+ # OpenStack's EC2 API doesn't yet support importing keys
 154+ //$keypair = $this->userNova->importKeypair( $formData['keyname'], $formData['key'] );
 155+
 156+ #$out = Html::element( 'p', array(), 'Imported keypair ' . $keypair->getKeyName() . ' with fingerprint ' . $keypair->getKeyFingerprint() );
 157+ $out = Html::element( 'p', array(), 'Imported keypair' );
 158+
 159+ $wgOut->addHTML( $out );
 160+ return true;
 161+ }
 162+}
 163+
 164+class SpecialNovaKeyForm extends HTMLForm {
 165+}
Index: trunk/extensions/OpenStackManager/OpenStackNovaController.php
@@ -68,10 +68,12 @@
6969 function getKeypairs( $reload = false ) {
7070 if ( count( $this->keypairs ) == 0 || $reload ) {
7171 $this->keypairs = array();
72 - $keypairs = $this->novaConnection->describe_key_pairs();
73 - $keypairs = $keypairs->body->keypairsSet->item;
 72+ $response = $this->novaConnection->describe_key_pairs();
 73+ $keypairs = $response->body->keypairsSet->item;
7474 foreach ( $keypairs as $keypair ) {
75 - $this->keypairs["$keypair->keyName"] = $keypair;
 75+ $keypair = new OpenStackNovaKeypair( $keypair );
 76+ $keyname = $keypair->getKeyName();
 77+ $this->keypairs["$keyname"] = $keypair;
7678 }
7779 }
7880 return $this->keypairs;
@@ -94,7 +96,7 @@
9597 function createInstance( $image, $key, $instanceType, $availabilityZone ) {
9698 # 1, 1 is min and max number of instances to create.
9799 # We never want to make more than one at a time.
98 - $instance = $this->novaConnection->run_instances($image, 1, 1, array(
 100+ $response = $this->novaConnection->run_instances($image, 1, 1, array(
99101 'KeyName' => $key,
100102 'InstanceType' => $instanceType,
101103 'Placement.AvailabilityZone' => $availabilityZone,
@@ -107,4 +109,14 @@
108110 return $instance;
109111 }
110112
 113+ function importKeyPair( $keyName, $key ) {
 114+ $response = $this->novaConnection->import_key_pair( $keyName, $key );
 115+
 116+ $keypair = new OpenStackNovaKeypair( $response->body );
 117+ $keyName = $keypair->getKeyName();
 118+ $this->keypairs["$keyName"] = $keypair;
 119+
 120+ return $keypair;
 121+ }
 122+
111123 }
Index: trunk/extensions/OpenStackManager/OpenStackNovaKeypair.php
@@ -0,0 +1,20 @@
 2+<?php
 3+
 4+# TODO: Make this an abstract class, and make the EC2 API a subclass
 5+class OpenStackNovaKeyPair {
 6+
 7+ var $keypair;
 8+
 9+ function __construct( $apiKeypairResponse ) {
 10+ $this->keypair = $apiKeypairResponse;
 11+ }
 12+
 13+ function getKeyName() {
 14+ return $this->keypair->keyName;
 15+ }
 16+
 17+ function getKeyFingerprint() {
 18+ return $this->keypair->keyFingerprint;
 19+ }
 20+
 21+}
Index: trunk/extensions/OpenStackManager/OpenStackManager.php
@@ -36,11 +36,15 @@
3737 $wgExtensionMessagesFiles['OpenStackManager'] = $dir . 'OpenStackManager.i18n.php';
3838 $wgExtensionAliasesFiles['OpenStackManager'] = $dir . 'OpenStackManager.alias.php';
3939 $wgAutoloadClasses['OpenStackNovaInstance'] = $dir . 'OpenStackNovaInstance.php';
 40+$wgAutoloadClasses['OpenStackNovaKeypair'] = $dir . 'OpenStackNovaKeypair.php';
4041 $wgAutoloadClasses['OpenStackNovaController'] = $dir . 'OpenStackNovaController.php';
4142 $wgAutoloadClasses['OpenStackNovaUser'] = $dir . 'OpenStackNovaUser.php';
4243 $wgAutoloadClasses['SpecialNovaInstance'] = $dir . 'SpecialNovaInstance.php';
 44+$wgAutoloadClasses['SpecialNovaKey'] = $dir . 'SpecialNovaKey.php';
4345 $wgAutoloadClasses['AmazonEC2'] = $dir . 'aws-sdk/sdk.class.php';
4446 $wgSpecialPages['NovaInstance'] = 'SpecialNovaInstance';
4547 $wgSpecialPageGroups['NovaInstance'] = 'other';
 48+$wgSpecialPages['NovaKey'] = 'SpecialNovaKey';
 49+$wgSpecialPageGroups['NovaKey'] = 'other';
4650
4751 $wgHooks['LDAPSetCreationValues'][] = 'OpenStackNovaUser::LDAPSetCreationValues';

Follow-up revisions

RevisionCommit summaryAuthorDate
r78263Followup r78241 (More just a ping to Ryan ;))...reedy18:19, 12 December 2010

Status & tagging log