~ubuntu-branches/ubuntu/trusty/python-softlayer/trusty

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
"""
    SoftLayer.metadata
    ~~~~~~~~~~~~~~~~~~
    Metadata Manager/helpers

    :copyright: (c) 2013, SoftLayer Technologies, Inc. All rights reserved.
    :license: MIT, see LICENSE for more details.
"""
from SoftLayer.transports import make_rest_api_call
from SoftLayer.consts import API_PRIVATE_ENDPOINT_REST, USER_AGENT
from SoftLayer.exceptions import SoftLayerAPIError, SoftLayerError


METADATA_MAPPING = {
    'backend_mac': {'call': 'BackendMacAddresses'},
    'datacenter': {'call': 'Datacenter'},
    'datacenter_id': {'call': 'DatacenterId'},
    'domain': {'call': 'Domain'},
    'frontend_mac': {'call': 'FrontendMacAddresses'},
    'fqdn': {'call': 'FullyQualifiedDomainName'},
    'hostname': {'call': 'Hostname'},
    'id': {'call': 'Id'},
    'primary_backend_ip': {'call': 'PrimaryBackendIpAddress'},
    'primary_ip': {'call': 'PrimaryIpAddress'},
    'primary_frontend_ip': {'call': 'PrimaryIpAddress'},
    'provision_state': {'call': 'ProvisionState'},
    'router': {'call': 'Router', 'param_req': True},
    'tags': {'call': 'Tags'},
    'user_data': {'call': 'UserMetadata'},
    'user_metadata': {'call': 'UserMetadata'},
    'vlan_ids': {'call': 'VlanIds', 'param_req': True},
    'vlans': {'call': 'Vlans', 'param_req': True},
}
METADATA_ATTRIBUTES = METADATA_MAPPING.keys()


class MetadataManager(object):
    """ Provides an interface for the metadata service. This provides metadata
        about the resourse it is called from. See `METADATA_ATTRIBUTES` for
        full list of attributes.

        Usage:

            >>> import SoftLayer
            >>> client = SoftLayer.Client()
            >>> from SoftLayer.metadata import MetadataManager
            >>> meta = MetadataManager(client)
            >>> meta.get('datacenter')
            'dal05'
            >>> meta.get('fqdn')
            'test.example.com'

    """

    attribs = METADATA_MAPPING

    def __init__(self, client=None, timeout=5):
        self.url = API_PRIVATE_ENDPOINT_REST.rstrip('/')
        self.timeout = timeout

    def make_request(self, path):
        url = '/'.join([self.url, 'SoftLayer_Resource_Metadata', path])
        try:
            return make_rest_api_call('GET', url,
                                      http_headers={'User-Agent': USER_AGENT},
                                      timeout=self.timeout)
        except SoftLayerAPIError as e:
            if e.faultCode == 404:
                return None
            raise e

    def get(self, name, param=None):
        """ Retreive a metadata attribute

        :param name: name of the attribute to retrieve. See `attribs`
        :param param: Required parameter for some attributes

        """
        if name not in self.attribs:
            raise SoftLayerError('Unknown metadata attribute.')

        call_details = self.attribs[name]
        extension = '.json'
        if self.attribs[name]['call'] == 'UserMetadata':
            extension = '.txt'

        if call_details.get('param_req'):
            if not param:
                raise SoftLayerError(
                    'Parameter required to get this attribute.')
            path = "%s/%s%s" % (self.attribs[name]['call'], param, extension)
        else:
            path = "%s%s" % (self.attribs[name]['call'], extension)

        return self.make_request(path)

    def _get_network(self, kind, router=True, vlans=True, vlan_ids=True):
        network = {}
        macs = self.get('%s_mac' % kind)
        network['mac_addresses'] = macs

        if len(macs) == 0:
            return network

        if router:
            network['router'] = self.get('router', macs[0])

        if vlans:
            network['vlans'] = self.get('vlans', macs[0])

        if vlan_ids:
            network['vlan_ids'] = self.get('vlan_ids', macs[0])

        return network

    def public_network(self, **kwargs):
        """ Returns details about the public network

        :param boolean router: True to return router details
        :param boolean vlans: True to return vlan details
        :param boolean vlan_ids: True to return vlan_ids

        """
        return self._get_network('frontend', **kwargs)

    def private_network(self, **kwargs):
        """ Returns details about the private network

        :param boolean router: True to return router details
        :param boolean vlans: True to return vlan details
        :param boolean vlan_ids: True to return vlan_ids

        """
        return self._get_network('backend', **kwargs)