You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by to...@apache.org on 2012/04/13 05:05:58 UTC

svn commit: r1325595 - /libcloud/trunk/libcloud/compute/drivers/vcl.py

Author: tomaz
Date: Fri Apr 13 03:05:58 2012
New Revision: 1325595

URL: http://svn.apache.org/viewvc?rev=1325595&view=rev
Log:
Forgot to add this file.

Added:
    libcloud/trunk/libcloud/compute/drivers/vcl.py

Added: libcloud/trunk/libcloud/compute/drivers/vcl.py
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/compute/drivers/vcl.py?rev=1325595&view=auto
==============================================================================
--- libcloud/trunk/libcloud/compute/drivers/vcl.py (added)
+++ libcloud/trunk/libcloud/compute/drivers/vcl.py Fri Apr 13 03:05:58 2012
@@ -0,0 +1,321 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""
+VCL driver
+"""
+
+import sys
+import time
+
+import libcloud
+from libcloud.utils.py3 import xmlrpclib
+
+from libcloud.common.types import InvalidCredsError, LibcloudError
+from libcloud.compute.types import Provider, NodeState
+from libcloud.compute.base import NodeDriver, Node
+from libcloud.compute.base import NodeLocation, NodeSize, NodeImage
+
+
+class VCLSafeTransport(xmlrpclib.SafeTransport):
+    def __init__(self, datetime, user, passwd, host):
+
+        self._pass = passwd
+        self._use_datetime = datetime
+        self._connection = (None, None)
+        self._extra_headers = []
+
+    def send_content(self, connection, request_body):
+        connection.putheader('Content-Type', 'text/xml')
+        connection.putheader('X-APIVERSION', '2')
+        connection.putheader('X-User', self._user)
+        connection.putheader('X-Pass', self._pass)
+        connection.putheader('Content-Length', str(len(request_body)))
+        connection.endheaders(request_body)
+
+
+class VCLProxy(xmlrpclib.ServerProxy):
+    API_POSTFIX = '/index.php?mode=xmlrpccall'
+    transportCls = VCLSafeTransport
+
+    def __init__(self, user, key, secure, host, port, driver, verbose=False):
+        url = ''
+        cls = self.transportCls
+
+        if secure:
+            url = 'https://'
+            port = port or 443
+        else:
+            url = 'http://'
+            port = port or 80
+
+        url += host + ':' + str(port)
+        url += VCLProxy.API_POSTFIX
+
+        self.API = url
+        t = cls(0, user, key, self.API)
+
+        xmlrpclib.ServerProxy.__init__(
+            self,
+            uri=self.API,
+            transport=t,
+            verbose=verbose
+        )
+
+
+class VCLConnection(object):
+    """
+    Connection class for the VCL driver
+    """
+
+    proxyCls = VCLProxy
+    driver = None
+
+    def __init__(self, user, key, secure, host, port):
+        self.user = user
+        self.key = key
+        self.secure = secure
+        self.host = host
+        self.port = port
+
+    def request(self, method, *args, **kwargs):
+        sl = self.proxyCls(user=self.user, key=self.key, secure=self.secure,
+                           host=self.host, port=self.port, driver=self.driver)
+
+        try:
+            return getattr(sl, method)(*args)
+        except xmlrpclib.Fault:
+            e = sys.exc_info()[1]
+            if e.faultCode == 'VCL_Account':
+                raise InvalidCredsError(e.faultString)
+            raise LibcloudError(e, driver=self.driver)
+
+
+class VCLNodeDriver(NodeDriver):
+    """
+    VCL node driver
+
+    @keyword:   host: The VCL host to which you make requests(required)
+    @type:      host: C{string}
+    """
+
+    NODE_STATE_MAP = {
+        'ready': NodeState.RUNNING,
+        'failed': NodeState.TERMINATED,
+        'timedout': NodeState.TERMINATED,
+        'loading': NodeState.PENDING,
+        'time': NodeState.PENDING,
+        'future': NodeState.PENDING,
+        'error': NodeState.UNKNOWN,
+        'notready': NodeState.PENDING,
+        'notavailable': NodeState.TERMINATED,
+        'success': NodeState.PENDING
+    }
+
+    connectionCls = VCLConnection
+    name = 'VCL'
+    type = Provider.VCL
+
+    def __init__(self, key, secret, secure=True, host=None, port=None, *args,
+                 **kwargs):
+        if not host:
+            raise Exception('When instantiating VCL driver directly ' +
+                            'you also need to provide host')
+
+        self.key = key
+        self.host = host
+        self.secret = secret
+        self.connection = self.connectionCls(key, secret, secure, host, port)
+        self.connection.driver = self
+
+    def _vcl_request(self, method, *args):
+        res = self.connection.request(
+            method,
+            *args
+        )
+        if(res['status'] == 'error'):
+            raise LibcloudError(res['errormsg'], driver=self)
+        return res
+
+    def create_node(self, **kwargs):
+        """Create a new VCL reservation
+
+        See L{NodeDriver.create_node} for more keyword args.
+        size and name ignored, image is the id from list_images
+        @keyword    start: start time as unix timestamp
+        @type       start: C{string}
+
+        @keyword    length: length of time in minutes
+        @type       length: C{string}
+        """
+
+        image = kwargs["image"]
+        start = kwargs.get('start', int(time.time()))
+        length = kwargs.get('length', '60')
+
+        res = self._vcl_request(
+            "XMLRPCaddRequest",
+            image.id,
+            start,
+            length
+        )
+
+        return Node(
+            id=res['requestid'],
+            name=image.name,
+            state=self.NODE_STATE_MAP[res['status']],
+            public_ips=[],
+            private_ips=[],
+            driver=self,
+            image=image.name
+        )
+
+    def destroy_node(self, node):
+        """
+        End VCL reservation for the node passed in.
+        Throws error if request fails.
+        """
+        try:
+            res = self._vcl_request(
+                'XMLRPCendRequest',
+                node.id
+            )
+        except LibcloudError:
+            return False
+        return True
+
+    def _to_image(self, img):
+        return NodeImage(
+            id=img['id'],
+            name=img['name'],
+            driver=self.connection.driver
+        )
+
+    def list_images(self, location=None):
+        """
+        List images available to the user provided credentials
+        """
+        res = self.connection.request(
+            "XMLRPCgetImages"
+        )
+        return [self._to_image(i) for i in res]
+
+    def list_sizes(self, location=None):
+        """
+        VCL does not choosing sizes for node creation.
+        Size of images are statically set by administrators.
+        """
+        return [NodeSize(
+            't1.micro',
+            'none',
+            '512',
+            0, 0, 0, self)
+        ]
+
+    def _to_connect_data(self, request_id, ipaddr):
+        res = self._vcl_request(
+            "XMLRPCgetRequestConnectData",
+            request_id,
+            ipaddr
+        )
+        return res
+
+    def _to_status(self, requestid, imagename, ipaddr):
+        res = self._vcl_request(
+            "XMLRPCgetRequestStatus",
+            requestid
+        )
+
+        public_ips = []
+        extra = []
+        if(res['status'] == 'ready'):
+            cdata = self._to_connect_data(requestid, ipaddr)
+            public_ips = [cdata['serverIP']]
+            extra = {
+                'user': cdata['user'],
+                'pass': cdata['password']
+            }
+        return Node(
+            id=requestid,
+            name=imagename,
+            state=self.NODE_STATE_MAP[res['status']],
+            public_ips=public_ips,
+            private_ips=[],
+            driver=self,
+            image=imagename,
+            extra=extra
+        )
+
+    def _to_nodes(self, res, ipaddr):
+        return [self._to_status(
+            h['requestid'],
+            h['imagename'],
+            ipaddr
+        ) for h in res]
+
+    def list_nodes(self, ipaddr):
+        res = self._vcl_request(
+            "XMLRPCgetRequestIds"
+        )
+        return self._to_nodes(res['requests'], ipaddr)
+
+    def ex_update_node_access(self, node, ipaddr):
+        """
+        Update the remote ip accessing the node.
+
+        @param: node: the reservation node to update
+        @type:  node: Node object
+
+        @param: ipaddr: the ipaddr used to access the node
+        @type:  ipaddr: C{string}
+
+        @return: node with updated information
+        """
+        return self._to_status(node.id, node.image, ipaddr)
+
+    def ex_extend_request_time(self, node, minutes):
+        """
+        Time in minutes to extend the requested node's reservation time
+
+        @param: node: the reservation node to update
+        @type:  node: Node object
+
+        @param: minutes: the number of mintes to update
+        @type:  minutes: C{string}
+
+        @return: true on success, throws error on failure
+        """
+        return self._vcl_request(
+            "XMLRPCextendRequest",
+            node.id,
+            minutes
+        )
+
+    def ex_get_request_end_time(self, node):
+        """
+        Get the ending time of the node reservation.
+
+        @param: node: the reservation node to update
+        @type:  node: Node object
+
+        @return: unix timestamp
+        """
+        res = self._vcl_request(
+            "XMLRPCgetRequestIds"
+        )
+        time = 0
+        for i in res['requests']:
+                if i['requestid'] == node.id:
+                        time = i['end']
+        return time