Skip to content

Commit

Permalink
Fixes in LXD plugin, LinuxBridge plugin, APIs (#114)
Browse files Browse the repository at this point in the history
* addition in yaks connectors, both ocaml and pyhton

Signed-off-by: gabrik <gabriele.baldoni@gmail.com>

* added eval calls in agent for floating ip and port connection to network

Signed-off-by: gabrik <gabriele.baldoni@gmail.com>

* typo fix in fagent

Signed-off-by: gabrik <gabriele.baldoni@gmail.com>

* fix yaks_connector.py, was not using updated resource tree for fdu

Signed-off-by: gabrik <gabriele.baldoni@gmail.com>

* added utility function for getting ip address of a given connection point

Signed-off-by: gabrik <gabriele.baldoni@gmail.com>

* added logs in lxd_plugin when generating custom profile device configuration

Signed-off-by: gabrik <gabriele.baldoni@gmail.com>

* fix in lxd monitoring

Signed-off-by: gabrik <gabriele.baldoni@gmail.com>
  • Loading branch information
gabrik authored Jun 26, 2019
1 parent 29a6416 commit b7ab204
Show file tree
Hide file tree
Showing 8 changed files with 595 additions and 43 deletions.
12 changes: 7 additions & 5 deletions etc/systemd/stop.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#!/usr/bin/env bash

sudo systemctl stop yaks
sudo systemctl stop fos_agent
sudo systemctl stop fos_linux
sudo systemctl stop fos_lxd
sudo systemctl stop fos_linuxbridge
sudo systemctl stop fos_lxd
sudo systemctl stop fos_linux
sudo systemctl stop fos_agent
sudo systemctl stop yaks



8 changes: 8 additions & 0 deletions fos-plugins/LXD/LXD_plugin
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ class LXD(RuntimePluginFDU):
self.logger.info(
'stop_runtime()', 'LXD Plugin - Destroying {} running FDUs'.format(len(self.current_fdus)))
for k in list(self.current_fdus.keys()):
# TODO verify this
try:
fdu = self.current_fdus.get(k)
self.__force_fdu_termination(k)
Expand Down Expand Up @@ -850,6 +851,12 @@ class LXD(RuntimePluginFDU):
c_net = {}
for i in record.get('interfaces'):
ip = self.call_nw_plugin_function('get_address', {'mac_address':i.get('mac_address','')})
# Getting address from LXD if unable from network manager, eg. if connected to physical device/lxd bridge
if ip == '':
lxd_net_info_addrs = cs.network[i['vintf_name']]['addresses']
for a in lxd_net_info_addrs:
if a['family'] == 'inet':
ip = a['address']
# c_net.append(
# {'name': i['vintf_name'],
# 'mac_address': i.get('mac_address',''),
Expand Down Expand Up @@ -924,6 +931,7 @@ class LXD(RuntimePluginFDU):
interfaces = []
for intf in fdu.get_interfaces():
intf_name = intf.get('vintf_name')
self.logger.info('__generate_custom_profile_devices_configuration()','Interface Info {}'.format(intf))
mac = intf.get('mac_address', self.__generate_random_mac())
if intf.get('if_type').upper() in ['PHYSICAL','BRIDGED']:
real_intf_name = intf.get('phy_face')
Expand Down
2 changes: 1 addition & 1 deletion fos-plugins/linuxbridge/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ all:
echo "Nothing to do"

install:
sudo pip3 install jinja2
sudo pip3 install jinja2 netifaces psutil
ifeq "$(wildcard $(LB_PLUGIN_DIR))" ""
sudo cp -r ../linuxbridge /etc/fos/plugins/
else
Expand Down
105 changes: 104 additions & 1 deletion fos-plugins/linuxbridge/linuxbridge_plugin
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import base64
import binascii
import hashlib
import psutil
import netifaces
from jinja2 import Environment
from fog05.interfaces.NetworkPlugin import *
from fog05 import Yaks_Connector
Expand Down Expand Up @@ -135,7 +136,11 @@ class LinuxBridge(NetworkPlugin):
'connect_cp_to_vnetwork': self.connect_cp_to_vnetwork,
'disconnect_cp': self.disconnect_cp,
'delete_port': self.delete_port,
'get_address': self.get_address
'get_address': self.get_address,
'create_floating_ip': self.create_floating_ip,
'delete_floating_ip': self.delete_floating_ip,
'assign_floating_ip': self.assign_floating_ip,
'remove_floating_ip': self.remove_floating_ip
}

for k in d:
Expand Down Expand Up @@ -596,6 +601,104 @@ class LinuxBridge(NetworkPlugin):
return self.networks.get(network_uuid)


# FLOATING IPs #

def create_floating_ip(self):
self.logger.info('create_floating_ip()', 'Creating new floating IP')
ip_id = '{}'.format(uuid.uuid4())
ip_small_id = ip_id.split('-')[0]
vface = 'fl-{}'.format(ip_small_id)
face = self.overlay_interface
cmd = "sudo ip link add {} link {} type macvlan mode vepa"
self.call_os_plugin_function('execute_command',{'command':cmd,'blocking':True, 'external':True})
cmd = "sudo dhclient {}".format(vface)
self.call_os_plugin_function('execute_command',{'command':cmd,'blocking':True, 'external':True})
try:
addr = netifaces.ifaddresses(vface)[2][0]['addr']
except:
self.logger.error('create_floating_ip()','Unable to retrieve address for floating interface')
addr = ''
float_record = {
'uuid':ip_id,
'ip_version':'IPV4',
'address':addr,
'face':face,
'vface':vface,
'cp_id':''
}
self.logger.info('create_floating_ip()',' [ DONE ] New floating IP created {}'.format(float_record))
self.connector.loc.actual.add_node_floating_ip(self.node, self.uuid, ip_id, float_record)
return {'result':float_record}

def delete_floating_ip(self, ip_id):
self.logger.info('delete_floating_ip()', 'Deting floating IP {}'.format(ip_id))
ip_small_id = ip_id.split('-')[0]
vface = 'fl-{}'.format(ip_small_id)
cmd = 'sudo ip link del {}'.format(vface)
self.call_os_plugin_function('execute_command',{'command':cmd,'blocking':True, 'external':True})
rec = self.connector.loc.actual.get_node_floating_ip(self.node, self.uuid, ip_id)
self.connector.loc.actual.remove_node_floating_ip(self.node, self.uuid, ip_id)
self.logger.info('delete_floating_ip()', '[DONE] Deletted IP {}'.format(ip_id))
return {'result': rec}

def assign_floating_ip(self, ip_id, cp_id):
self.logger.info('assign_floating_ip()', 'Assigning floating IP {} to {}'.format(ip_id, cp_id))
rec = self.connector.loc.actual.get_node_floating_ip(self.node, self.uuid, ip_id)
if rec is None:
self.logger.error('assign_floating_ip()', 'Not found IP: {}'.format(ip_id))
return {'error': 11}




cp_ip = self.__get_cp_ip(cp_id)
if cp_ip == '':
self.logger.error('assign_floating_ip()', 'Connection point {} as not IP'.format(ip_id))
return {'error': 11}
cmd = 'sudo iptables -t nat -A PREROUTING -d {} -j DNAT --to {}'.format(rec['vface'], cp_ip)
self.call_os_plugin_function('execute_command',{'command':cmd,'blocking':True, 'external':True})
rec.update({'cp_id':cp_id})
self.connector.loc.actual.add_node_floating_ip(self.node, self.uuid, ip_id, rec)
self.logger.info('assign_floating_ip()', '[DONE] assigned floating IP {} to {}'.format(ip_id, cp_id))
return {'result': rec}



def remove_floating_ip(self, ip_id, cp_id):
self.logger.info('remove_floating_ip()', 'Removing floating IP {} from {}'.format(ip_id, cp_id))
rec = self.connector.loc.actual.get_node_floating_ip(self.node, self.uuid, ip_id)
if rec is None:
self.logger.error('remove_floating_ip()', 'Not found IP: {}'.format(ip_id))
return {'error': 11}
cp_ip = self.__get_cp_ip(cp_id)
if cp_ip == '':
self.logger.error('remove_floating_ip()', 'Connection point {} as not IP'.format(ip_id))
return {'error': 11}
cmd = 'sudo iptables -t nat -D PREROUTING -d {} -j DNAT --to {}'.format(rec['vface'], cp_ip)
self.call_os_plugin_function('execute_command',{'command':cmd,'blocking':True, 'external':True})
rec.update({'cp_id':''})
self.connector.loc.actual.add_node_floating_ip(self.node, self.uuid, ip_id, rec)
self.logger.info('remove_floating_ip()', '[DONE] removed floating IP {} from {}'.format(ip_id, cp_id))
return {'result': rec}

# ============ #


def __get_cp_ip(self, cp_id):
cp_rec = self.connector.loc.actual.get_node_port(self.node, self.uuid, cp_id)
fdus = self.connector.loc.actual.get_node_all_fdus_instances(self.node)
cp_ip = ''
for i in fdus:
intfs = i['interfaces']
for intf in intfs:
if intf.get('cp_id') is not None and intf.get('cp_id') != '':
if intf.get('cp_id') == cp_id:
i_name = intf['vintf_name']
hv_info = i['hypervisor_info']
if len(hv_info) > 0:
cp_id = hv_info['network']['i_name']['addresses'][0]['address']
return cp_ip

def __cird2block(self, cird):
'''
Convert cird subnet to first address (for router), first dhcp, last dhcp, netmask
Expand Down
144 changes: 142 additions & 2 deletions src/agent/fos-agent/fos_agent.ml
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,140 @@ let agent verbose_flag debug_flag configuration =
| _ -> let eval_res = FAgentTypes.{result = None ; error=Some 11} in
Lwt.return @@ FAgentTypes.string_of_eval_result eval_res
in
(* NM Evals *)
let eval_connect_cp_to_network self (props:Apero.properties) =
MVar.read self >>= fun state ->
let%lwt net_p = get_network_plugin self in
let cp_id = Apero.Option.get @@ Apero.Properties.get "cp_uuid" props in
let net_id = Apero.Option.get @@ Apero.Properties.get "network_uuid" props in
try%lwt
let parameters = [("cp_id",cp_id);("vnet_id", net_id)] in
let fname = "connect_cp_to_vnetwork" in
Yaks_connector.Local.Actual.exec_nm_eval (Apero.Option.get state.configuration.agent.uuid) net_p fname parameters state.yaks
>>= fun res ->
match res with
| Some r -> Lwt.return @@ FAgentTypes.string_of_eval_result r
| None -> let eval_res = FAgentTypes.{result = None ; error=Some 11} in
Lwt.return @@ FAgentTypes.string_of_eval_result eval_res
with
| _ -> let eval_res = FAgentTypes.{result = None ; error=Some 11} in
Lwt.return @@ FAgentTypes.string_of_eval_result eval_res
in
let eval_remove_cp_from_network self (props:Apero.properties) =
MVar.read self >>= fun state ->
let%lwt net_p = get_network_plugin self in
let cp_id = Apero.Option.get @@ Apero.Properties.get "cp_uuid" props in
try%lwt
let parameters = [("cp_id",cp_id)] in
let fname = "disconnect_cp" in
Yaks_connector.Local.Actual.exec_nm_eval (Apero.Option.get state.configuration.agent.uuid) net_p fname parameters state.yaks
>>= fun res ->
match res with
| Some r -> Lwt.return @@ FAgentTypes.string_of_eval_result r
| None -> let eval_res = FAgentTypes.{result = None ; error=Some 11} in
Lwt.return @@ FAgentTypes.string_of_eval_result eval_res
with
| _ -> let eval_res = FAgentTypes.{result = None ; error=Some 11} in
Lwt.return @@ FAgentTypes.string_of_eval_result eval_res
in
(* NM Floating IPs *)
let eval_create_floating_ip self (props:Apero.properties) =
ignore props;
MVar.read self >>= fun state ->
let%lwt net_p = get_network_plugin self in
try%lwt
let fname = "create_floating_ip" in
Yaks_connector.Local.Actual.exec_nm_eval (Apero.Option.get state.configuration.agent.uuid) net_p fname [] state.yaks
>>= fun res ->
match res with
| Some r ->
(* Convertion from record *)
let floating_r = FTypes.floating_ip_record_of_string @@ JSON.to_string (Apero.Option.get r.result) in
let floating = FTypes.{uuid = floating_r.uuid; ip_version = floating_r.ip_version; address = floating_r.address} in
Yaks_connector.Global.Actual.add_node_floating_ip sys_id Yaks_connector.default_tenant_id (Apero.Option.get state.configuration.agent.uuid) floating.uuid floating state.yaks
>>= fun _ ->
let eval_res = FAgentTypes.{result = Some (JSON.of_string (FTypes.string_of_floating_ip floating)) ; error=None} in
Lwt.return @@ FAgentTypes.string_of_eval_result eval_res
| None -> let eval_res = FAgentTypes.{result = None ; error=Some 11} in
Lwt.return @@ FAgentTypes.string_of_eval_result eval_res
with
| _ -> let eval_res = FAgentTypes.{result = None ; error=Some 11} in
Lwt.return @@ FAgentTypes.string_of_eval_result eval_res
in
let eval_delete_floating_ip self (props:Apero.properties) =
MVar.read self >>= fun state ->
let%lwt net_p = get_network_plugin self in
try%lwt
let ip_id = Apero.Option.get @@ Apero.Properties.get "floating_uuid" props in
let parameters = [("ip_id",ip_id)] in
let fname = "delete_floating_ip" in
Yaks_connector.Local.Actual.exec_nm_eval (Apero.Option.get state.configuration.agent.uuid) net_p fname parameters state.yaks
>>= fun res ->
match res with
| Some r ->
(* Convertion from record *)
let floating_r = FTypes.floating_ip_record_of_string @@ JSON.to_string (Apero.Option.get r.result) in
let floating = FTypes.{uuid = floating_r.uuid; ip_version = floating_r.ip_version; address = floating_r.address} in
Yaks_connector.Global.Actual.add_node_floating_ip sys_id Yaks_connector.default_tenant_id (Apero.Option.get state.configuration.agent.uuid) floating.uuid floating state.yaks
>>= fun _ ->
let eval_res = FAgentTypes.{result = Some (JSON.of_string (FTypes.string_of_floating_ip floating)) ; error=None} in
Lwt.return @@ FAgentTypes.string_of_eval_result eval_res
| None -> let eval_res = FAgentTypes.{result = None ; error=Some 11} in
Lwt.return @@ FAgentTypes.string_of_eval_result eval_res
with
| _ -> let eval_res = FAgentTypes.{result = None ; error=Some 11} in
Lwt.return @@ FAgentTypes.string_of_eval_result eval_res
in
let eval_assign_floating_ip self (props:Apero.properties) =
MVar.read self >>= fun state ->
let%lwt net_p = get_network_plugin self in
try%lwt
let ip_id = Apero.Option.get @@ Apero.Properties.get "floating_uuid" props in
let cp_id = Apero.Option.get @@ Apero.Properties.get "cp_uuid" props in
let parameters = [("ip_id",ip_id);("cp_id",cp_id)] in
let fname = "assign_floating_ip" in
Yaks_connector.Local.Actual.exec_nm_eval (Apero.Option.get state.configuration.agent.uuid) net_p fname parameters state.yaks
>>= fun res ->
match res with
| Some r ->
(* Convertion from record *)
let floating_r = FTypes.floating_ip_record_of_string @@ JSON.to_string (Apero.Option.get r.result) in
let floating = FTypes.{uuid = floating_r.uuid; ip_version = floating_r.ip_version; address = floating_r.address} in
Yaks_connector.Global.Actual.add_node_floating_ip sys_id Yaks_connector.default_tenant_id (Apero.Option.get state.configuration.agent.uuid) floating.uuid floating state.yaks
>>= fun _ ->
let eval_res = FAgentTypes.{result = Some (JSON.of_string (FTypes.string_of_floating_ip floating)) ; error=None} in
Lwt.return @@ FAgentTypes.string_of_eval_result eval_res
| None -> let eval_res = FAgentTypes.{result = None ; error=Some 11} in
Lwt.return @@ FAgentTypes.string_of_eval_result eval_res
with
| _ -> let eval_res = FAgentTypes.{result = None ; error=Some 11} in
Lwt.return @@ FAgentTypes.string_of_eval_result eval_res
in
let eval_remove_floating_ip self (props:Apero.properties) =
MVar.read self >>= fun state ->
let%lwt net_p = get_network_plugin self in
try%lwt
let ip_id = Apero.Option.get @@ Apero.Properties.get "floating_uuid" props in
let cp_id = Apero.Option.get @@ Apero.Properties.get "cp_uuid" props in
let parameters = [("ip_id",ip_id);("cp_id",cp_id)] in
let fname = "remove_floating_ip" in
Yaks_connector.Local.Actual.exec_nm_eval (Apero.Option.get state.configuration.agent.uuid) net_p fname parameters state.yaks
>>= fun res ->
match res with
| Some r ->
(* Convertion from record *)
let floating_r = FTypes.floating_ip_record_of_string @@ JSON.to_string (Apero.Option.get r.result) in
let floating = FTypes.{uuid = floating_r.uuid; ip_version = floating_r.ip_version; address = floating_r.address} in
Yaks_connector.Global.Actual.add_node_floating_ip sys_id Yaks_connector.default_tenant_id (Apero.Option.get state.configuration.agent.uuid) floating.uuid floating state.yaks
>>= fun _ ->
let eval_res = FAgentTypes.{result = Some (JSON.of_string (FTypes.string_of_floating_ip floating)) ; error=None} in
Lwt.return @@ FAgentTypes.string_of_eval_result eval_res
| None -> let eval_res = FAgentTypes.{result = None ; error=Some 11} in
Lwt.return @@ FAgentTypes.string_of_eval_result eval_res
with
| _ -> let eval_res = FAgentTypes.{result = None ; error=Some 11} in
Lwt.return @@ FAgentTypes.string_of_eval_result eval_res
in
(* Listeners *)
(* Global Desired *)
let cb_gd_plugin self (pl:FTypes.plugin option) (is_remove:bool) (uuid:string option) =
Expand Down Expand Up @@ -719,6 +853,13 @@ let agent verbose_flag debug_flag configuration =
let%lwt _ = Yaks_connector.Local.Actual.add_agent_eval uuid "get_network_info" (eval_get_network_info state) yaks in
let%lwt _ = Yaks_connector.Local.Actual.add_agent_eval uuid "get_port_info" (eval_get_port_info state) yaks in
let%lwt _ = Yaks_connector.Local.Actual.add_agent_eval uuid "get_image_info" (eval_get_image_info state) yaks in
(* Network Mgmt Evals *)
let%lwt _ = Yaks_connector.Local.Actual.add_agent_eval uuid "add_port_to_network" (eval_connect_cp_to_network state) yaks in
let%lwt _ = Yaks_connector.Local.Actual.add_agent_eval uuid "remove_port_from_network" (eval_remove_cp_from_network state) yaks in
let%lwt _ = Yaks_connector.Local.Actual.add_agent_eval uuid "create_floating_ip" (eval_create_floating_ip state) yaks in
let%lwt _ = Yaks_connector.Local.Actual.add_agent_eval uuid "delete_floating_ip" (eval_delete_floating_ip state) yaks in
let%lwt _ = Yaks_connector.Local.Actual.add_agent_eval uuid "assign_floating_ip" (eval_assign_floating_ip state) yaks in
let%lwt _ = Yaks_connector.Local.Actual.add_agent_eval uuid "remove_floating_ip" (eval_remove_floating_ip state) yaks in
(* Constraint Eval *)
let%lwt _ = Yaks_connector.LocalConstraint.Actual.add_agent_eval uuid "get_fdu_info" (eval_get_fdu_info state) yaks in
(* Registering listeners *)
Expand Down Expand Up @@ -809,5 +950,4 @@ let info =
in
Cmdliner.Term.info "agent" ~version:"%%VERSION%%" ~doc ~exits:Cmdliner.Term.default_exits ~man

let () = Cmdliner.Term.exit @@ Cmdliner.Term.eval (agent_t, info)

let () = Cmdliner.Term.exit @@ Cmdliner.Term.eval (agent_t, info)
Loading

0 comments on commit b7ab204

Please sign in to comment.