2
0
mirror of https://github.com/xcat2/confluent.git synced 2025-02-16 18:49:04 +00:00

Implement begins of self api

This paves the way to get deployment started
in earnest.
This commit is contained in:
Jarrod Johnson 2020-04-10 16:46:41 -04:00
parent c76a0cfa16
commit 58fd760698
5 changed files with 161 additions and 10 deletions

View File

@ -30,6 +30,7 @@ import confluent.log as log
import confluent.messages
import confluent.core as pluginapi
import confluent.asynchttp
import confluent.selfservice as selfservice
import confluent.shellserver as shellserver
import confluent.tlvdata
import confluent.util as util
@ -419,6 +420,10 @@ def resourcehandler_backend(env, start_response):
if 'restexplorerop' in querydict:
operation = querydict['restexplorerop']
del querydict['restexplorerop']
if env.get('PATH_INFO', '').startswith('/self/'):
for res in selfservice.handle_request(env, operation, start_response):
yield res
return
authorized = _authorize_request(env, operation)
if 'logout' in authorized:
start_response('200 Successful logout', headers)

View File

@ -85,9 +85,31 @@ def _rebuildidxmap():
ci = int(open('/sys/class/net/{0}/ifindex'.format(iname)).read())
_idxtoifnamemap[ci] = iname
def myiptonets(svrip):
fam = netifaces.AF_INET
if ':' in svrip:
fam = netifaces.AF_INET6
relevantnic = None
for iface in netifaces.interfaces():
for addr in netifaces.ifaddresses(iface).get(fam, []):
addr = addr.get('addr', '')
addr = addr.split('%')[0]
if addresses_match(addr, svrip):
relevantnic = iface
break
else:
continue
break
return inametonets(relevantnic)
def idxtonets(ifidx):
_rebuildidxmap()
iname = _idxtoifnamemap.get(ifidx, None)
return inametonets(iname)
def inametonets(iname):
addrs = netifaces.ifaddresses(iname)
try:
addrs = addrs[netifaces.AF_INET]
@ -98,7 +120,7 @@ def idxtonets(ifidx):
mask = struct.unpack('!I', socket.inet_aton(addr['netmask']))[0]
net = ip & mask
net = socket.inet_ntoa(struct.pack('!I', net))
yield (net, mask_to_cidr(addr['netmask']))
yield (net, mask_to_cidr(addr['netmask']), addr['addr'])
# TODO(jjohnson2): have a method to arbitrate setting methods, to aid
# in correct matching of net.* based on parameters, mainly for pxe
@ -109,7 +131,8 @@ def idxtonets(ifidx):
# that mac address
# the ip as reported by recvmsg to match the subnet of that net.* interface
# if switch and port available, that should match.
def get_nic_config(configmanager, node, ip=None, mac=None, ifidx=None):
def get_nic_config(configmanager, node, ip=None, mac=None, ifidx=None,
serverip=None):
"""Fetch network configuration parameters for a nic
For a given node and interface, find and retrieve the pertinent network
@ -148,13 +171,24 @@ def get_nic_config(configmanager, node, ip=None, mac=None, ifidx=None):
'ipv4_address': None,
'ipv4_method': None,
'prefix': None,
'ipv4_server': None,
}
nets = None
needsvrip = False
if ifidx is not None:
dhcprequested = False
nets = list(idxtonets(ifidx))
if serverip is not None:
needsvrip = True
dhcprequested = False
nets = list(myiptonets(serverip))
if nets is not None:
candgws = []
candsrvs = []
for net in nets:
net, prefix = net
net, prefix, svrip = net
candsrvs.append(svrip)
cfgdata['ipv4_server'] = svrip
for candidate in cfgbyname:
if cfgbyname[candidate].get('ipv4_method', None) == 'dhcp':
dhcprequested = True
@ -185,12 +219,16 @@ def get_nic_config(configmanager, node, ip=None, mac=None, ifidx=None):
except Exception:
return cfgdata
for net in nets:
net, prefix = net
net, prefix, svrip = net
if ip_on_same_subnet(net, ipbynodename, prefix):
cfgdata['ipv4_address'] = ipbynodename
cfgdata['ipv4_method'] = 'static'
cfgdata['prefix'] = prefix
break
for svr in candsrvs:
if ip_on_same_subnet(svr, ipbynodename, prefix):
cfgdata['ipv4_server'] = svr
break
for gw in candgws:
if ip_on_same_subnet(gw, ipbynodename, prefix):
cfgdata['ipv4_gateway'] = gw

View File

@ -0,0 +1,63 @@
import confluent.config.configmanager as configmanager
import confluent.netutil as netutil
import crypt
import json
import yaml
def yamldump(input):
return yaml.dump(input, default_flow_style=False)
def handle_request(env, operation, start_response):
nodename = env.get('HTTP_CONFLUENT_NODENAME', None)
apikey = env.get('HTTP_CONFLUENT_APIKEY', None)
if not (nodename and apikey):
start_response('401 Unauthorized', [])
yield 'Unauthorized'
return
cfg = configmanager.ConfigManager(None)
eak = cfg.get_node_attributes(nodename, 'api.key').get(
nodename, {}).get('api.key', {}).get('value', None)
if not eak:
start_response('401 Unauthorized', [])
yield 'Unauthorized'
return
salt = '$'.join(eak.split('$', 3)[:-1]) + '$'
if crypt.crypt(apikey, salt) != eak:
start_response('401 Unauthorized', [])
yield 'Unauthorized'
return
retype = env.get('HTTP_ACCEPT', 'application/yaml')
if retype == '*/*':
retype = 'application/yaml'
if retype == 'application/yaml':
dumper = yamldump
elif retype == 'application/json':
dumper = json.dumps
else:
start_response('406 Not supported', [])
yield 'Unsupported content type in ACCEPT: ' + retype
return
if env['PATH_INFO'] == '/self/deploycfg':
myip = env.get('HTTP_X_FORWARDED_HOST', None)
myip = myip.replace('[', '').replace(']', '')
ncfg = netutil.get_nic_config(cfg, nodename, serverip=myip)
if ncfg['prefix']:
ncfg['ipv4_netmask'] = netutil.cidr_to_mask(ncfg['prefix'])
deployinfo = cfg.get_node_attributes(nodename, 'deployment.*')
deployinfo = deployinfo.get(nodename, {})
profile = deployinfo.get(
'deployment.pendingprofile', {}).get('value', '')
ncfg['profile'] = profile
protocol = deployinfo.get('deployment.useinsecureprotocols', {}).get(
'value', 'never')
if protocol == 'always':
ncfg['protocol'] = 'http'
else:
ncfg['protocol'] = 'https'
start_response('200 OK', (('Content-Type', retype),))
yield dumper(ncfg)
else:
start_response('404 Not Found', ())
yield 'Not found'

View File

@ -5,15 +5,60 @@ for currif in *; do
done
cd -
while ! grep MANAGER /tmp/confluent.info >& /dev/null; do
/opt/confluent/bin/copernicus > /tmp/confluent.out
/opt/confluent/bin/copernicus -t > /tmp/confluent.info
done
read ifidx <<EOF
$(grep MANAGER confluent.info|grep fe80|sed -e s/.*%//)
$(grep ^MANAGER /tmp/confluent.info|grep fe80|sed -e s/.*%//)
EOF
read mgr << EOF
$(grep ^MANAGER /tmp/confluent.info|grep fe80|awk '{print $2}')
EOF
mgridx=${mgr#*%}
mgr="[$mgr]"
ifname=$(ip link |grep ^$ifidx:|awk '{print $2}')
ifname=${ifname%:}
echo $ifname > /tmp/net.ifaces
# Need to construct the following:
# echo ip=172.30.203.31::172.30.0.254:255.255.0.0:r4u31:enp65s0f0:none >> /etc/cmdline.d/01-confluent.conf
# echo inst.repo=http://172.30.0.254/confluent-public/os/centos-8.1-x86_64-compute/distribution >> /etc/cmdline.d/01-confluent.conf
nodename=$grep ^NODENAME /tmp/confluent.info|awk '{print $2}')
#TODO: blkid --label <whatever> to find mounted api
if [ -z "$apikey" ]; then
apikey=$(/opt/confluent/bin/clortho $nodename $mgr)
fi
curl -f -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $apikey" https://$mgr/confluent-api/self/deploycfg > /tmp/confluent.deploycfg
ipv4_address: 172.30.203.31
ipv4_gateway: null
ipv4_method: static
ipv4_netmask: 255.255.0.0
ipv4_server: 172.30.254.2
prefix: 16
profile: centos-8.1-x86_64-compute
mgr=$(grep ^ipv4_server: /tmp/confluent.deploycfg)
mgr=${mgr#ipv4_server: }
profilename=$(grep ^profile: /tmp/confluent.deploycfg)
profilename=${profilename#profile: }
proto=$(grep ^protocol: /tmp/confluent.deploycfg)
proto=${proto#protocol: }
echo inst.repo=$proto://$mgr/confluent-public/os/$profilename/distribution >> /etc/cmdline.d/01-confluent.conf
echo inst.ks=$proto://$mgr/confluent-public/os/$profilename/kickstart >> /etc/cmdline.d/01-confluent.conf
autoconfigmethod=$(grep ipv4_method /tmp/confluent.deploycfg)
autoconfigmethod=${autoconfigmethod#ipv4_method}
if [ "$autoconfigmethod" = "dhcp" ]; then
echo ip=$ifname:dhcp
else
v4addr=$(grep ^ipv4_address: /tmp/confluent.deploycfg)
v4addr=${v4addr#ipv4_address: }
v4gw=$(grep ^ipv4_gateway: /tmp/confluent.deploycfg)
v4gw=${v4gw#ipv4_gateway: }
if [ "$v4gw" = "null" ]; then
v4gw=""
fi
v4nm=$(grep ipv4_netmask: /tmp/confluent.deploycfg)
v4nm=${v4nm#ipv4_netmask: }
echo ip=$v4addr::$vpgw:$v4nm:$nodename:$ifname:none >> /etc/cmdline.d/01-confluent.conf
fi

View File

@ -1,2 +1,2 @@
#!/bin/bash
cp /etc/pki/tls/certs/ca-bundle.crt /sysroot/etc/pki/tls/certs/
cat /etc/pki/tls/certs/ca-bundle.crt > /sysroot/etc/pki/tls/certs/