Redact k8s connection info in node list
The node list (web and cli) displays the connection port for the node, but the k8s drivers use that to send service account credential info to zuul. To avoid exposing this to users if operators have chosen to make the nodepool-launcher webserver accessible, redact the connection port if it is not an integer. This also affects the command-line nodepool-list in the same way. Change-Id: I7a309f95417d47612e40d983b3a2ec6ee4d0183a
This commit is contained in:
parent
f39d2b955a
commit
9c496e2939
@ -142,6 +142,14 @@ def node_list(zk, node_id=None):
|
||||
else:
|
||||
if zk.getNodeLockContenders(node):
|
||||
locked = "locked"
|
||||
port = node.connection_port
|
||||
try:
|
||||
int(port)
|
||||
except (ValueError, TypeError):
|
||||
# The port field is being used to carry connection
|
||||
# information which may contain credentials (e.g., k8s
|
||||
# service account). Suppress it.
|
||||
port = "redacted"
|
||||
values = [
|
||||
node.id,
|
||||
node.provider,
|
||||
@ -157,7 +165,7 @@ def node_list(zk, node_id=None):
|
||||
node.private_ipv4,
|
||||
node.az,
|
||||
node.username,
|
||||
node.connection_port,
|
||||
port,
|
||||
node.launcher,
|
||||
node.allocated_to,
|
||||
node.hold_job,
|
||||
|
@ -15,8 +15,10 @@
|
||||
# limitations under the License.
|
||||
|
||||
import fixtures
|
||||
import json
|
||||
import logging
|
||||
import time
|
||||
from urllib import request
|
||||
|
||||
from nodepool import tests
|
||||
from nodepool.zk import zookeeper as zk
|
||||
@ -572,3 +574,40 @@ class TestDriverKubernetes(tests.DBTestCase):
|
||||
|
||||
servers = manager.listNodes()
|
||||
self.assertEqual(len(servers), 1)
|
||||
|
||||
def test_node_list_k8s_json(self):
|
||||
# TODO: generalize the k8s test infrastructure (fake client,
|
||||
# etc) and move this to test_webapp
|
||||
configfile = self.setup_config('kubernetes.yaml')
|
||||
pool = self.useNodepool(configfile, watermark_sleep=1)
|
||||
self.startPool(pool)
|
||||
webapp = self.useWebApp(pool, port=0)
|
||||
webapp.start()
|
||||
port = webapp.server.socket.getsockname()[1]
|
||||
|
||||
req = zk.NodeRequest()
|
||||
req.state = zk.REQUESTED
|
||||
req.node_types.append('kubernetes-namespace')
|
||||
self.zk.storeNodeRequest(req)
|
||||
|
||||
self.log.debug("Waiting for request %s", req.id)
|
||||
req = self.waitForNodeRequest(req)
|
||||
self.assertEqual(req.state, zk.FULFILLED)
|
||||
|
||||
req = request.Request(
|
||||
"http://localhost:%s/node-list" % port)
|
||||
req.add_header('Accept', 'application/json')
|
||||
f = request.urlopen(req)
|
||||
self.assertEqual(f.info().get('Content-Type'),
|
||||
'application/json')
|
||||
data = f.read()
|
||||
objs = json.loads(data.decode('utf8'))
|
||||
# We don't check the value of 'locked' because we may get a
|
||||
# cached value returned.
|
||||
self.assertDictContainsSubset({'id': '0000000000',
|
||||
'ipv6': None,
|
||||
'label': ['kubernetes-namespace'],
|
||||
'provider': 'kubespray',
|
||||
'public_ipv4': None,
|
||||
'connection_port': 'redacted',
|
||||
'state': 'ready'}, objs[0])
|
||||
|
@ -232,6 +232,7 @@ class TestWebApp(tests.DBTestCase):
|
||||
'label': ['fake-label'],
|
||||
'provider': 'fake-provider',
|
||||
'public_ipv4': 'fake',
|
||||
'connection_port': 22,
|
||||
'state': 'ready'}, objs[0])
|
||||
self.assertTrue('locked' in objs[0])
|
||||
# specify valid node_id
|
||||
@ -251,6 +252,7 @@ class TestWebApp(tests.DBTestCase):
|
||||
'label': ['fake-label'],
|
||||
'provider': 'fake-provider',
|
||||
'public_ipv4': 'fake',
|
||||
'connection_port': 22,
|
||||
'state': 'ready'}, objs[0])
|
||||
self.assertTrue('locked' in objs[0])
|
||||
# node_id not found
|
||||
|
Loading…
Reference in New Issue
Block a user