~ubuntu-branches/ubuntu/wily/heat/wily-proposed

« back to all changes in this revision

Viewing changes to heat/engine/resources/aws/ec2/network_interface.py

  • Committer: Package Import Robot
  • Author(s): James Page, Corey Bryant, James Page
  • Date: 2015-03-30 11:11:18 UTC
  • mfrom: (1.1.23)
  • Revision ID: package-import@ubuntu.com-20150330111118-2qpycylx6swu4yhj
Tags: 2015.1~b3-0ubuntu1
[ Corey Bryant ]
* New upstream milestone release for OpenStack kilo:
  - d/control: Align with upstream dependencies.
  - d/p/sudoers_patch.patch: Rebased.
  - d/p/fix-requirements.patch: Rebased.

[ James Page ]
* d/p/fixup-assert-regex.patch: Tweak test to use assertRegexpMatches.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#
 
2
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
 
3
#    not use this file except in compliance with the License. You may obtain
 
4
#    a copy of the License at
 
5
#
 
6
#         http://www.apache.org/licenses/LICENSE-2.0
 
7
#
 
8
#    Unless required by applicable law or agreed to in writing, software
 
9
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 
10
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 
11
#    License for the specific language governing permissions and limitations
 
12
#    under the License.
 
13
 
 
14
from heat.common.i18n import _
 
15
from heat.engine import attributes
 
16
from heat.engine import constraints
 
17
from heat.engine import properties
 
18
from heat.engine import resource
 
19
 
 
20
 
 
21
class NetworkInterface(resource.Resource):
 
22
 
 
23
    PROPERTIES = (
 
24
        DESCRIPTION, GROUP_SET, PRIVATE_IP_ADDRESS, SOURCE_DEST_CHECK,
 
25
        SUBNET_ID, TAGS,
 
26
    ) = (
 
27
        'Description', 'GroupSet', 'PrivateIpAddress', 'SourceDestCheck',
 
28
        'SubnetId', 'Tags',
 
29
    )
 
30
 
 
31
    _TAG_KEYS = (
 
32
        TAG_KEY, TAG_VALUE,
 
33
    ) = (
 
34
        'Key', 'Value',
 
35
    )
 
36
 
 
37
    ATTRIBUTES = (
 
38
        PRIVATE_IP_ADDRESS_ATTR,
 
39
    ) = (
 
40
        'PrivateIpAddress',
 
41
    )
 
42
 
 
43
    properties_schema = {
 
44
        DESCRIPTION: properties.Schema(
 
45
            properties.Schema.STRING,
 
46
            _('Description for this interface.')
 
47
        ),
 
48
        GROUP_SET: properties.Schema(
 
49
            properties.Schema.LIST,
 
50
            _('List of security group IDs associated with this interface.'),
 
51
            update_allowed=True
 
52
        ),
 
53
        PRIVATE_IP_ADDRESS: properties.Schema(
 
54
            properties.Schema.STRING
 
55
        ),
 
56
        SOURCE_DEST_CHECK: properties.Schema(
 
57
            properties.Schema.BOOLEAN,
 
58
            _('Flag indicating if traffic to or from instance is validated.'),
 
59
            implemented=False
 
60
        ),
 
61
        SUBNET_ID: properties.Schema(
 
62
            properties.Schema.STRING,
 
63
            _('Subnet ID to associate with this interface.'),
 
64
            required=True,
 
65
            constraints=[
 
66
                constraints.CustomConstraint('neutron.subnet')
 
67
            ]
 
68
        ),
 
69
        TAGS: properties.Schema(
 
70
            properties.Schema.LIST,
 
71
            schema=properties.Schema(
 
72
                properties.Schema.MAP,
 
73
                _('List of tags associated with this interface.'),
 
74
                schema={
 
75
                    TAG_KEY: properties.Schema(
 
76
                        properties.Schema.STRING,
 
77
                        required=True
 
78
                    ),
 
79
                    TAG_VALUE: properties.Schema(
 
80
                        properties.Schema.STRING,
 
81
                        required=True
 
82
                    ),
 
83
                },
 
84
                implemented=False,
 
85
            )
 
86
        ),
 
87
    }
 
88
 
 
89
    attributes_schema = {
 
90
        PRIVATE_IP_ADDRESS: attributes.Schema(
 
91
            _('Private IP address of the network interface.')
 
92
        ),
 
93
    }
 
94
 
 
95
    default_client_name = 'neutron'
 
96
 
 
97
    @staticmethod
 
98
    def network_id_from_subnet_id(neutronclient, subnet_id):
 
99
        subnet_info = neutronclient.show_subnet(subnet_id)
 
100
        return subnet_info['subnet']['network_id']
 
101
 
 
102
    def __init__(self, name, json_snippet, stack):
 
103
        super(NetworkInterface, self).__init__(name, json_snippet, stack)
 
104
        self.fixed_ip_address = None
 
105
 
 
106
    def handle_create(self):
 
107
        client = self.neutron()
 
108
 
 
109
        subnet_id = self.properties[self.SUBNET_ID]
 
110
        network_id = self.client_plugin().network_id_from_subnet_id(
 
111
            subnet_id)
 
112
 
 
113
        fixed_ip = {'subnet_id': subnet_id}
 
114
        if self.properties[self.PRIVATE_IP_ADDRESS]:
 
115
            fixed_ip['ip_address'] = self.properties[self.PRIVATE_IP_ADDRESS]
 
116
 
 
117
        props = {
 
118
            'name': self.physical_resource_name(),
 
119
            'admin_state_up': True,
 
120
            'network_id': network_id,
 
121
            'fixed_ips': [fixed_ip]
 
122
        }
 
123
        # if without group_set, don't set the 'security_groups' property,
 
124
        # neutron will create the port with the 'default' securityGroup,
 
125
        # if has the group_set and the value is [], which means to create the
 
126
        # port without securityGroup(same as the behavior of neutron)
 
127
        if self.properties[self.GROUP_SET] is not None:
 
128
            sgs = self.client_plugin().get_secgroup_uuids(
 
129
                self.properties.get(self.GROUP_SET))
 
130
            props['security_groups'] = sgs
 
131
        port = client.create_port({'port': props})['port']
 
132
        self.resource_id_set(port['id'])
 
133
 
 
134
    def handle_delete(self):
 
135
        if self.resource_id is None:
 
136
            return
 
137
 
 
138
        client = self.neutron()
 
139
        try:
 
140
            client.delete_port(self.resource_id)
 
141
        except Exception as ex:
 
142
            self.client_plugin().ignore_not_found(ex)
 
143
 
 
144
    def handle_update(self, json_snippet, tmpl_diff, prop_diff):
 
145
        if prop_diff:
 
146
            update_props = {}
 
147
            if self.GROUP_SET in prop_diff:
 
148
                group_set = prop_diff.get(self.GROUP_SET)
 
149
                # update should keep the same behavior as creation,
 
150
                # if without the GroupSet in update template, we should
 
151
                # update the security_groups property to referent
 
152
                # the 'default' security group
 
153
                if group_set is not None:
 
154
                    sgs = self.client_plugin().get_secgroup_uuids(group_set)
 
155
                else:
 
156
                    sgs = self.client_plugin().get_secgroup_uuids(['default'])
 
157
 
 
158
                update_props['security_groups'] = sgs
 
159
 
 
160
                self.neutron().update_port(self.resource_id,
 
161
                                           {'port': update_props})
 
162
 
 
163
    def _get_fixed_ip_address(self, ):
 
164
        if self.fixed_ip_address is None:
 
165
            client = self.neutron()
 
166
            try:
 
167
                port = client.show_port(self.resource_id)['port']
 
168
                if port['fixed_ips'] and len(port['fixed_ips']) > 0:
 
169
                    self.fixed_ip_address = port['fixed_ips'][0]['ip_address']
 
170
            except Exception as ex:
 
171
                self.client_plugin().ignore_not_found(ex)
 
172
 
 
173
        return self.fixed_ip_address
 
174
 
 
175
    def _resolve_attribute(self, name):
 
176
        if name == self.PRIVATE_IP_ADDRESS:
 
177
            return self._get_fixed_ip_address()
 
178
 
 
179
 
 
180
def resource_mapping():
 
181
    return {
 
182
        'AWS::EC2::NetworkInterface': NetworkInterface,
 
183
    }