summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.openstack.org>2018-11-29 20:14:31 +0000
committerGerrit Code Review <review@openstack.org>2018-11-29 20:14:31 +0000
commit5f2281a59e340b32472d78bcfaebe1886c8e479b (patch)
treef7ee618f7d36697dd64cd4863776365dfac6b124
parent40162102a757621a23fbada8c3bbf22ebf94ee67 (diff)
parent16325d5c4c5edd32a1467eaef6b3212cd51f3956 (diff)
Merge "Add arbitrary node attributes config option"
-rw-r--r--doc/source/configuration.rst9
-rw-r--r--nodepool/driver/__init__.py14
-rw-r--r--nodepool/driver/openstack/config.py2
-rw-r--r--nodepool/tests/fixtures/config_validate/good.yaml3
-rw-r--r--nodepool/tests/fixtures/node.yaml3
-rw-r--r--nodepool/tests/unit/test_launcher.py2
-rw-r--r--nodepool/tests/unit/test_zk.py4
-rwxr-xr-xnodepool/zk.py6
-rw-r--r--releasenotes/notes/node-metadata-e1e822b49464f51a.yaml7
9 files changed, 46 insertions, 4 deletions
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index aed6ae1..27abacf 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -700,6 +700,9 @@ Selecting the OpenStack driver adds the following options to the
700 - zuul-security-group 700 - zuul-security-group
701 auto-floating-ip: False 701 auto-floating-ip: False
702 host-key-checking: True 702 host-key-checking: True
703 node-attributes:
704 key1: value1
705 key2: value2
703 labels: 706 labels:
704 - name: trusty 707 - name: trusty
705 min-ram: 8192 708 min-ram: 8192
@@ -720,6 +723,12 @@ Selecting the OpenStack driver adds the following options to the
720 723
721 Pool name 724 Pool name
722 725
726 .. attr:: node-attributes
727 :type: dict
728
729 A dictionary of key-value pairs that will be stored with the node data
730 in ZooKeeper. The keys and values can be any arbitrary string.
731
723 .. attr:: max-cores 732 .. attr:: max-cores
724 :type: int 733 :type: int
725 734
diff --git a/nodepool/driver/__init__.py b/nodepool/driver/__init__.py
index 660833b..216bfe8 100644
--- a/nodepool/driver/__init__.py
+++ b/nodepool/driver/__init__.py
@@ -501,6 +501,10 @@ class NodeRequestHandler(NodeRequestHandlerNotifications,
501 node.launcher = self.launcher_id 501 node.launcher = self.launcher_id
502 node.allocated_to = self.request.id 502 node.allocated_to = self.request.id
503 503
504 # This sets static data defined in the config file in the
505 # ZooKeeper Node object.
506 node.attributes = self.pool.node_attributes
507
504 self.setNodeMetadata(node) 508 self.setNodeMetadata(node)
505 509
506 # Note: It should be safe (i.e., no race) to lock the node 510 # Note: It should be safe (i.e., no race) to lock the node
@@ -756,8 +760,10 @@ class NodeRequestHandler(NodeRequestHandlerNotifications,
756 760
757 def setNodeMetadata(self, node): 761 def setNodeMetadata(self, node):
758 ''' 762 '''
759 Handler may implement this to store metadata before building the node. 763 Handler may implement this to store driver-specific metadata in the
760 The OpenStack handler uses this to set az, cloud and region. 764 Node object before building the node. This data is normally dynamically
765 calculated during runtime. The OpenStack handler uses this to set az,
766 cloud and region.
761 ''' 767 '''
762 pass 768 pass
763 769
@@ -822,11 +828,13 @@ class ConfigPool(ConfigValue):
822 def __init__(self): 828 def __init__(self):
823 self.labels = {} 829 self.labels = {}
824 self.max_servers = math.inf 830 self.max_servers = math.inf
831 self.node_attributes = None
825 832
826 def __eq__(self, other): 833 def __eq__(self, other):
827 if isinstance(other, ConfigPool): 834 if isinstance(other, ConfigPool):
828 return (self.labels == other.labels and 835 return (self.labels == other.labels and
829 self.max_servers == other.max_servers) 836 self.max_servers == other.max_servers and
837 self.node_attributes == other.node_attributes)
830 return False 838 return False
831 839
832 840
diff --git a/nodepool/driver/openstack/config.py b/nodepool/driver/openstack/config.py
index 32c1454..ea680c1 100644
--- a/nodepool/driver/openstack/config.py
+++ b/nodepool/driver/openstack/config.py
@@ -275,6 +275,7 @@ class OpenStackProviderConfig(ProviderConfig):
275 pp.security_groups = pool.get('security-groups', []) 275 pp.security_groups = pool.get('security-groups', [])
276 pp.auto_floating_ip = bool(pool.get('auto-floating-ip', True)) 276 pp.auto_floating_ip = bool(pool.get('auto-floating-ip', True))
277 pp.host_key_checking = bool(pool.get('host-key-checking', True)) 277 pp.host_key_checking = bool(pool.get('host-key-checking', True))
278 pp.node_attributes = pool.get('node-attributes')
278 279
279 for label in pool.get('labels', []): 280 for label in pool.get('labels', []):
280 pl = ProviderLabel() 281 pl = ProviderLabel()
@@ -367,6 +368,7 @@ class OpenStackProviderConfig(ProviderConfig):
367 'max-servers': int, 368 'max-servers': int,
368 'max-ram': int, 369 'max-ram': int,
369 'labels': [pool_label], 370 'labels': [pool_label],
371 'node-attributes': dict,
370 'availability-zones': [str], 372 'availability-zones': [str],
371 'security-groups': [str] 373 'security-groups': [str]
372 } 374 }
diff --git a/nodepool/tests/fixtures/config_validate/good.yaml b/nodepool/tests/fixtures/config_validate/good.yaml
index 372641c..db7d1ec 100644
--- a/nodepool/tests/fixtures/config_validate/good.yaml
+++ b/nodepool/tests/fixtures/config_validate/good.yaml
@@ -38,6 +38,9 @@ providers:
38 max-servers: 184 38 max-servers: 184
39 auto-floating-ip: True 39 auto-floating-ip: True
40 host-key-checking: True 40 host-key-checking: True
41 node-attributes:
42 key1: value1
43 key2: value2
41 labels: 44 labels:
42 - name: trusty 45 - name: trusty
43 diskimage: trusty 46 diskimage: trusty
diff --git a/nodepool/tests/fixtures/node.yaml b/nodepool/tests/fixtures/node.yaml
index 4568267..1e65f16 100644
--- a/nodepool/tests/fixtures/node.yaml
+++ b/nodepool/tests/fixtures/node.yaml
@@ -26,6 +26,9 @@ providers:
26 pools: 26 pools:
27 - name: main 27 - name: main
28 max-servers: 96 28 max-servers: 96
29 node-attributes:
30 key1: value1
31 key2: value2
29 availability-zones: 32 availability-zones:
30 - az1 33 - az1
31 networks: 34 networks:
diff --git a/nodepool/tests/unit/test_launcher.py b/nodepool/tests/unit/test_launcher.py
index 4b12ff2..a4ca282 100644
--- a/nodepool/tests/unit/test_launcher.py
+++ b/nodepool/tests/unit/test_launcher.py
@@ -489,6 +489,8 @@ class TestLauncher(tests.DBTestCase):
489 self.assertEqual(nodes[0].type, ['fake-label']) 489 self.assertEqual(nodes[0].type, ['fake-label'])
490 self.assertEqual(nodes[0].username, 'zuul') 490 self.assertEqual(nodes[0].username, 'zuul')
491 self.assertNotEqual(nodes[0].host_keys, []) 491 self.assertNotEqual(nodes[0].host_keys, [])
492 self.assertEqual(nodes[0].attributes,
493 {'key1': 'value1', 'key2': 'value2'})
492 494
493 def test_node_host_key_checking_false(self): 495 def test_node_host_key_checking_false(self):
494 """Test that an image and node are created""" 496 """Test that an image and node are created"""
diff --git a/nodepool/tests/unit/test_zk.py b/nodepool/tests/unit/test_zk.py
index 8f1dca5..401196a 100644
--- a/nodepool/tests/unit/test_zk.py
+++ b/nodepool/tests/unit/test_zk.py
@@ -862,6 +862,7 @@ class TestZKModel(tests.BaseTestCase):
862 o.comment = 'comment' 862 o.comment = 'comment'
863 o.hold_job = 'hold job' 863 o.hold_job = 'hold job'
864 o.host_keys = ['key1', 'key2'] 864 o.host_keys = ['key1', 'key2']
865 o.attributes = {'executor-zone': 'vpn'}
865 866
866 d = o.toDict() 867 d = o.toDict()
867 self.assertNotIn('id', d) 868 self.assertNotIn('id', d)
@@ -883,6 +884,7 @@ class TestZKModel(tests.BaseTestCase):
883 self.assertEqual(d['comment'], o.comment) 884 self.assertEqual(d['comment'], o.comment)
884 self.assertEqual(d['hold_job'], o.hold_job) 885 self.assertEqual(d['hold_job'], o.hold_job)
885 self.assertEqual(d['host_keys'], o.host_keys) 886 self.assertEqual(d['host_keys'], o.host_keys)
887 self.assertEqual(d['attributes'], o.attributes)
886 888
887 def test_Node_fromDict(self): 889 def test_Node_fromDict(self):
888 now = int(time.time()) 890 now = int(time.time())
@@ -907,6 +909,7 @@ class TestZKModel(tests.BaseTestCase):
907 'hold_job': 'hold job', 909 'hold_job': 'hold job',
908 'host_keys': ['key1', 'key2'], 910 'host_keys': ['key1', 'key2'],
909 'connection_port': 22022, 911 'connection_port': 22022,
912 'attributes': {'executor-zone': 'vpn'},
910 } 913 }
911 914
912 o = zk.Node.fromDict(d, node_id) 915 o = zk.Node.fromDict(d, node_id)
@@ -930,6 +933,7 @@ class TestZKModel(tests.BaseTestCase):
930 self.assertEqual(o.hold_job, d['hold_job']) 933 self.assertEqual(o.hold_job, d['hold_job'])
931 self.assertEqual(o.host_keys, d['host_keys']) 934 self.assertEqual(o.host_keys, d['host_keys'])
932 self.assertEqual(o.connection_port, d['connection_port']) 935 self.assertEqual(o.connection_port, d['connection_port'])
936 self.assertEqual(o.attributes, d['attributes'])
933 937
934 def test_custom_connection_port(self): 938 def test_custom_connection_port(self):
935 n = zk.Node('0001') 939 n = zk.Node('0001')
diff --git a/nodepool/zk.py b/nodepool/zk.py
index 0bcd190..daaf4f6 100755
--- a/nodepool/zk.py
+++ b/nodepool/zk.py
@@ -521,6 +521,7 @@ class Node(BaseModel):
521 self.host_keys = [] 521 self.host_keys = []
522 self.hold_expiration = None 522 self.hold_expiration = None
523 self.resources = None 523 self.resources = None
524 self.attributes = None
524 525
525 def __repr__(self): 526 def __repr__(self):
526 d = self.toDict() 527 d = self.toDict()
@@ -556,7 +557,8 @@ class Node(BaseModel):
556 self.connection_port == other.connection_port and 557 self.connection_port == other.connection_port and
557 self.host_keys == other.host_keys and 558 self.host_keys == other.host_keys and
558 self.hold_expiration == other.hold_expiration and 559 self.hold_expiration == other.hold_expiration and
559 self.resources == other.resources) 560 self.resources == other.resources and
561 self.attributes == other.attributes)
560 else: 562 else:
561 return False 563 return False
562 564
@@ -603,6 +605,7 @@ class Node(BaseModel):
603 d['connection_port'] = self.connection_port 605 d['connection_port'] = self.connection_port
604 d['hold_expiration'] = self.hold_expiration 606 d['hold_expiration'] = self.hold_expiration
605 d['resources'] = self.resources 607 d['resources'] = self.resources
608 d['attributes'] = self.attributes
606 return d 609 return d
607 610
608 @staticmethod 611 @staticmethod
@@ -664,6 +667,7 @@ class Node(BaseModel):
664 else: 667 else:
665 self.hold_expiration = hold_expiration 668 self.hold_expiration = hold_expiration
666 self.resources = d.get('resources') 669 self.resources = d.get('resources')
670 self.attributes = d.get('attributes')
667 671
668 672
669class ZooKeeper(object): 673class ZooKeeper(object):
diff --git a/releasenotes/notes/node-metadata-e1e822b49464f51a.yaml b/releasenotes/notes/node-metadata-e1e822b49464f51a.yaml
new file mode 100644
index 0000000..3d467f9
--- /dev/null
+++ b/releasenotes/notes/node-metadata-e1e822b49464f51a.yaml
@@ -0,0 +1,7 @@
1---
2features:
3 - |
4 A new configuration option is available under the 'pools' attribute
5 of an OpenStack provider. This config value, 'node-attributes', can contain
6 a dictionary of arbitrary key-value pairs and will be stored with the
7 node data within ZooKeeper.