Skip to content

Commit

Permalink
Merge pull request #9129 from bloomberg/workload_endpoint_network_name
Browse files Browse the repository at this point in the history
Add network name to labels for workload endpoints
  • Loading branch information
marvin-tigera authored Oct 4, 2024
2 parents 78183c5 + ade5c19 commit 2f02c0d
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@
PROJECT_NAME_LABEL_NAME = 'projectcalico.org/openstack-project-name'
PROJECT_NAME_MAX_LENGTH = datamodel_v3.SANITIZE_LABEL_MAX_LENGTH
PROJECT_PARENT_ID_LABEL_NAME = 'projectcalico.org/openstack-project-parent-id'
NETWORK_NAME_LABEL_NAME = 'projectcalico.org/openstack-network-name'
NETWORK_NAME_MAX_LENGTH = datamodel_v3.SANITIZE_LABEL_MAX_LENGTH

# Note: Calico requires a label value to be an empty string, or to consist of
# alphanumeric characters, '-', '_' or '.', starting and ending with an
Expand Down Expand Up @@ -221,6 +223,23 @@ def get_floating_ips_for_port(self, context, port):
)
]

def get_network_name_for_port(self, context, port):
network = context.session.query(
models_v2.Network
).filter_by(
id=port['network_id']
).first()

try:
network_name = datamodel_v3.sanitize_label_name_value(
network['name'],
NETWORK_NAME_MAX_LENGTH,
)
return network_name
except Exception:
LOG.warning(f"Failed to find network name for port {port['id']}")
return None

def add_extra_port_information(self, context, port):
"""add_extra_port_information
Expand All @@ -236,6 +255,10 @@ def add_extra_port_information(self, context, port):
port['security_groups'] = self.get_security_groups_for_port(
context, port
)
port['network_name'] = self.get_network_name_for_port(
context, port
)

self.add_port_gateways(port, context)
self.add_port_interface_name(port)
self.add_port_project_data(port, context)
Expand Down Expand Up @@ -357,6 +380,9 @@ def endpoint_labels(port, namespace):
labels[PROJECT_NAME_LABEL_NAME] = name
labels[PROJECT_PARENT_ID_LABEL_NAME] = parent_id

network_name = port.get('network_name')
if network_name is not None:
labels[NETWORK_NAME_LABEL_NAME] = network_name
return labels


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,22 @@
'fixed_ip_address': '10.65.0.2',
'floating_ip_address': '192.168.0.1'}]

network1 = {'id': 'calico-network-id',
'name': 'calico-network-name',
'status': 'ACTIVE',
'admin_state_up': True,
'shared': True,
'mtu': 9000,
'project_id': 'jane3'}

network2 = {'id': 'calico-other-network-id',
'name': 'my-first-network',
'status': 'ACTIVE',
'admin_state_up': True,
'shared': True,
'mtu': 9000,
'project_id': 'jane3'}


class EtcdKeyNotFound(Exception):
pass
Expand Down Expand Up @@ -211,6 +227,9 @@ class Lib(object):
# Subnets that the OpenStack database knows about.
osdb_subnets = []

# Networks that the OpenStack database knows about.
osdb_networks = []

def setUp(self):
# Announce the current test case.
_log.info("TEST CASE: %s", self.id())
Expand All @@ -237,7 +256,7 @@ def setUp(self):
self.db_context = mech_calico.ctx.get_admin_context()
self.db_context.to_dict.return_value = {}
self.db_context.session.query.return_value.filter_by.side_effect = (
self.port_query
self.db_query
)

# Arrange what the DB's get_ports will return.
Expand All @@ -248,6 +267,10 @@ def setUp(self):
self.db.get_subnet.side_effect = self.get_subnet
self.db.get_subnets.side_effect = self.get_subnets

# Arrange DB's get_network and get_networks calls
self.db.get_network.side_effect = self.get_network
self.db.get_networks.side_effect = self.get_networks

# Arrange what the DB's get_security_groups query will return (the
# default SG).
self.db.get_security_groups.return_value = [
Expand Down Expand Up @@ -543,6 +566,18 @@ def get_subnets(self, context, filters=None):
matches = [s for s in self.osdb_subnets]
return matches

def get_network(self, context, id):
return self.get_networks(context, filters={'id': [id]})[0]

def get_networks(self, context, filters=None):
if filters is None:
return self.osdb_networks

assert list(filters.keys()) == ['id']
allowed_ids = set(filters['id'])

return [p for p in self.osdb_networks if p['id'] in allowed_ids]

def notify_security_group_update(self, id, rules, port, type):
"""Notify a new or changed security group definition."""
# Prep appropriate responses for next get_security_group and
Expand Down Expand Up @@ -575,19 +610,28 @@ def get_port_security_group_bindings(self, context, filters):
return [b for b in self.port_security_group_bindings
if b['port_id'] in allowed_ids]

def port_query(self, **kw):
def db_query(self, **kw):
# 'port_id' query key for IPAllocations
if kw.get('port_id', None):
for port in self.osdb_ports:
if port['id'] == kw['port_id']:
return port['fixed_ips']
# 'fixed_port_id query key for FloatingIPs
elif kw.get('fixed_port_id', None):
fips = []
for fip in floating_ports:
if fip['fixed_port_id'] == kw['fixed_port_id']:
fips.append(fip)
return fips
# 'id' query key for Networks
elif kw.get('id', None):
for network in self.osdb_networks:
if network['id'] == kw['id']:
network_mock = mock.MagicMock()
network_mock.first.return_value = network
return network_mock
else:
raise Exception("port_query doesn't know how to handle kw=%r" % kw)
raise Exception("db_query doesn't know how to handle kw=%r" % kw)

return None

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,15 @@ def etcd3gw_client_put(self, key, value, **kwargs):
self.recent_writes[key] = value

if 'metadata' in self.recent_writes[key]:
# If this is an update, check that the metadata other than labels
# is unchanged.
# If this is an update, check that the metadata, other than labels
# and annotations, is unchanged.
if existing_v3_metadata:
if 'labels' in self.recent_writes[key]['metadata']:
existing_v3_metadata['labels'] = \
self.recent_writes[key]['metadata']['labels']
if 'annotations' in self.recent_writes[key]['metadata']:
existing_v3_metadata['annotations'] = \
self.recent_writes[key]['metadata']['annotations']
self.assertEqual(existing_v3_metadata,
self.recent_writes[key]['metadata'])
# Now delete not-easily-predictable metadata fields from the data
Expand Down Expand Up @@ -414,6 +417,7 @@ def make_context(self):
def test_start_two_ports(self):
"""Startup with two existing ports but no existing etcd data."""
# Provide two Neutron ports.
self.osdb_networks = [lib.network1, lib.network2]
self.osdb_ports = [lib.port1, lib.port2]

# Allow the etcd transport's resync thread to run.
Expand Down Expand Up @@ -449,7 +453,9 @@ def test_start_two_ports(self):
'projectcalico.org/openstack-project-id': 'jane3',
'projectcalico.org/openstack-project-name': 'pname_jane3',
'projectcalico.org/openstack-project-parent-id': 'gibson',
'projectcalico.org/orchestrator': 'openstack'
'projectcalico.org/orchestrator': 'openstack',
'projectcalico.org/openstack-network-name':
'calico-network-name'
}
},
'spec': {'endpoint': 'DEADBEEF-1234-5678',
Expand Down Expand Up @@ -484,7 +490,9 @@ def test_start_two_ports(self):
'projectcalico.org/openstack-project-id': 'jane3',
'projectcalico.org/openstack-project-name': 'pname_jane3',
'projectcalico.org/openstack-project-parent-id': 'gibson',
'projectcalico.org/orchestrator': 'openstack'
'projectcalico.org/orchestrator': 'openstack',
'projectcalico.org/openstack-network-name':
'calico-network-name'
}
},
'spec': {'endpoint': 'FACEBEEF-1234-5678',
Expand Down Expand Up @@ -518,7 +526,7 @@ def test_start_two_ports(self):
context = self.make_context()
context._port = lib.port1
context._plugin_context.session.query.return_value.filter_by.\
side_effect = self.port_query
side_effect = self.db_query
self.driver.delete_port_postcommit(context)
self.assertEtcdWrites({})
self.assertEtcdDeletes(set([ep_deadbeef_key_v3]))
Expand Down Expand Up @@ -619,7 +627,9 @@ def test_start_two_ports(self):
'projectcalico.org/openstack-project-id': 'jane3',
'projectcalico.org/openstack-project-name': 'pname_jane3',
'projectcalico.org/openstack-project-parent-id': 'gibson',
'projectcalico.org/orchestrator': 'openstack'
'projectcalico.org/orchestrator': 'openstack',
'projectcalico.org/openstack-network-name':
'calico-network-name'
}
},
'spec': {'endpoint': 'HELLO-1234-5678',
Expand Down Expand Up @@ -892,6 +902,25 @@ def test_start_two_ports(self):
self.assertEtcdWrites(expected_writes)
self.assertEtcdDeletes(set())

# Change network used
_log.info("Change network used by endpoint HELLO")
context._port['network_id'] = 'calico-other-network-id'
self.osdb_ports[0]['network_id'] = 'calico-other-network-id'
self.driver.update_port_postcommit(context)

# Expected changes
ep_hello_value_v3['metadata']['labels'][
'projectcalico.org/openstack-network-name'] = 'my-first-network'
ep_hello_value_v3['metadata']['annotations'][
'openstack.projectcalico.org/network-id'] = \
'calico-other-network-id'
expected_writes = {
ep_hello_key_v3: ep_hello_value_v3,
sg_1_key_v3: sg_1_value_v3,
}
self.assertEtcdWrites(expected_writes)
self.assertEtcdDeletes(set())

# Reset the state for safety.
self.osdb_ports[0]['fixed_ips'] = old_ips

Expand Down

0 comments on commit 2f02c0d

Please sign in to comment.