diff --git a/confluent_server/confluent/discovery/core.py b/confluent_server/confluent/discovery/core.py index 7ca752a4..98560465 100644 --- a/confluent_server/confluent/discovery/core.py +++ b/confluent_server/confluent/discovery/core.py @@ -429,6 +429,8 @@ def handle_api_request(configmanager, inputdata, operation, pathcomponents): return (msg.KeyValueData({'rescan': 'started'}),) elif operation in ('update', 'create'): + if pathcomponents == ['discovery', 'register']: + return if 'node' not in inputdata: raise exc.InvalidArgumentException('Missing node name in input') mac = _get_mac_from_query(pathcomponents) diff --git a/confluent_server/confluent/discovery/handlers/generic.py b/confluent_server/confluent/discovery/handlers/generic.py index aca0f864..d38058c9 100644 --- a/confluent_server/confluent/discovery/handlers/generic.py +++ b/confluent_server/confluent/discovery/handlers/generic.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import confluent.util as util import errno import eventlet import socket @@ -31,6 +32,15 @@ class NodeHandler(object): self.info = info self.configmanager = configmanager targsa = [None] + self.ipaddr = None + self.relay_url = None + self.relay_server = None + # if this is a remote registered component, prefer to use the agent forwarder + if info.get('forwarder_url', False): + self.relay_url = info['forwarder_url'] + self.relay_server = info['forwarder_server'] + self.relay_token = info['forwarder_token'] + return # first let us prefer LLA if possible, since that's most stable for sa in info['addresses']: if sa[0].startswith('fe80'): @@ -103,11 +113,33 @@ class NodeHandler(object): def https_cert(self): if self._fp: return self._fp - if ':' in self.ipaddr: - ip = '[{0}]'.format(self.ipaddr) + if self.relay_url: + kv = util.TLSCertVerifier(self.configmanager, self.relay_server, + 'pubkeys.tls_hardwaremanager').verify_cert + w = webclient.SecureHTTPConnection(self.relay_server, verifycallback=kv) + relaycreds = self.configmanager.get_node_attributes(self.relay_server, 'secret.*', decrypt=True) + relaycreds = relaycreds.get(self.relay_server, {}) + relayuser = relaycreds.get('secret.hardwaremanagementuser', {}).get('value', None) + relaypass = relaycreds.get('secret.hardwaremanegementpassword', {}).get('value', None) + if not relayuser or not relaypass: + raise Exception('No credentials for {0}'.format(self.relay_server)) + w.set_basic_credentials(relayuser, relaypass) + w.connect() + w.request('GET', self.relay_url) + r = w.getresponse() + rb = r.read() + if r.code != 302: + raise Exception('Unexpected return from forwarder') + newurl = r.getheader('Location') + port = int(newurl.rsplit(':', 1)[-1][:-1]) + ip = self.relay_server else: - ip = self.ipaddr - wc = webclient.SecureHTTPConnection(ip, verifycallback=self._savecert) + port = 443 + if ':' in self.ipaddr: + ip = '[{0}]'.format(self.ipaddr) + else: + ip = self.ipaddr + wc = webclient.SecureHTTPConnection(ip, verifycallback=self._savecert, port=port) try: wc.connect() except IOError as ie: