Statistics
| Branch: | Tag: | Revision:

root / kamaki / clients / cyclades.py @ 388197fe

History | View | Annotate | Download (7.1 kB)

1
# Copyright 2011 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

    
34
from .compute import ComputeClient, ClientError
35
from .utils import path4url
36
import json
37

    
38
class CycladesClient(ComputeClient):
39
    """GRNet Cyclades API client"""
40

    
41
    def networks_get(self, network_id = '', command='', **kwargs):
42
        """GET base_url/networks[/network_id][/command] request
43
        @param network_id or ''
44
        @param command can be 'detail', or ''
45
        """
46
        path=path4url('networks', network_id, command)
47
        success = kwargs.pop('success', (200, 203))
48
        return self.get(path, success=success, **kwargs)
49

    
50
    def networks_delete(self, network_id = '', command='', **kwargs):
51
        """DEL ETE base_url/networks[/network_id][/command] request
52
        @param network_id or ''
53
        @param command can be 'detail', or ''
54
        """
55
        path=path4url('networks', network_id, command)
56
        success = kwargs.pop('success', 204)
57
        return self.delete(path, success=success, **kwargs)
58

    
59
    def networks_post(self, network_id = '', command='', json_data=None, **kwargs):
60
        """POST base_url/servers[/server_id]/[command] request
61
        @param server_id or ''
62
        @param command: can be 'action' or ''
63
        @param json_data: a json valid dict that will be send as data
64
        """
65
        data= json_data
66
        if json_data is not None:
67
            data = json.dumps(json_data)
68
            self.set_header('Content-Type', 'application/json')
69
            self.set_header('Content-Length', len(data))
70

    
71
        path = path4url('networks', network_id, command)
72
        success = kwargs.pop('success', 202)
73
        return self.post(path, data=data, success=success, **kwargs)
74

    
75
    def networks_put(self, network_id = '', command='', json_data=None, **kwargs):
76
        """PUT base_url/servers[/server_id]/[command] request
77
        @param server_id or ''
78
        @param command: can be 'action' or ''
79
        @param json_data: a json valid dict that will be send as data
80
        """
81
        data= json_data
82
        if json_data is not None:
83
            data = json.dumps(json_data)
84
            self.set_header('Content-Type', 'application/json')
85
            self.set_header('Content-Length', len(data))
86

    
87
        path = path4url('networks', network_id, command)
88
        success = kwargs.pop('success', 204)
89
        return self.put(path, data=data, success=success, **kwargs)
90

    
91
    def start_server(self, server_id):
92
        """Submit a startup request for a server specified by id"""
93
        req = {'start': {}}
94
        self.servers_post(server_id, 'action', json_data=req, success=202)
95

    
96
    def shutdown_server(self, server_id):
97
        """Submit a shutdown request for a server specified by id"""
98
        req = {'shutdown': {}}
99
        self.servers_post(server_id, 'action', json_data=req, success=202)
100
    
101
    def get_server_console(self, server_id):
102
        """Get a VNC connection to the console of a server specified by id"""
103
        req = {'console': {'type': 'vnc'}}
104
        r = self.servers_post(server_id, 'action', json_data=req, success=200)
105
        return r.json['console']
106

    
107
    def get_firewall_profile(self, server_id):
108
        r = self.get_server_details(server_id)
109
        try:
110
            return r['addresses']['values'][0]['firewallProfile']
111
        except KeyError:
112
            raise ClientError('No Firewall Profile', 520,
113
                details='Server %s is missing a firewall profile'%server_id)
114

    
115
    def set_firewall_profile(self, server_id, profile):
116
        """Set the firewall profile for the public interface of a server
117
           The server is specified by id, the profile argument
118
           is one of (ENABLED, DISABLED, PROTECTED).
119
        """
120
        req = {'firewallProfile': {'profile': profile}}
121
        self.servers_post(server_id, 'action', json_data=req, success=202)
122
    
123
    def list_server_nics(self, server_id):
124
        r = self.servers_get(server_id, 'ips')
125
        return r.json['addresses']['values']
126

    
127
    def get_server_stats(self, server_id):
128
        r = self.servers_get(server_id, 'stats')
129
        return r.json['stats']
130
    
131
    def list_networks(self, detail=False):
132
        detail = 'detail' if detail else ''
133
        r = self.networks_get(command=detail)
134
        return r.json['networks']['values']
135

    
136
    def create_network(self, name, cidr=False, gateway=False, type=False, dhcp=False):
137
        """@params cidr, geteway, type and dhcp should be strings
138
        """
139
        net = dict(name=name)
140
        if cidr:
141
            net['cidr']=cidr
142
        if gateway:
143
            net['gateway']=gateway
144
        if type:
145
            net['type']=type
146
        if dhcp:
147
            net['dhcp']=dhcp
148
        req = dict(network=net)
149
        r = self.networks_post(json_data=req, success=202)
150
        return r.json['network']
151

    
152
    def get_network_details(self, network_id):
153
        r = self.networks_get(network_id=network_id)
154
        return r.json['network']
155

    
156
    def update_network_name(self, network_id, new_name):
157
        req = {'network': {'name': new_name}}
158
        self.networks_put(network_id=network_id, json_data=req)
159

    
160
    def delete_network(self, network_id):
161
        self.networks_delete(network_id)
162

    
163
    def connect_server(self, server_id, network_id):
164
        req = {'add': {'serverRef': server_id}}
165
        self.networks_post(network_id, 'action', json_data=req)
166

    
167
    def disconnect_server(self, server_id, nic_id):
168
        server_nets = self.list_server_nics(server_id)
169
        nets = [(net['id'],net['network_id'])  for net in server_nets if nic_id == net['id']]
170
        if len(nets) == 0:
171
            return
172
        for (nic_id, network_id) in nets:
173
            req={'remove':{'attachment':unicode(nic_id)}}
174
            self.networks_post(network_id, 'action', json_data=req)