Skip to content

Commit

Permalink
Updated LinuxBridge plugin to be able to retrieve address informations (
Browse files Browse the repository at this point in the history
#103)

* added eval for getting ip address from network plugin, initial implementation on LXD plugin instance monitor
Signed-off-by: gabrik <gabriele.baldoni@gmail.com>
  • Loading branch information
gabrik committed Jun 14, 2019
1 parent faa34cb commit 01e0a9b
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 53 deletions.
31 changes: 27 additions & 4 deletions fos-plugins/LXD/LXD_plugin
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ class LXD(RuntimePluginFDU):
'FDU {} is not in DEFINED state'.format(instance_uuid))
else:
fdu_uuid = fdu.fdu_uuid
record = self.connector.loc.actual.get_node_fdu(self.node, self.uuid, fdu_uuid,instance_uuid )
record = self.connector.loc.actual.get_node_fdu(self.node, self.uuid, fdu_uuid,instance_uuid)

self.logger.info('configure_fdu()', '[ INFO ] LXD Plugin - Creating profile...')
try:
Expand Down Expand Up @@ -376,6 +376,7 @@ class LXD(RuntimePluginFDU):
res = self.connector.loc.actual.get_node_port(self.node, self.nm, cp_id)
cp.update({'status':'CONNECTED'})
# record.get('connection_points').append(cp_id)

dev, interfaces = self.__generate_custom_profile_devices_configuration(fdu)
record.update({'interfaces':interfaces})
self.logger.info('configure_fdu()', '[ INFO ] Profile devices {}'.format(dev))
Expand Down Expand Up @@ -826,9 +827,31 @@ class LXD(RuntimePluginFDU):
c = self.conn.containers.get(instance_name)
cs = c.state()
detailed_state = {}
c_net = cs.network
if c_net is None:
c_net = []
#c_net = cs.network

#{'network':
# {'eth0':
# {'addresses':
# [{'family': 'inet', 'address': '10.68.0.228', 'netmask': '24', 'scope': 'global'}, {'family': 'inet6', 'address': 'fe80::216:67ff:fe09:c5d0', 'netmask': '64', 'scope': 'link'}],
# 'counters': {'bytes_received': 2200, 'bytes_sent': 1793, 'packets_received': 18, 'packets_sent': 12},
# 'hwaddr': '00:16:67:09:c5:d0',
# 'host_name': '',
# 'mtu': 1500,
# 'state': 'up',
# 'type': 'broadcast'}
#
#if c_net is None:
# c_net = []
c_net = []
for i in record.get('interfaces'):
ip = self.call_nw_plugin_function('get_address', {'mac_address':i.get('mac_address','')})
c_net.append(
{'name': i['vintf_name'],
'mac_address': i.get('mac_address',''),
'address': ip}
)


detailed_state.update({'network': c_net})
detailed_state.update({'cpu': cs.cpu})
detailed_state.update({'memory': cs.memory})
Expand Down
118 changes: 71 additions & 47 deletions fos-plugins/linuxbridge/linuxbridge_plugin
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ class LinuxBridge(NetworkPlugin):
'disconnect_interface': self.disconnect_interface,
'connect_cp_to_vnetwork': self.connect_cp_to_vnetwork,
'disconnect_cp': self.disconnect_cp,
'delete_port': self.delete_port
'delete_port': self.delete_port,
'get_address': self.get_address
}

for k in d:
Expand Down Expand Up @@ -174,6 +175,27 @@ class LinuxBridge(NetworkPlugin):
self.delete_virtual_bridge(k)


def get_address(self, mac_address):

# LEASE FILE FORMAT
# 1560518377 00:16:3e:5e:a8:fa 192.168.123.13 holy-gar 01:00:16:3e:5e:a8:fa

for netid in self.networks:
net = self.networks[netid]
if net.get('ip_configuration') is not None:
n_small_id = netid.split('-')[0]
path = os.path.join(self.BASE_DIR, self.DHCP_DIR)
lease_file = os.path.join(path,'net_{}_leases'.format(n_small_id))

if self.call_os_plugin_function('read_file',{'file_path':lease_file}):
res = self.call_os_plugin_function('read_file',{'file_path':lease_file, 'root':False}).split('\n')
for l in res:
tok = l.split(' ')
if tok[1] == mac_address:
return {'result': tok[2]}
continue
return {'result': ''}


# todo: last item is empty-> delete
def get_bridge_names_from_output_string(self, output):
Expand Down Expand Up @@ -814,58 +836,16 @@ class LinuxBridge(NetworkPlugin):
pid_file = os.path.join(path,'net_{}.pid'.format(n_small_id))
conf = 'net_{}.conf'.format(n_small_id)
start_file = 'dhcp_{}.sh'.format(n_small_id)



dnsmasq_conf = Environment().from_string(template_conf)
dnsmasq_conf = dnsmasq_conf.render(dhcpinterface=dhcp_intf, lease_file=lease_file,dhcppid=pid_file)
if address_info.get('dhcp_range') is not None and address_info.get('dhcp_enable') :
dnsmasq_conf = dnsmasq_conf+'\ndhcp-range={},86400s'.format(address_info.get('dhcp_range'))
else:
dnsmasq_conf = dnsmasq_conf+'\ndhcp-range={},static,86400s'.format(address_info.get('subnet').split('/')[0])
if address_info.get('gateway') is not None:
dnsmasq_conf = dnsmasq_conf+'\ndhcp-option=3,{}'.format(address_info.get('gateway'))
if address_info.get('dns') is not None:
dnsmasq_conf = dnsmasq_conf+'\ndhcp-option=6,{}'.format(address_info.get('dns'))

dnsmasq_conf = binascii.hexlify(base64.b64encode(bytes(dnsmasq_conf,'utf-8'))).decode()
self.call_os_plugin_function('store_file',{'content':dnsmasq_conf, 'file_path':path, 'filename':conf})

template_start = self.call_os_plugin_function('read_file',{'file_path':os.path.join(self.DIR, 'templates', 'dnsmasq.sh'), 'root':False})
dnsmasq_sh = Environment().from_string(template_start)
addrs = self.__cird2block(address_info.get('subnet'))
dnsmasq_sh = dnsmasq_sh.render(netid=n_small_id, dhcp_conf_path=os.path.join(path, conf), ip=addrs[0], mask=addrs[-1])
dnsmasq_sh = binascii.hexlify(base64.b64encode(bytes(dnsmasq_sh,'utf-8'))).decode()
self.call_os_plugin_function('store_file',{'content':dnsmasq_sh, 'file_path':path, 'filename':start_file})

chmod_cmd = 'chmod +x {}'.format(os.path.join(path, start_file))
self.call_os_plugin_function('execute_command',{'command':chmod_cmd,'blocking':True, 'external':False})
return start_file

def __generate_dnsmaq_script(self, descriptor):
net_uuid = descriptor.get('uuid')
address_info = descriptor.get('ip_configuration')
n_small_id = net_uuid.split('-')[0]
vdev_name = 'br-{}'.format(n_small_id)
netns_name = 'fosns-{}'.format(n_small_id)
path = os.path.join(self.BASE_DIR, self.DHCP_DIR)

template_conf = self.call_os_plugin_function('read_file',{'file_path':os.path.join(self.DIR, 'templates', 'dnsmasq.conf'), 'root':False})

dhcp_intf = 'dhcp-{}-i'.format(n_small_id)
lease_file = os.path.join(path,'net_{}_leases'.format(n_small_id))
pid_file = os.path.join(path,'net_{}.pid'.format(n_small_id))
conf = 'net_{}.conf'.format(n_small_id)
start_file = 'dhcp_{}.sh'.format(n_small_id)



dnsmasq_conf = Environment().from_string(template_conf)
dnsmasq_conf = dnsmasq_conf.render(dhcpinterface=dhcp_intf, lease_file=lease_file,dhcppid=pid_file)
if address_info.get('dhcp_range') is not None and address_info.get('dhcp_enable') :
dnsmasq_conf = dnsmasq_conf+'\ndhcp-range={},86400s'.format(address_info.get('dhcp_range'))
else:
dnsmasq_conf = dnsmasq_conf+'\ndhcp-range={},static,86400s'.format(address_info.get('subnet').split('/')[0])
#dnsmasq_conf = dnsmasq_conf+'\ndhcp-range={},static,86400s'.format(address_info.get('subnet').split('/')[0])
dnsmasq_conf = dnsmasq_conf+'\ndhcp-range={},{},86400s'.format(addrs[1], addrs[2])
if address_info.get('gateway') is not None:
dnsmasq_conf = dnsmasq_conf+'\ndhcp-option=3,{}'.format(address_info.get('gateway'))
if address_info.get('dns') is not None:
Expand All @@ -876,15 +856,59 @@ class LinuxBridge(NetworkPlugin):

template_start = self.call_os_plugin_function('read_file',{'file_path':os.path.join(self.DIR, 'templates', 'dnsmasq.sh'), 'root':False})
dnsmasq_sh = Environment().from_string(template_start)
addrs = self.__cird2block(address_info.get('subnet'))
dnsmasq_sh = dnsmasq_sh.render(netid=n_small_id, dhcp_conf_path=os.path.join(path, conf), ip=addrs[0], mask=addrs[-1])

dns_face_ip = address_info.get('subnet').split('/')[0]
dnsmasq_sh = dnsmasq_sh.render(netid=n_small_id, dhcp_conf_path=os.path.join(path, conf), ip=dns_face_ip, mask=addrs[-1])
dnsmasq_sh = binascii.hexlify(base64.b64encode(bytes(dnsmasq_sh,'utf-8'))).decode()
self.call_os_plugin_function('store_file',{'content':dnsmasq_sh, 'file_path':path, 'filename':start_file})

chmod_cmd = 'chmod +x {}'.format(os.path.join(path, start_file))
self.call_os_plugin_function('execute_command',{'command':chmod_cmd,'blocking':True, 'external':False})
return start_file

# def __generate_dnsmaq_script(self, descriptor):
# net_uuid = descriptor.get('uuid')
# address_info = descriptor.get('ip_configuration')
# n_small_id = net_uuid.split('-')[0]
# vdev_name = 'br-{}'.format(n_small_id)
# netns_name = 'fosns-{}'.format(n_small_id)
# path = os.path.join(self.BASE_DIR, self.DHCP_DIR)

# template_conf = self.call_os_plugin_function('read_file',{'file_path':os.path.join(self.DIR, 'templates', 'dnsmasq.conf'), 'root':False})

# dhcp_intf = 'dhcp-{}-i'.format(n_small_id)
# lease_file = os.path.join(path,'net_{}_leases'.format(n_small_id))
# pid_file = os.path.join(path,'net_{}.pid'.format(n_small_id))
# conf = 'net_{}.conf'.format(n_small_id)
# start_file = 'dhcp_{}.sh'.format(n_small_id)



# dnsmasq_conf = Environment().from_string(template_conf)
# dnsmasq_conf = dnsmasq_conf.render(dhcpinterface=dhcp_intf, lease_file=lease_file,dhcppid=pid_file)
# if address_info.get('dhcp_range') is not None and address_info.get('dhcp_enable') :
# dnsmasq_conf = dnsmasq_conf+'\ndhcp-range={},86400s'.format(address_info.get('dhcp_range'))
# else:
# dnsmasq_conf = dnsmasq_conf+'\ndhcp-range={},static,86400s'.format(address_info.get('subnet').split('/')[0])
# if address_info.get('gateway') is not None:
# dnsmasq_conf = dnsmasq_conf+'\ndhcp-option=3,{}'.format(address_info.get('gateway'))
# if address_info.get('dns') is not None:
# dnsmasq_conf = dnsmasq_conf+'\ndhcp-option=6,{}'.format(address_info.get('dns'))

# dnsmasq_conf = binascii.hexlify(base64.b64encode(bytes(dnsmasq_conf,'utf-8'))).decode()
# self.call_os_plugin_function('store_file',{'content':dnsmasq_conf, 'file_path':path, 'filename':conf})

# template_start = self.call_os_plugin_function('read_file',{'file_path':os.path.join(self.DIR, 'templates', 'dnsmasq.sh'), 'root':False})
# dnsmasq_sh = Environment().from_string(template_start)
# addrs = self.__cird2block(address_info.get('subnet'))
# dnsmasq_sh = dnsmasq_sh.render(netid=n_small_id, dhcp_conf_path=os.path.join(path, conf), ip=addrs[0], mask=addrs[-1])
# dnsmasq_sh = binascii.hexlify(base64.b64encode(bytes(dnsmasq_sh,'utf-8'))).decode()
# self.call_os_plugin_function('store_file',{'content':dnsmasq_sh, 'file_path':path, 'filename':start_file})

# chmod_cmd = 'chmod +x {}'.format(os.path.join(path, start_file))
# self.call_os_plugin_function('execute_command',{'command':chmod_cmd,'blocking':True, 'external':False})
# return start_file


def __generate_vxlan_shutdown_script(self, net_uuid):
template_sh = self.call_os_plugin_function('read_file',{'file_path':os.path.join(self.DIR, 'templates', 'vxlan_destroy.sh'), 'root':False})
Expand Down
1 change: 1 addition & 0 deletions fos-plugins/linuxbridge/templates/dnsmasq.conf
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
no-hosts
no-resolv
strict-order
bind-interfaces
interface={{ dhcpinterface }}
# domain={{ netname }}
dhcp-authoritative
Expand Down
33 changes: 32 additions & 1 deletion src/agent/fos-agent/fos_agent.ml
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ let agent verbose_flag debug_flag configuration =
) fdu_d.connection_points
in
let%lwt rfaces = Lwt_list.map_p (fun (e:FDU.interface) ->
let facer = FDU.{vintf_name = e.name; status = `CREATE; if_type = e.virtual_interface.intf_type; phy_face = None; cp_id = None; veth_face_name=None; properties=None} in
let facer = FDU.{vintf_name = e.name; status = `CREATE; if_type = e.virtual_interface.intf_type; phy_face = None; cp_id = None; veth_face_name=None; properties=None; mac_address = e.mac_address} in
let facer =
match e.if_type with
| `INTERNAL -> (match e.cp_id with
Expand All @@ -414,6 +414,36 @@ let agent verbose_flag debug_flag configuration =
| (_,_) -> Lwt.return_unit)

in
(* *)
let cb_gd_net_all self (net:FTypes.virtual_network option) (is_remove:bool) (uuid:string option) =
let%lwt net_p = get_network_plugin self in
match is_remove with
| false ->
(match net with
| Some net ->
MVar.read self >>= fun self ->
let%lwt _ = Logs_lwt.debug (fun m -> m "[FOS-AGENT] - CB-GD-NET - ##############") in
let%lwt _ = Logs_lwt.debug (fun m -> m "[FOS-AGENT] - CB-GD-NET - vNET Updated! Agent will update actual store and call the right plugin!") in
let%lwt _ = Yaks_connector.Global.Actual.add_network sys_id Yaks_connector.default_tenant_id net.uuid net self.yaks in
let record = FTypesRecord.{uuid = net.uuid; status = `CREATE; properties = None; ip_configuration = net.ip_configuration; overlay = None; vni = None; mcast_addr = None; vlan_id = None; face = None} in
Yaks_connector.Local.Desired.add_node_network (Apero.Option.get self.configuration.agent.uuid) net_p net.uuid record self.yaks
>>= Lwt.return
| None -> Lwt.return_unit)
| true ->
(match uuid with
| Some netid -> MVar.read self >>= fun self ->
let%lwt _ = Logs_lwt.debug (fun m -> m "[FOS-AGENT] - CB-GD-NET - ##############") in
let%lwt _ = Logs_lwt.debug (fun m -> m "[FOS-AGENT] - CB-GD-NET - vNET Removed!") in
let%lwt net_info = Yaks_connector.Local.Actual.get_node_network (Apero.Option.get self.configuration.agent.uuid) net_p netid self.yaks >>= fun x -> Lwt.return @@ Apero.Option.get x in
let net_info = {net_info with status = `DESTROY} in
let%lwt _ = Yaks_connector.Local.Desired.add_node_network (Apero.Option.get self.configuration.agent.uuid) net_p netid net_info self.yaks in
Yaks_connector.Global.Actual.remove_network sys_id Yaks_connector.default_tenant_id netid self.yaks >>= Lwt.return
| None ->
let%lwt _ = Logs_lwt.debug (fun m -> m "[FOS-AGENT] - CB-GD-NET - vNET NO UUID!!!!") in
Lwt.return_unit)

in
(* *)
let cb_gd_net self (net:FTypesRecord.virtual_network option) (is_remove:bool) (uuid:string option) =
let%lwt net_p = get_network_plugin self in
match is_remove with
Expand Down Expand Up @@ -696,6 +726,7 @@ let agent verbose_flag debug_flag configuration =
let%lwt _ = Yaks_connector.Global.Desired.observe_node_plugins sys_id Yaks_connector.default_tenant_id uuid (cb_gd_plugin state) yaks in
let%lwt _ = Yaks_connector.Global.Desired.observe_fdu sys_id Yaks_connector.default_tenant_id (cb_gd_fdu state) yaks in
let%lwt _ = Yaks_connector.Global.Desired.observe_node_fdu sys_id Yaks_connector.default_tenant_id uuid (cb_gd_node_fdu state) yaks in
let%lwt _ = Yaks_connector.Global.Desired.observe_network sys_id Yaks_connector.default_tenant_id (cb_gd_net_all state) yaks in
let%lwt _ = Yaks_connector.Global.Desired.observe_node_network sys_id Yaks_connector.default_tenant_id uuid (cb_gd_net state) yaks in
let%lwt _ = Yaks_connector.Global.Desired.observe_ports sys_id Yaks_connector.default_tenant_id (cb_gd_cp state) yaks in
let%lwt _ = Yaks_connector.Global.Desired.observe_images sys_id Yaks_connector.default_tenant_id (cb_gd_image state) yaks in
Expand Down
2 changes: 1 addition & 1 deletion src/core/ocaml/fos-core/fos_core.ml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ let getuuid () =
let ic = Pervasives.open_in "/etc/machine-id" in
let uuid = input_line ic in
let _ = close_in ic in
uuid
String.sub uuid 0 8 ^ "-" ^ String.sub uuid 8 4 ^ "-" ^ String.sub uuid 12 4 ^ "-" ^ String.sub uuid 16 4 ^ "-" ^ String.sub uuid 20 12
| "DARWIN" ->
let ic = Unix.open_process_in "ioreg -rd1 -c IOPlatformExpertDevice | awk '/IOPlatformUUID/ { print $3; }'" in
let uuid = input_line ic in
Expand Down
1 change: 1 addition & 0 deletions src/im/ocaml/fos-im/fdu.atd
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ type interface_record = {
vintf_name : string;
status : net_state;
if_type : vintf_t;
?mac_address : string option;
?phy_face : string option;
?cp_id : string option;
?veth_face_name: string option;
Expand Down
4 changes: 4 additions & 0 deletions src/im/python/yang/fos/fdur.rec.yang
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ module fdur.rec {
type net_state;
}

leaf mac_address {
type string;
}

leaf properties {
type string;
// This should be a JSON
Expand Down

0 comments on commit 01e0a9b

Please sign in to comment.