r78233 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r78232‎ | r78233 | r78234 >
Date:03:50, 12 December 2010
Author:laner
Status:deferred
Tags:
Comment:
* Renaming CreateInstance to NovaInstance
* Adding actions to NovaInstance special page for instance creation, modification, and lists
* Adding security to Instance creation
** Will ensure you are in the project you wish to create instances in
** Will ensure your user account has Nova credentials
* Added a NovaUser class to represent Nova user accounts
** Functions added for getting credentials, getting project and role memberships, checking for project and role memberships, and checking for existence
Modified paths:
  • /trunk/extensions/OpenStackManager/OpenStackManager.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaController.php (modified) (history)
  • /trunk/extensions/OpenStackManager/OpenStackNovaUser.php (added) (history)
  • /trunk/extensions/OpenStackManager/SpecialCreateInstance.php (deleted) (history)
  • /trunk/extensions/OpenStackManager/SpecialNovaInstance.php (added) (history)

Diff [purge]

Index: trunk/extensions/OpenStackManager/SpecialCreateInstance.php
@@ -1,110 +0,0 @@
2 -<?php
3 -class OpenStackCreateInstance extends SpecialPage {
4 -
5 - var $adminNova, $userNova;
6 -
7 - function __construct() {
8 - global $wgOpenStackManagerNovaAdminKeys;
9 - parent::__construct( 'OpenStackCreateInstance' );
10 - wfLoadExtensionMessages('OpenStackManager');
11 - $credentials = $wgOpenStackManagerNovaAdminKeys;
12 - $this->adminNova = new OpenStackNovaController( $credentials );
13 - }
14 -
15 - function execute( $par ) {
16 - global $wgRequest, $wgOut;
17 -
18 - $this->setHeaders();
19 - $wgOut->setPagetitle("Create Instance");
20 -
21 - $instanceid = $wgRequest->getVal('instanceid');
22 -
23 - # TODO: Add project name field
24 -
25 - $instanceInfo = Array();
26 - $instanceInfo['instanceName'] = array(
27 - 'type' => 'text',
28 - 'label-message' => 'instancename',
29 - 'default' => '',
30 - 'section' => 'instance/info',
31 - );
32 -
33 - $instanceTypes = $this->adminNova->getInstanceTypes();
34 - $instanceType_keys = Array();
35 - foreach ( $instanceTypes as $instanceType ) {
36 - $instanceType_keys["$instanceType"] = $instanceType;
37 - }
38 - $instanceInfo['instanceType'] = array(
39 - 'type' => 'select',
40 - 'section' => 'instance/info',
41 - 'options' => $instanceType_keys,
42 - 'label-message' => 'instancetype',
43 - );
44 -
45 - # Availability zone names can't be translated. Get the keys, and make an array
46 - # where the name points to itself as a value
47 - $availabilityZones = $this->adminNova->getAvailabilityZones();
48 - $availabilityZone_keys = Array();
49 - foreach ( array_keys( $availabilityZones ) as $availabilityZone_key ) {
50 - $availabilityZone_keys["$availabilityZone_key"] = $availabilityZone_key;
51 - }
52 - $instanceInfo['availabilityZone'] = array(
53 - 'type' => 'select',
54 - 'section' => 'instance/info',
55 - 'options' => $availabilityZone_keys,
56 - 'label-message' => 'availabilityzone',
57 - );
58 -
59 - # Image names can't be translated. Get the image, and make an array
60 - # where the name points to itself as a value
61 - $images = $this->adminNova->getImages();
62 - $image_keys = Array();
63 - foreach ( array_keys($images) as $image_key ) {
64 - $image_keys["$image_key"] = $image_key;
65 - }
66 - $instanceInfo['imageType'] = array(
67 - 'type' => 'select',
68 - 'section' => 'instance/info',
69 - 'options' => $image_keys,
70 - 'label-message' => 'imagetype',
71 - );
72 -
73 - # Keypair names can't be translated. Get the keys, and make an array
74 - # where the name points to itself as a value
75 - # TODO: get keypairs as the user, not the admin
76 - $keypairs = $this->adminNova->getKeypairs();
77 - $keypair_keys = Array();
78 - foreach ( array_keys( $keypairs ) as $keypair_key ) {
79 - $keypair_keys["$keypair_key"] = $keypair_key;
80 - }
81 - $instanceInfo['keypair'] = array(
82 - 'type' => 'select',
83 - 'section' => 'instance/info',
84 - 'options' => $keypair_keys,
85 - 'label-message' => 'keypair',
86 - );
87 -
88 - #TODO: Add availablity zone field
89 -
90 - $instanceForm = new OpenStackCreateInstanceForm( $instanceInfo, 'openstackmanager-form' );
91 - $instanceForm->setTitle( SpecialPage::getTitleFor( 'OpenStackCreateInstance' ));
92 - $instanceForm->setSubmitID( 'openstackmanager-form-createinstancesubmit' );
93 - $instanceForm->setSubmitCallback( array( $this, 'tryCreateSubmit' ) );
94 - $instanceForm->show();
95 -
96 - }
97 -
98 - function tryCreateSubmit( $formData, $entryPoint = 'internal' ) {
99 - global $wgOut;
100 -
101 - $instance = $this->adminNova->createInstance( $formData['imageType'], $formData['keypair'],
102 - $formData['instanceType'], $formData['availabilityZone'] );
103 -
104 - $wgOut->addHTML('<p>Created instance ' . $instance->getInstanceID() . ' with image ' . $instance->getImageId() . '</p>');
105 -
106 - return true;
107 - }
108 -}
109 -
110 -class OpenStackCreateInstanceForm extends HTMLForm {
111 -}
Index: trunk/extensions/OpenStackManager/OpenStackManager.php
@@ -35,8 +35,10 @@
3636
3737 $wgExtensionMessagesFiles['OpenStackManager'] = $dir . 'OpenStackManager.i18n.php';
3838 $wgExtensionAliasesFiles['OpenStackManager'] = $dir . 'OpenStackManager.alias.php';
39 -$wgAutoloadClasses['OpenStackCreateInstance'] = $dir . 'SpecialCreateInstance.php';
 39+$wgAutoloadClasses['OpenStackNovaInstance'] = $dir . 'OpenStackNovaInstance.php';
4040 $wgAutoloadClasses['OpenStackNovaController'] = $dir . 'OpenStackNovaController.php';
 41+$wgAutoloadClasses['OpenStackNovaUser'] = $dir . 'OpenStackNovaUser.php';
 42+$wgAutoloadClasses['SpecialNovaInstance'] = $dir . 'SpecialNovaInstance.php';
4143 $wgAutoloadClasses['AmazonEC2'] = $dir . 'aws-sdk/sdk.class.php';
42 -$wgSpecialPages['OpenStackCreateInstance'] = 'OpenStackCreateInstance';
43 -$wgSpecialPageGroups['OpenStackCreateInstance'] = 'other';
 44+$wgSpecialPages['NovaInstance'] = 'SpecialNovaInstance';
 45+$wgSpecialPageGroups['NovaInstance'] = 'other';
Index: trunk/extensions/OpenStackManager/SpecialNovaInstance.php
@@ -0,0 +1,188 @@
 2+<?php
 3+class SpecialNovaInstance extends SpecialPage {
 4+
 5+ var $adminNova, $userNova;
 6+
 7+ function __construct() {
 8+ parent::__construct( 'NovaInstance' );
 9+ }
 10+
 11+ function execute( $par ) {
 12+ global $wgRequest;
 13+ global $wgOpenStackManagerNovaAdminKeys;
 14+
 15+ wfLoadExtensionMessages('OpenStackManager');
 16+ $user = new OpenStackNovaUser();
 17+ $project = $wgRequest->getVal('project');
 18+ if ( ! $user->exists() ) {
 19+ $this->noCredentials();
 20+ return true;
 21+ }
 22+ $userCredentials = $user->getCredentials( $project );
 23+ $this->userNova = new OpenStackNovaController( $userCredentials );
 24+ $adminCredentials = $wgOpenStackManagerNovaAdminKeys;
 25+ $this->adminNova = new OpenStackNovaController( $adminCredentials );
 26+
 27+ $action = $wgRequest->getVal('action');
 28+
 29+ if ( $action == "create" ) {
 30+ if ( ! $user->inProject( $project ) ) {
 31+ $this->notInProject();
 32+ return true;
 33+ }
 34+ $this->createInstance();
 35+ } else if ( $action == "modify" ) {
 36+ if ( ! $user->inProject( $project ) ) {
 37+ $this->notInProject();
 38+ return true;
 39+ }
 40+ $this->modifyInstance();
 41+ } else {
 42+ $this->listInstances();
 43+ }
 44+ }
 45+
 46+ function noCredentials() {
 47+ global $wgOut;
 48+
 49+ $this->setHeaders();
 50+ $wgOut->setPagetitle("No Nova credentials found for your account");
 51+ $wgOut->addHTML('<p>There were no Nova credentials found for your user account. Please ask a Nova administrator to create credentials for you.</p>');
 52+ }
 53+
 54+ function notInProject() {
 55+ global $wgOut;
 56+
 57+ $this->setHeaders();
 58+ $wgOut->setPagetitle("Your account is not in the project requested");
 59+ $wgOut->addHTML('<p>You can not complete the action requested as your user account is not in the project requested.</p>');
 60+ }
 61+
 62+ function createInstance() {
 63+ global $wgRequest, $wgOut;
 64+
 65+ $this->setHeaders();
 66+ $wgOut->setPagetitle("Create Instance");
 67+
 68+ $instanceid = $wgRequest->getVal('instanceid');
 69+
 70+ # TODO: Add project name field
 71+
 72+ $instanceInfo = Array();
 73+ $instanceInfo['instanceName'] = array(
 74+ 'type' => 'text',
 75+ 'label-message' => 'instancename',
 76+ 'default' => '',
 77+ 'section' => 'instance/info',
 78+ );
 79+
 80+ $instanceTypes = $this->adminNova->getInstanceTypes();
 81+ $instanceType_keys = Array();
 82+ foreach ( $instanceTypes as $instanceType ) {
 83+ $instanceType_keys["$instanceType"] = $instanceType;
 84+ }
 85+ $instanceInfo['instanceType'] = array(
 86+ 'type' => 'select',
 87+ 'section' => 'instance/info',
 88+ 'options' => $instanceType_keys,
 89+ 'label-message' => 'instancetype',
 90+ );
 91+
 92+ # Availability zone names can't be translated. Get the keys, and make an array
 93+ # where the name points to itself as a value
 94+ $availabilityZones = $this->adminNova->getAvailabilityZones();
 95+ $availabilityZone_keys = Array();
 96+ foreach ( array_keys( $availabilityZones ) as $availabilityZone_key ) {
 97+ $availabilityZone_keys["$availabilityZone_key"] = $availabilityZone_key;
 98+ }
 99+ $instanceInfo['availabilityZone'] = array(
 100+ 'type' => 'select',
 101+ 'section' => 'instance/info',
 102+ 'options' => $availabilityZone_keys,
 103+ 'label-message' => 'availabilityzone',
 104+ );
 105+
 106+ # Image names can't be translated. Get the image, and make an array
 107+ # where the name points to itself as a value
 108+ $images = $this->adminNova->getImages();
 109+ $image_keys = Array();
 110+ foreach ( array_keys($images) as $image_key ) {
 111+ $image_keys["$image_key"] = $image_key;
 112+ }
 113+ $instanceInfo['imageType'] = array(
 114+ 'type' => 'select',
 115+ 'section' => 'instance/info',
 116+ 'options' => $image_keys,
 117+ 'label-message' => 'imagetype',
 118+ );
 119+
 120+ # Keypair names can't be translated. Get the keys, and make an array
 121+ # where the name points to itself as a value
 122+ # TODO: get keypairs as the user, not the admin
 123+ $keypairs = $this->userNova->getKeypairs();
 124+ $keypair_keys = Array();
 125+ foreach ( array_keys( $keypairs ) as $keypair_key ) {
 126+ $keypair_keys["$keypair_key"] = $keypair_key;
 127+ }
 128+ $instanceInfo['keypair'] = array(
 129+ 'type' => 'select',
 130+ 'section' => 'instance/info',
 131+ 'options' => $keypair_keys,
 132+ 'label-message' => 'keypair',
 133+ );
 134+
 135+ #TODO: Add availablity zone field
 136+
 137+ $instanceForm = new OpenStackCreateInstanceForm( $instanceInfo, 'openstackmanager-form' );
 138+ $instanceForm->setTitle( SpecialPage::getTitleFor( 'OpenStackCreateInstance' ));
 139+ $instanceForm->setSubmitID( 'openstackmanager-form-createinstancesubmit' );
 140+ $instanceForm->setSubmitCallback( array( $this, 'tryCreateSubmit' ) );
 141+ $instanceForm->show();
 142+
 143+ }
 144+
 145+ function modifyInstance() {
 146+ return true;
 147+ }
 148+
 149+ function listInstances() {
 150+ global $wgOut;
 151+
 152+ $this->setHeaders();
 153+ $wgOut->setPagetitle("Instance list");
 154+
 155+ $out = '';
 156+ $instances = $this->adminNova->getInstances();
 157+ $out .= Html::element( 'th', array(), 'ID' );
 158+ $out .= Html::element( 'th', array(), 'State' );
 159+ $out .= Html::element( 'th', array(), 'Type' );
 160+ $out .= Html::element( 'th', array(), 'Image ID' );
 161+ $out .= Html::element( 'th', array(), 'Project' );
 162+ foreach ( $instances as $instance ) {
 163+ $instanceOut = Html::element( 'td', array(), $instance->getInstanceId() );
 164+ $instanceOut .= Html::element( 'td', array(), $instance->getInstanceState() );
 165+ $instanceOut .= Html::element( 'td', array(), $instance->getInstanceType() );
 166+ $instanceOut .= Html::element( 'td', array(), $instance->getImageId() );
 167+ $instanceOut .= Html::element( 'td', array(), $instance->getOwner() );
 168+ $out .= Html::rawElement( 'tr', array(), $instanceOut );
 169+ }
 170+ $out = Html::rawElement( 'table', array( 'id' => 'novainstancelist', 'class' => 'wikitable' ), $out );
 171+
 172+ $wgOut->addHTML( $out );
 173+ }
 174+
 175+ function tryCreateSubmit( $formData, $entryPoint = 'internal' ) {
 176+ global $wgOut;
 177+
 178+ $instance = $this->userNova->createInstance( $formData['imageType'], $formData['keypair'],
 179+ $formData['instanceType'], $formData['availabilityZone'] );
 180+
 181+ $out = Html::element( 'p', array(), 'Created instance ' . $instance->getInstanceID() . ' with image ' . $instance->getImageId() );
 182+
 183+ $wgOut->addHTML( $out );
 184+ return true;
 185+ }
 186+}
 187+
 188+class OpenStackCreateInstanceForm extends HTMLForm {
 189+}
Property changes on: trunk/extensions/OpenStackManager/SpecialNovaInstance.php
___________________________________________________________________
Added: svn:eol-style
1190 + native
Index: trunk/extensions/OpenStackManager/OpenStackNovaUser.php
@@ -0,0 +1,99 @@
 2+<?php
 3+
 4+class OpenStackNovaUser {
 5+
 6+ var $userDN;
 7+ var $userInfo;
 8+
 9+ function __construct() {
 10+ global $wgAuth, $wgUser;
 11+ global $wgOpenStackManagerLDAPUser, $wgOpenStackManagerLDAPUserPassword;
 12+
 13+ $this->connect();
 14+ $this->userDN = $wgAuth->getUserDN( strtolower( $wgUser->getName() ) );
 15+ $this->userInfo = $wgAuth->userInfo;
 16+ }
 17+
 18+ function getCredentials( $project='' ) {
 19+ if ( isset( $this->userInfo[0]['accesskey'] ) ) {
 20+ $accessKey = $this->userInfo[0]['accesskey'][0];
 21+ $accessKey = $accessKey . ':' . $project;
 22+ } else {
 23+ $accessKey = '';
 24+ }
 25+ if ( isset( $this->userInfo[0]['secretkey'] ) ) {
 26+ $secretKey = $this->userInfo[0]['secretkey'][0];
 27+ } else {
 28+ $secretKey = '';
 29+ }
 30+ return array( 'accessKey' => $accessKey, 'secretKey' => $secretKey );
 31+ }
 32+
 33+ function isAdmin() {
 34+ if ( isset( $this->userInfo[0]['isadmin'] ) ) {
 35+ $isAdmin = $this->userInfo[0]['isadmin'];
 36+ if ( strtolower( $isAdmin ) == "true" ) {
 37+ return true;
 38+ }
 39+ }
 40+ return false;
 41+ }
 42+
 43+ function exists() {
 44+ $credentials = $this->getCredentials();
 45+ if ( $credentials['accessKey'] && $credentials['secretKey'] ) {
 46+ return true;
 47+ } else {
 48+ return false;
 49+ }
 50+ }
 51+
 52+ function hasProjects() {
 53+ $this->connect();
 54+ return array();
 55+ }
 56+
 57+ function hasRoles() {
 58+ $this->connect();
 59+ return array();
 60+ }
 61+
 62+ function inProject( $project ) {
 63+ global $wgAuth;
 64+ global $wgOpenStackManagerLDAPProjectBaseDN;
 65+
 66+ $this->connect();
 67+
 68+ $filter = "(&(cn=$project)(member=$this->userDN))";
 69+ $entry = ldap_search( $wgAuth->ldapconn, $wgOpenStackManagerLDAPProjectBaseDN, $filter );
 70+ if ( $entry ) {
 71+ $entries = ldap_get_entries( $wgAuth->ldapconn, $entry );
 72+ if ( $entries ) {
 73+ if ( $entries['count'] == "0" ) {
 74+ $wgAuth->printDebug( "Couldn't find the user in project: $project", NONSENSITIVE );
 75+ return false;
 76+ } else {
 77+ return true;
 78+ }
 79+ } else {
 80+ return false;
 81+ }
 82+ } else {
 83+ return false;
 84+ }
 85+ }
 86+
 87+ function inRole( $role, $project) {
 88+ $this->connect();
 89+
 90+ return true;
 91+ }
 92+
 93+ function connect() {
 94+ global $wgAuth;
 95+ global $wgOpenStackManagerLDAPUser, $wgOpenStackManagerLDAPUserPassword;
 96+
 97+ $wgAuth->connect();
 98+ $wgAuth->bindAs( $wgOpenStackManagerLDAPUser, $wgOpenStackManagerLDAPUserPassword );
 99+ }
 100+}
Index: trunk/extensions/OpenStackManager/OpenStackNovaController.php
@@ -36,7 +36,7 @@
3737 if ( count( $this->instances ) == 0 || $reload ) {
3838 $this->instances = array();
3939 $response = $this->novaConnection->describe_instances();
40 - $instances = $instances->body->reservationSet->item;
 40+ $instances = $response->body->reservationSet->item;
4141 foreach ( $instances as $instance ) {
4242 $instance = new OpenStackNovaInstance($instance);
4343 $instanceId = $instance->getInstanceId();

Status & tagging log