2
0
mirror of https://github.com/xcat2/confluent.git synced 2025-08-24 20:20:36 +00:00

Create mechanism to create node identity images

These images are used in the flow of routed deployment.
This commit is contained in:
Jarrod Johnson
2022-03-16 15:41:07 -04:00
parent 40a187d2aa
commit 94ab644f5c
4 changed files with 102 additions and 0 deletions

View File

@@ -382,6 +382,11 @@ def _init_core():
'pluginattrs': ['hardwaremanagement.method'],
'default': 'ipmi',
}),
'deployment': {
'ident_img': PluginRoute({
'handler': 'identimage'
})
},
'events': {
'hardware': {
'log': PluginRoute({

View File

@@ -526,6 +526,8 @@ def get_input_message(path, operation, inputdata, nodes=None, multinode=False,
elif '/'.join(path).startswith(
'configuration/management_controller/licenses') and inputdata:
return InputLicense(path, nodes, inputdata, configmanager)
elif path == ['deployment', 'ident_image']:
return InputIdentImage(path, nodes, inputdata)
elif inputdata:
raise exc.InvalidArgumentException(
'No known input handler for request')
@@ -887,6 +889,12 @@ class ConfluentInputMessage(ConfluentMessage):
def is_valid_key(self, key):
return key in self.valid_values
class InputIdentImage(ConfluentInputMessage):
keyname = 'ident_image'
valid_values = ['create']
class InputIdentifyMessage(ConfluentInputMessage):
valid_values = set([
'on',

View File

@@ -274,6 +274,19 @@ class NetManager(object):
myattribs['current_nic'] = False
def get_flat_net_config(configmanager, node):
fnc = get_full_net_config(configmanager, node)
dft = fnc.get('default', {})
if dft:
ret = [dft]
else:
ret = []
for nc in fnc.get('extranets', {}):
nc = fnc['extranets'][nc]
if nc:
ret.append(nc)
return ret
def get_full_net_config(configmanager, node, serverip=None):
cfd = configmanager.get_node_attributes(node, ['net.*'])
cfd = cfd.get(node, {})

View File

@@ -0,0 +1,76 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2022 Lenovo
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# This plugin provides an ssh implementation comforming to the 'console'
# specification. consoleserver or shellserver would be equally likely
# to use this.
import confluent.messages as msg
import confluent.netutil as netutil
import eventlet.green.subprocess as subprocess
import os
import shutil
import tempfile
import socket
import yaml
import json
def mkdirp(path):
try:
os.makedirs(path)
except OSError as e:
if e.errno != 17:
raise
def create_apikey():
alpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./'
newpass = ''.join([alpha[x >> 2] for x in bytearray(os.urandom(32))])
return newpass
def create_ident_image(node, configmanager):
tmpd = tempfile.mkdtemp()
ident = { 'nodename': node }
apikey = create_apikey()
configmanager.set_node_attributes({node: {'secret.selfapiarmtoken': apikey}})
ident['apitoken'] = apikey
# This particular mechanism does not (yet) do anything smart with collective
# It would be a reasonable enhancement to list all collective server addresses
# restricted by 'managercandidates'
ident['deploy_servers'] = []
for myaddr in netutil.get_my_addresses():
myaddr = socket.inet_ntop(myaddr[0], myaddr[1])
ident['deploy_servers'].append(myaddr)
ident['net_cfgs'] = netutil.get_flat_net_config(configmanager, node)
with open(os.path.join(tmpd, 'cnflnt.yml'), 'w') as yamlout:
yaml.safe_dump(ident, yamlout, default_flow_style=False)
with open(os.path.join(tmpd, 'cnflnt.jsn'), 'w') as jsonout:
json.dump(ident, jsonout)
mkdirp('/var/lib/confluent/private/identity_images/')
imgname = '/var/lib/confluent/private/identity_images/{0}.img'.format(node)
if os.path.exists(imgname):
os.remove(imgname)
subprocess.check_call(['/opt/confluent/bin/dir2img', tmpd, imgname, 'cnflnt_idnt'])
shutil.rmtree(tmpd)
def update(nodes, element, configmanager, inputdata):
for node in nodes:
create_ident_image(node, configmanager)
yield msg.CreatedResource(
'nodes/{0}/deployment/ident_image'.format(node))