File: interface.py

package info (click to toggle)
python-softlayer 6.2.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 7,508 kB
  • sloc: python: 57,195; makefile: 133; xml: 97; sh: 59
file content (162 lines) | stat: -rw-r--r-- 5,649 bytes parent folder | download | duplicates (2)
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
"""Security group interface operations."""
# :license: MIT, see LICENSE for more details.

import click

import SoftLayer
from SoftLayer.CLI import environment
from SoftLayer.CLI import exceptions
from SoftLayer.CLI import formatting

COLUMNS = ['networkComponentId',
           'virtualServerId',
           'hostname',
           'interface',
           'ipAddress', ]

REQUEST_COLUMNS = ['requestId']


@click.command(cls=SoftLayer.CLI.command.SLCommand, )
@click.argument('securitygroup_id')
@click.option('--sortby',
              help='Column to sort by',
              type=click.Choice(COLUMNS))
@environment.pass_env
def interface_list(env, securitygroup_id, sortby):
    """List interfaces associated with security groups."""
    mgr = SoftLayer.NetworkManager(env.client)

    table = formatting.Table(COLUMNS)
    table.sortby = sortby

    mask = (
        '''networkComponentBindings[
            networkComponentId,
            networkComponent[
                id,
                port,
                guest[
                    id,
                    hostname,
                    primaryBackendIpAddress,
                    primaryIpAddress
                ]
            ]
        ]'''
    )

    secgroup = mgr.get_securitygroup(securitygroup_id, mask=mask)
    for binding in secgroup.get('networkComponentBindings', []):
        interface_id = binding['networkComponentId']
        try:
            interface = binding['networkComponent']
            vsi = interface['guest']
            vsi_id = vsi['id']
            hostname = vsi['hostname']
            priv_pub = 'PRIVATE' if interface['port'] == 0 else 'PUBLIC'
            ip_address = (vsi['primaryBackendIpAddress']
                          if interface['port'] == 0
                          else vsi['primaryIpAddress'])
        except KeyError:
            vsi_id = "N/A"
            hostname = "Not enough permission to view"
            priv_pub = "N/A"
            ip_address = "N/A"

        table.add_row([
            interface_id,
            vsi_id,
            hostname,
            priv_pub,
            ip_address
        ])

    env.fout(table)


@click.command(cls=SoftLayer.CLI.command.SLCommand, )
@click.argument('securitygroup_id')
@click.option('--network-component', '-n',
              help=('The network component to associate '
                    'with the security group'))
@click.option('--server', '-s',
              help='The server ID to associate with the security group')
@click.option('--interface', '-i',
              help='The interface of the server to associate (public/private)')
@environment.pass_env
def add(env, securitygroup_id, network_component, server, interface):
    """Attach an interface to a security group."""
    _validate_args(network_component, server, interface)

    mgr = SoftLayer.NetworkManager(env.client)
    component_id = _get_component_id(env, network_component, server, interface)

    ret = mgr.attach_securitygroup_component(securitygroup_id,
                                             component_id)
    if not ret:
        raise exceptions.CLIAbort("Could not attach network component")

    table = formatting.Table(REQUEST_COLUMNS)
    table.add_row([ret['requestId']])

    env.fout(table)


@click.command(cls=SoftLayer.CLI.command.SLCommand, )
@click.argument('securitygroup_id')
@click.option('--network-component', '-n',
              help=('The network component to remove from '
                    'with the security group'))
@click.option('--server', '-s',
              help='The server ID to remove from the security group')
@click.option('--interface', '-i',
              help='The interface of the server to remove (public/private)')
@environment.pass_env
def remove(env, securitygroup_id, network_component, server, interface):
    """Detach an interface from a security group."""
    _validate_args(network_component, server, interface)

    mgr = SoftLayer.NetworkManager(env.client)
    component_id = _get_component_id(env, network_component, server, interface)

    ret = mgr.detach_securitygroup_component(securitygroup_id,
                                             component_id)
    if not ret:
        raise exceptions.CLIAbort("Could not detach network component")

    table = formatting.Table(REQUEST_COLUMNS)
    table.add_row([ret['requestId']])

    env.fout(table)


def _validate_args(network_component, server, interface):
    use_server = bool(server and interface and not network_component)
    use_component = bool(network_component and not bool(server or interface))

    if not use_server and not use_component:
        raise exceptions.CLIAbort("Must set either --network-component "
                                  "or both --server and --interface")
    if use_server and interface.lower() not in ['public', 'private']:
        raise exceptions.CLIAbort(
            "Interface must be either 'public' or 'private'")


def _get_component_id(env, network_component, server, interface):
    use_server = bool(server and interface and not network_component)
    vs_mgr = SoftLayer.VSManager(env.client)

    if use_server:
        vs_mask = 'networkComponents[id, port]'
        vsi = vs_mgr.get_instance(server, mask=vs_mask)
        port = 0 if interface.lower() == 'private' else 1
        component = [c for c in vsi['networkComponents'] if c['port'] == port]
        if len(component) != 1:
            raise exceptions.CLIAbort("Instance %s has no %s interface"
                                      % (server, interface))
        component_id = component[0]['id']
    else:
        component_id = network_component

    return component_id