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:
parent
c76a0cfa16
commit
58fd760698
@ -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)
|
||||
|
@ -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
|
||||
|
63
confluent_server/confluent/selfservice.py
Normal file
63
confluent_server/confluent/selfservice.py
Normal 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'
|
@ -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
|
||||
|
||||
|
||||
|
@ -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/
|
||||
|
Loading…
x
Reference in New Issue
Block a user