PageRenderTime 202ms CodeModel.GetById 81ms app.highlight 20ms RepoModel.GetById 60ms app.codeStats 0ms

/vendor/Microsoft/SqlAzure/Management/Client.php

https://bitbucket.org/ktos/tinyshare
PHP | 564 lines | 289 code | 60 blank | 215 comment | 76 complexity | 9fca9f7dc4006d1ccf53822f97bd3fa6 MD5 | raw file
  1<?php
  2/**
  3 * Copyright (c) 2009 - 2011, RealDolmen
  4 * All rights reserved.
  5 *
  6 * Redistribution and use in source and binary forms, with or without
  7 * modification, are permitted provided that the following conditions are met:
  8 *     * Redistributions of source code must retain the above copyright
  9 *       notice, this list of conditions and the following disclaimer.
 10 *     * Redistributions in binary form must reproduce the above copyright
 11 *       notice, this list of conditions and the following disclaimer in the
 12 *       documentation and/or other materials provided with the distribution.
 13 *     * Neither the name of RealDolmen nor the
 14 *       names of its contributors may be used to endorse or promote products
 15 *       derived from this software without specific prior written permission.
 16 *
 17 * THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 20 * DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 27 *
 28 * @category   Microsoft
 29 * @package    Microsoft_WindowsAzure
 30 * @subpackage Management
 31 * @copyright  Copyright (c) 2009 - 2011, RealDolmen (http://www.realdolmen.com)
 32 * @license    http://phpazure.codeplex.com/license
 33 * @version    $Id: Storage.php 51671 2010-09-30 08:33:45Z unknown $
 34 */
 35
 36/**
 37 * @see Microsoft_AutoLoader
 38 */
 39require_once dirname(__FILE__) . '/../../AutoLoader.php';
 40
 41/**
 42 * @category   Microsoft
 43 * @package    Microsoft_SqlAzure
 44 * @subpackage Management
 45 * @copyright  Copyright (c) 2009 - 2011, RealDolmen (http://www.realdolmen.com)
 46 * @license    http://phpazure.codeplex.com/license
 47 */
 48class Microsoft_SqlAzure_Management_Client
 49{
 50	/**
 51	 * Management service URL
 52	 */
 53	const URL_MANAGEMENT        = "https://management.database.windows.net:8443";
 54	
 55	/**
 56	 * Operations
 57	 */
 58	const OP_OPERATIONS                = "operations";
 59	const OP_SERVERS                   = "servers";
 60	const OP_FIREWALLRULES             = "firewallrules";
 61
 62	/**
 63	 * Current API version
 64	 * 
 65	 * @var string
 66	 */
 67	protected $_apiVersion = '1.0';
 68	
 69	/**
 70	 * Subscription ID
 71	 *
 72	 * @var string
 73	 */
 74	protected $_subscriptionId = '';
 75	
 76	/**
 77	 * Management certificate path (.PEM)
 78	 *
 79	 * @var string
 80	 */
 81	protected $_certificatePath = '';
 82	
 83	/**
 84	 * Management certificate passphrase
 85	 *
 86	 * @var string
 87	 */
 88	protected $_certificatePassphrase = '';
 89	
 90	/**
 91	 * Microsoft_Http_Client channel used for communication with REST services
 92	 * 
 93	 * @var Microsoft_Http_Client
 94	 */
 95	protected $_httpClientChannel = null;	
 96
 97	/**
 98	 * Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract instance
 99	 * 
100	 * @var Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract
101	 */
102	protected $_retryPolicy = null;
103	
104	/**
105	 * Returns the last request ID
106	 * 
107	 * @var string
108	 */
109	protected $_lastRequestId = null;
110	
111	/**
112	 * Creates a new Microsoft_SqlAzure_Management_Client instance
113	 * 
114	 * @param string $subscriptionId Subscription ID
115	 * @param string $certificatePath Management certificate path (.PEM)
116	 * @param string $certificatePassphrase Management certificate passphrase
117     * @param Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests
118	 */
119	public function __construct(
120		$subscriptionId,
121		$certificatePath,
122		$certificatePassphrase,
123		Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy = null
124	) {
125		$this->_subscriptionId = $subscriptionId;
126		$this->_certificatePath = $certificatePath;
127		$this->_certificatePassphrase = $certificatePassphrase;
128		
129		$this->_retryPolicy = $retryPolicy;
130		if (is_null($this->_retryPolicy)) {
131		    $this->_retryPolicy = Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract::noRetry();
132		}
133		
134		// Setup default Microsoft_Http_Client channel
135		$options = array(
136		    'adapter'       => 'Microsoft_Http_Client_Adapter_Socket',
137		    'ssltransport'  => 'ssl',
138			'sslcert'       => $this->_certificatePath,
139			'sslpassphrase' => $this->_certificatePassphrase,
140			'sslusecontext' => true,
141		);
142		if (function_exists('curl_init')) {
143			// Set cURL options if cURL is used afterwards
144			$options['curloptions'] = array(
145					CURLOPT_FOLLOWLOCATION => true,
146					CURLOPT_TIMEOUT => 120,
147			);
148		}
149		$this->_httpClientChannel = new Microsoft_Http_Client(null, $options);
150	}
151	
152	/**
153	 * Set the HTTP client channel to use
154	 * 
155	 * @param Microsoft_Http_Client_Adapter_Interface|string $adapterInstance Adapter instance or adapter class name.
156	 */
157	public function setHttpClientChannel($adapterInstance = 'Microsoft_Http_Client_Adapter_Socket')
158	{
159		$this->_httpClientChannel->setAdapter($adapterInstance);
160	}
161	
162    /**
163     * Retrieve HTTP client channel
164     * 
165     * @return Microsoft_Http_Client_Adapter_Interface
166     */
167    public function getHttpClientChannel()
168    {
169        return $this->_httpClientChannel;
170    }
171	
172	/**
173	 * Returns the Windows Azure subscription ID
174	 * 
175	 * @return string
176	 */
177	public function getSubscriptionId()
178	{
179		return $this->_subscriptionId;
180	}
181	
182	/**
183	 * Returns the last request ID.
184	 * 
185	 * @return string
186	 */
187	public function getLastRequestId()
188	{
189		return $this->_lastRequestId;
190	}
191	
192	/**
193	 * Get base URL for creating requests
194	 *
195	 * @return string
196	 */
197	public function getBaseUrl()
198	{
199		return self::URL_MANAGEMENT . '/' . $this->_subscriptionId;
200	}
201	
202	/**
203	 * Perform request using Microsoft_Http_Client channel
204	 *
205	 * @param string $path Path
206	 * @param array $query Query parameters
207	 * @param string $httpVerb HTTP verb the request will use
208	 * @param array $headers x-ms headers to add
209	 * @param mixed $rawData Optional RAW HTTP data to be sent over the wire
210	 * @return Microsoft_Http_Response
211	 */
212	protected function _performRequest(
213		$path = '/',
214		$query = array(),
215		$httpVerb = Microsoft_Http_Client::GET,
216		$headers = array(),
217		$rawData = null
218	) {
219	    // Clean path
220		if (strpos($path, '/') !== 0) {
221			$path = '/' . $path;
222		}
223			
224		// Clean headers
225		if (is_null($headers)) {
226		    $headers = array();
227		}
228		
229		// Ensure cUrl will also work correctly:
230		//  - disable Content-Type if required
231		//  - disable Expect: 100 Continue
232		if (!isset($headers["Content-Type"])) {
233			$headers["Content-Type"] = '';
234		}
235		//$headers["Expect"] = '';
236
237		// Add version header
238		$headers['x-ms-version'] = $this->_apiVersion;
239
240		// Generate URL and sign request
241		$requestUrl = $this->getBaseUrl() . rawurlencode($path);
242		$requestHeaders = $headers;
243		if (count($query) > 0) {
244			$queryString = '';
245			foreach ($query as $key => $value) {
246				$queryString .= ($queryString ? '&' : '?') . rawurlencode($key) . '=' . rawurlencode($value);
247			}			
248			$requestUrl .= $queryString;
249		}
250
251		// Prepare request 
252		$this->_httpClientChannel->resetParameters(true);
253		$this->_httpClientChannel->setUri($requestUrl);
254		$this->_httpClientChannel->setHeaders($requestHeaders);
255		$this->_httpClientChannel->setRawData($rawData);
256
257		// Execute request
258		$response = $this->_retryPolicy->execute(
259		    array($this->_httpClientChannel, 'request'),
260		    array($httpVerb)
261		);
262		
263		// Store request id
264		$this->_lastRequestId = $response->getHeader('x-ms-request-id');
265		
266		return $response;
267	}
268	
269	/** 
270	 * Parse result from Microsoft_Http_Response
271	 *
272	 * @param Microsoft_Http_Response $response Response from HTTP call
273	 * @return object
274	 * @throws Microsoft_WindowsAzure_Exception
275	 */
276	protected function _parseResponse(Microsoft_Http_Response $response = null)
277	{
278		if (is_null($response)) {
279			throw new Microsoft_SqlAzure_Exception('Response should not be null.');
280		}
281		
282        $xml = @simplexml_load_string($response->getBody());
283        
284        if ($xml !== false) {
285            // Fetch all namespaces 
286            $namespaces = array_merge($xml->getNamespaces(true), $xml->getDocNamespaces(true)); 
287            
288            // Register all namespace prefixes
289            foreach ($namespaces as $prefix => $ns) { 
290                if ($prefix != '') {
291                    $xml->registerXPathNamespace($prefix, $ns);
292                } 
293            } 
294        }
295        
296        return $xml;
297	}
298    
299	/**
300	 * Get error message from Microsoft_Http_Response
301	 *
302	 * @param Microsoft_Http_Response $response Repsonse
303	 * @param string $alternativeError Alternative error message
304	 * @return string
305	 */
306	protected function _getErrorMessage(Microsoft_Http_Response $response, $alternativeError = 'Unknown error.')
307	{
308		$response = $this->_parseResponse($response);
309		if ($response && $response->Message) {
310			return (string)$response->Message;
311		} else {
312			return $alternativeError;
313		}
314	}
315	
316	/**
317	 * The Create Server operation adds a new SQL Azure server to a subscription.
318	 * 
319	 * @param string $administratorLogin Administrator login.
320	 * @param string $administratorPassword Administrator password.
321	 * @param string $location Location of the server.
322	 * @return Microsoft_SqlAzure_Management_ServerInstance Server information.
323	 * @throws Microsoft_SqlAzure_Management_Exception
324	 */
325	public function createServer($administratorLogin, $administratorPassword, $location)
326	{
327		if ($administratorLogin == '' || is_null($administratorLogin)) {
328    		throw new Microsoft_SqlAzure_Management_Exception('Administrator login should be specified.');
329    	}
330		if ($administratorPassword == '' || is_null($administratorPassword)) {
331    		throw new Microsoft_SqlAzure_Management_Exception('Administrator password should be specified.');
332    	}
333    	if (is_null($location) && is_null($affinityGroup)) {
334    		throw new Microsoft_SqlAzure_Management_Exception('Please specify a location for the server.');
335    	}
336    	
337        $response = $this->_performRequest(self::OP_SERVERS, array(),
338    		Microsoft_Http_Client::POST,
339    		array('Content-Type' => 'application/xml; charset=utf-8'),
340    		'<Server xmlns="http://schemas.microsoft.com/sqlazure/2010/12/"><AdministratorLogin>' . $administratorLogin . '</AdministratorLogin><AdministratorLoginPassword>' . $administratorPassword . '</AdministratorLoginPassword><Location>' . $location . '</Location></Server>');
341 	
342    	if ($response->isSuccessful()) {
343			$xml = $this->_parseResponse($response);
344			
345			return new Microsoft_SqlAzure_Management_ServerInstance(
346				(string)$xml,
347				$administratorLogin,
348				$location
349			);
350    	} else {
351			throw new Microsoft_SqlAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
352		}	
353	}
354	
355	/**
356	 * The Get Servers operation enumerates SQL Azure servers that are provisioned for a subscription.
357	 * 
358	 * @return array An array of Microsoft_SqlAzure_Management_ServerInstance.
359	 * @throws Microsoft_SqlAzure_Management_Exception
360	 */
361	public function listServers()
362	{
363        $response = $this->_performRequest(self::OP_SERVERS);
364 	
365    	if ($response->isSuccessful()) {
366			$xml = $this->_parseResponse($response);
367			$xmlServices = null;
368			
369    		if (!$xml->Server) {
370				return array();
371			}
372		    if (count($xml->Server) > 1) {
373    		    $xmlServices = $xml->Server;
374    		} else {
375    		    $xmlServices = array($xml->Server);
376    		}
377    		
378			$services = array();
379			if (!is_null($xmlServices)) {				
380				for ($i = 0; $i < count($xmlServices); $i++) {
381					$services[] = new Microsoft_SqlAzure_Management_ServerInstance(
382					    (string)$xmlServices[$i]->Name,
383					    (string)$xmlServices[$i]->AdministratorLogin,
384					    (string)$xmlServices[$i]->Location
385					);
386				}
387			}
388			return $services;
389    	} else {
390			throw new Microsoft_SqlAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
391		}
392	}
393	
394	/**
395	 * The Drop Server operation drops a SQL Azure server from a subscription.
396	 * 
397	 * @param string $serverName Server to drop.
398	 * @throws Microsoft_SqlAzure_Management_Exception
399	 */
400	public function dropServer($serverName)
401	{
402		if ($serverName == '' || is_null($serverName)) {
403    		throw new Microsoft_SqlAzure_Management_Exception('Server name should be specified.');
404    	}
405    	
406        $response = $this->_performRequest(self::OP_SERVERS . '/' . $serverName, array(), Microsoft_Http_Client::DELETE);
407
408    	if (!$response->isSuccessful()) {
409			throw new Microsoft_SqlAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
410		}	
411	}
412	
413	/**
414	 * The Set Server Administrator Password operation sets the administrative password of a SQL Azure server for a subscription.
415	 * 
416	 * @param string $serverName Server to set password for.
417	 * @param string $administratorPassword Administrator password.
418	 * @throws Microsoft_SqlAzure_Management_Exception
419	 */
420	public function setAdministratorPassword($serverName, $administratorPassword)
421	{
422		if ($serverName == '' || is_null($serverName)) {
423    		throw new Microsoft_SqlAzure_Management_Exception('Server name should be specified.');
424    	}
425		if ($administratorPassword == '' || is_null($administratorPassword)) {
426    		throw new Microsoft_SqlAzure_Management_Exception('Administrator password should be specified.');
427    	}
428    	
429        $response = $this->_performRequest(self::OP_SERVERS . '/' . $serverName, array('op' => 'ResetPassword'),
430    		Microsoft_Http_Client::POST,
431    		array('Content-Type' => 'application/xml; charset=utf-8'),
432    		'<AdministratorLoginPassword xmlns="http://schemas.microsoft.com/sqlazure/2010/12/">' . $administratorPassword . '</AdministratorLoginPassword>');
433    		
434    	if (!$response->isSuccessful()) {
435			throw new Microsoft_SqlAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
436		}	
437	}
438	
439	/**
440	 * The Set Server Firewall Rule operation updates an existing firewall rule or adds a new firewall rule for a SQL Azure server that belongs to a subscription.
441	 * 
442	 * @param string $serverName Server name.
443	 * @param string $ruleName Firewall rule name.
444	 * @param string $startIpAddress Start IP address.
445	 * @param string $endIpAddress End IP address.
446	 * @return Microsoft_SqlAzure_Management_FirewallRuleInstance
447	 * @throws Microsoft_SqlAzure_Management_Exception
448	 */
449	public function createFirewallRule($serverName, $ruleName, $startIpAddress, $endIpAddress)
450	{
451		if ($serverName == '' || is_null($serverName)) {
452    		throw new Microsoft_SqlAzure_Management_Exception('Server name should be specified.');
453    	}
454		if ($ruleName == '' || is_null($ruleName)) {
455    		throw new Microsoft_SqlAzure_Management_Exception('Rule name should be specified.');
456    	}
457		if ($startIpAddress == '' || is_null($startIpAddress) || !filter_var($startIpAddress, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
458    		throw new Microsoft_SqlAzure_Management_Exception('Start IP address should be specified.');
459    	}
460		if ($endIpAddress == '' || is_null($endIpAddress) || !filter_var($endIpAddress, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
461    		throw new Microsoft_SqlAzure_Management_Exception('End IP address should be specified.');
462    	}
463    	
464        $response = $this->_performRequest(self::OP_SERVERS . '/' . $serverName . '/' . self::OP_FIREWALLRULES . '/' . $ruleName, array(),
465    		Microsoft_Http_Client::PUT,
466    		array('Content-Type' => 'application/xml; charset=utf-8'),
467    		'<FirewallRule xmlns="http://schemas.microsoft.com/sqlazure/2010/12/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.microsoft.com/sqlazure/2010/12/ FirewallRule.xsd"><StartIpAddress>' . $startIpAddress . '</StartIpAddress><EndIpAddress>' . $endIpAddress . '</EndIpAddress></FirewallRule>');
468
469    	if ($response->isSuccessful()) {
470    		return new Microsoft_SqlAzure_Management_FirewallRuleInstance(
471    			$ruleName,
472    			$startIpAddress,
473    			$endIpAddress
474    		);
475    	} else {
476			throw new Microsoft_SqlAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
477		}
478	}
479	
480	/**
481	 * The Get Server Firewall Rules operation retrieves a list of all the firewall rules for a SQL Azure server that belongs to a subscription.
482	 * 
483	 * @param string $serverName Server name.
484	 * @return Array of Microsoft_SqlAzure_Management_FirewallRuleInstance.
485	 * @throws Microsoft_SqlAzure_Management_Exception
486	 */
487	public function listFirewallRules($serverName)
488	{
489		if ($serverName == '' || is_null($serverName)) {
490    		throw new Microsoft_SqlAzure_Management_Exception('Server name should be specified.');
491    	}
492    	
493	    $response = $this->_performRequest(self::OP_SERVERS . '/' . $serverName . '/' . self::OP_FIREWALLRULES);
494 	
495    	if ($response->isSuccessful()) {
496			$xml = $this->_parseResponse($response);
497			$xmlServices = null;
498			
499    		if (!$xml->FirewallRule) {
500				return array();
501			}
502		    if (count($xml->FirewallRule) > 1) {
503    		    $xmlServices = $xml->FirewallRule;
504    		} else {
505    		    $xmlServices = array($xml->FirewallRule);
506    		}
507    		
508			$services = array();
509			if (!is_null($xmlServices)) {				
510				for ($i = 0; $i < count($xmlServices); $i++) {
511					$services[] = new Microsoft_SqlAzure_Management_FirewallRuleInstance(
512					    (string)$xmlServices[$i]->Name,
513					    (string)$xmlServices[$i]->StartIpAddress,
514					    (string)$xmlServices[$i]->EndIpAddress
515					);
516				}
517			}
518			return $services;
519    	} else {
520			throw new Microsoft_SqlAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
521		}		
522	}
523	
524	/**
525	 * The Delete Server Firewall Rule operation deletes a firewall rule from a SQL Azure server that belongs to a subscription.
526	 * 
527	 * @param string $serverName Server name.
528	 * @param string $ruleName Rule name.
529	 * @throws Microsoft_SqlAzure_Management_Exception
530	 */
531	public function deleteFirewallRule($serverName, $ruleName)
532	{
533		if ($serverName == '' || is_null($serverName)) {
534    		throw new Microsoft_SqlAzure_Management_Exception('Server name should be specified.');
535    	}
536		if ($ruleName == '' || is_null($ruleName)) {
537    		throw new Microsoft_SqlAzure_Management_Exception('Rule name should be specified.');
538    	}
539    	
540        $response = $this->_performRequest(self::OP_SERVERS . '/' . $serverName . '/' . self::OP_FIREWALLRULES . '/' . $ruleName, array(),
541    		Microsoft_Http_Client::DELETE);
542
543    	if (!$response->isSuccessful()) {
544			throw new Microsoft_SqlAzure_Management_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
545		}
546	}
547	
548	/**
549	 * Creates a firewall rule for Microsoft Services. This is required if access to SQL Azure is required from other services like Windows Azure.
550	 * 
551	 * @param string $serverName Server name.
552	 * @param boolean $allowAccess Allow access from other Microsoft Services?
553	 * @throws Microsoft_SqlAzure_Management_Exception
554	 */
555	public function createFirewallRuleForMicrosoftServices($serverName, $allowAccess)
556	{
557		if ($allowAccess) {
558			$this->createFirewallRule($serverName, 'MicrosoftServices', '0.0.0.0', '0.0.0.0');
559		} else {
560			$this->deleteFirewallRule($serverName, 'MicrosoftServices');
561		}
562	}
563	
564}