Skip to content

Commit

Permalink
F #111: VR: Use embedded OneGate client
Browse files Browse the repository at this point in the history
  • Loading branch information
sk4zuzu committed Jun 6, 2024
1 parent 254abef commit 388be48
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 49 deletions.
2 changes: 1 addition & 1 deletion appliances/VRouter/Keepalived/main.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def configure(basedir: '/etc/keepalived')
# NOTE: When running inside OneFlow we construct VRID out of the service's ID.
# To *completely* avoid possible conflicts, deploy each OneFlow service in an *isolated* VNET.
default_vrid = if ONEAPP_VNF_KEEPALIVED_VRID.nil?
unless (svcid = SERVICE_ID || onegate_service_show&.dig('SERVICE', 'id')).nil?
unless (svcid = SERVICE_ID || OneGate.instance.service_show&.dig('SERVICE', 'id')).nil?
svcid.to_i % 255 + 1
else
# Please don't rely on this.. If you must, deploy just a single VM per an *isolated* VNET.
Expand Down
8 changes: 6 additions & 2 deletions appliances/VRouter/Keepalived/tests.rb
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ def clear_vars(object)
it 'should render vrrp.conf' do
clear_env

ENV['ONEGATE_ENDPOINT'] = 'http://127.0.0.1:5030'

ENV['ONEAPP_VNF_KEEPALIVED_INTERFACES'] = 'eth0 eth1 eth2 eth3'

ENV['ONEAPP_VNF_KEEPALIVED_ETH0_INTERVAL'] = '1'
Expand Down Expand Up @@ -162,7 +164,7 @@ def clear_vars(object)

load './main.rb'; include Service::Keepalived

allow(Service::Keepalived).to receive(:onegate_service_show).and_return(nil)
allow(OneGate.instance).to receive(:service_show).and_return(nil)
allow(Service::Keepalived).to receive(:ip_link_set_up).and_return(nil)
allow(Service::Keepalived).to receive(:detect_nics).and_return(%w[eth0 eth1 eth2 eth3])
allow(Service::Keepalived).to receive(:toggle).and_return(nil)
Expand Down Expand Up @@ -215,6 +217,8 @@ def clear_vars(object)
it 'should render vrrp.conf (passwords)' do
clear_env

ENV['ONEGATE_ENDPOINT'] = 'http://127.0.0.1:5030'

ENV['VROUTER_KEEPALIVED_PASSWORD'] = 'asd123'
ENV['ONEAPP_VNF_KEEPALIVED_ETH3_PASSWORD'] = 'asd456'

Expand All @@ -232,7 +236,7 @@ def clear_vars(object)

load './main.rb'; include Service::Keepalived

allow(Service::Keepalived).to receive(:onegate_service_show).and_return(nil)
allow(OneGate.instance).to receive(:service_show).and_return(nil)
allow(Service::Keepalived).to receive(:ip_link_set_up).and_return(nil)
allow(Service::Keepalived).to receive(:detect_nics).and_return(%w[eth0 eth1 eth2 eth3])
allow(Service::Keepalived).to receive(:toggle).and_return(nil)
Expand Down
9 changes: 3 additions & 6 deletions appliances/VRouter/WireGuard/main.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,6 @@ def to_template
# Listen port number, defaults to 51820
ONEAPP_VNF_WG_LISTEN_PORT = env :ONEAPP_VNF_WG_LISTEN_PORT, 51820

# WG device name, defaults to wg0
ONEAPP_VNF_WG_DEVICE = env :ONEAPP_VNF_WG_DEVICE, 'wg0'

# Number of peers, it will generate peer configuration and associated keys
ONEAPP_VNF_WG_PEERS = env :ONEAPP_VNF_WG_PEERS, 5

Expand Down Expand Up @@ -325,7 +322,7 @@ def execute
ids.each do |vmid|
msg :info, "[WireGuard::execute] Updating VM #{vmid}"

bash "onegate vm update #{vmid} --data \"#{data}\""
OneGate.instance.vm_update(data, vmid)
rescue StandardError => e
msg :error, e.message
next
Expand Down Expand Up @@ -362,7 +359,7 @@ def toggle(operations)

# Get the vm ids of the virtual router. Used to get/set WG configuration
def onegate_vmids
vr = onegate_vrouter_show
vr = OneGate.instance.vrouter_show

vr['VROUTER']['VMS']['ID']
rescue
Expand All @@ -371,7 +368,7 @@ def onegate_vmids

# Get configuration from the VM template
def onegate_conf(vm_id)
vm = onegate_vm_show(vm_id)
vm = OneGate.instance.vm_show(vm_id)
utmp = vm['VM']['USER_TEMPLATE']

[utmp['ONEGATE_VNF_WG_SERVER_TIMESTAMP'], utmp['ONEGATE_VNF_WG_SERVER']]
Expand Down
12 changes: 8 additions & 4 deletions appliances/VRouter/tests.rb
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,9 @@ def clear_env

RSpec.describe 'get_service_vms' do
it 'should list all available vms (oneflow)' do
allow(self).to receive(:onegate_service_show).and_return(JSON.parse(<<~'SERVICE_SHOW'))
ENV['ONEGATE_ENDPOINT'] = 'http://127.0.0.1:5030'

allow(OneGate.instance).to receive(:service_show).and_return(JSON.parse(<<~'SERVICE_SHOW'))
{
"SERVICE": {
"name": "asd",
Expand Down Expand Up @@ -480,15 +482,17 @@ def clear_env
}
VM1_SHOW

allow(self).to receive(:onegate_vm_show).and_return(*vms)
allow(OneGate.instance).to receive(:vm_show).and_return(*vms)

expect(get_service_vms).to eq vms
end
end

RSpec.describe 'get_vrouter_vnets' do
it 'should recursively resolve all viable vnets' do
allow(self).to receive(:onegate_vrouter_show).and_return(JSON.parse(<<~'VROUTER_SHOW'))
ENV['ONEGATE_ENDPOINT'] = 'http://127.0.0.1:5030'

allow(OneGate.instance).to receive(:vrouter_show).and_return(JSON.parse(<<~'VROUTER_SHOW'))
{
"VROUTER": {
"NAME": "vrouter",
Expand Down Expand Up @@ -661,7 +665,7 @@ def clear_env
}
RESERVATION_VNET_SHOW

allow(self).to receive(:onegate_vnet_show).and_return(*vnets)
allow(OneGate.instance).to receive(:vnet_show).and_return(*vnets)

expect(get_vrouter_vnets).to eq vnets
end
Expand Down
106 changes: 70 additions & 36 deletions appliances/VRouter/vrouter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,79 @@

require 'ipaddr'
require 'json'
require 'net/https'
require 'singleton'
require 'uri'

begin
require '/etc/one-appliance/lib/helpers.rb'
rescue LoadError
require_relative '../lib/helpers.rb'
end

class OneGate
include Singleton

def initialize
@uri = URI.parse(ENV['ONEGATE_ENDPOINT'])
@vmid = ENV['VMID']
@token = ENV['TOKENTXT']

@http = Net::HTTP.new(@uri.host, @uri.port)
@http.use_ssl = @uri.scheme == 'https'
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end

def vrouter_show(keep_alive: false)
path = '/vrouter'
req = Net::HTTP::Get.new(path)
req.body = URI.encode_www_form('extended' => true)
do_request req, keep_alive
end

def vnet_show(vnid, keep_alive: false)
path = "/vnet/#{vnid}"
req = Net::HTTP::Get.new(path)
req.body = URI.encode_www_form('extended' => true)
do_request req, keep_alive
end

def service_show(keep_alive: false)
path = '/service'
req = Net::HTTP::Get.new(path)
do_request req, keep_alive
end

def vm_show(vmid = nil, keep_alive: false)
path = vmid.nil? ? '/vm' : "/vms/#{vmid}"
req = Net::HTTP::Get.new(path)
do_request req, keep_alive
end

def vm_update(data, vmid = nil, erase: false, keep_alive: false)
path = vmid.nil? ? '/vm' : "/vms/#{vmid}"
req = Net::HTTP::Put.new(path)
req.body = erase ? URI.encode_www_form('type' => 2, 'data' => data) : data
do_request req, keep_alive, expect_json: false
end

private

def do_request(req, keep_alive, expect_json: true)
@http.start unless @http.started?

req['X-ONEGATE-VMID'] = @vmid
req['X-ONEGATE-TOKEN'] = @token

expect_json ? JSON.parse(@http.request(req).body) : @http.request(req).body
rescue StandardError => e
msg :error, e.full_message
nil
ensure
@http.finish unless keep_alive
end
end

def ip_link_set_up(nic)
stdout = bash "ip link set '#{nic}' up", terminate: false
end
Expand Down Expand Up @@ -278,24 +344,8 @@ def subnets_to_ranges(subnets = addrs_to_subnets.values)
end
end

def onegate_vrouter_show
stdout = bash 'onegate vrouter show --json --extended', terminate: false
JSON.parse(stdout)
rescue StandardError => e
msg :error, e.full_message
nil
end

def onegate_vnet_show(network_id)
stdout = bash "onegate vnet show --json --extended '#{network_id}'", terminate: false
JSON.parse(stdout)
rescue StandardError => e
msg :error, e.full_message
nil
end

def get_vrouter_vnets
return [] if (document = onegate_vrouter_show).nil?
return [] if (document = OneGate.instance.vrouter_show).nil?
return [] if (nics = document.dig('VROUTER', 'TEMPLATE', 'NIC')).nil?

initial_network_ids = nics.map { |nic| nic['NETWORK_ID'] }
Expand All @@ -306,7 +356,7 @@ def get_vrouter_vnets

def recurse(network_ids)
network_ids.each_with_object([]) do |network_id, vnets|
next if (vnet = onegate_vnet_show(network_id)).nil?
next if (vnet = OneGate.instance.vnet_show(network_id)).nil?

vnets << vnet

Expand All @@ -333,24 +383,8 @@ def recurse(network_ids)
recurse(initial_network_ids)
end

def onegate_service_show
stdout = bash 'onegate service show --json', terminate: false
JSON.parse(stdout)
rescue StandardError => e
msg :error, e.full_message
nil
end

def onegate_vm_show(vm_id)
stdout = bash "onegate vm show --json '#{vm_id}'", terminate: false
JSON.parse(stdout)
rescue StandardError => e
msg :error, e.full_message
nil
end

def get_service_vms # OneFlow
return [] if (document = onegate_service_show).nil?
return [] if (document = OneGate.instance.service_show).nil?
return [] if (roles = document.dig('SERVICE', 'roles')).nil?

roles.each_with_object([]) do |role, acc|
Expand All @@ -362,7 +396,7 @@ def get_service_vms # OneFlow
acc << vm_id
end
end.uniq.each_with_object([]) do |vm_id, acc|
next if (vm = onegate_vm_show(vm_id)).nil?
next if (vm = OneGate.instance.vm_show(vm_id)).nil?

acc << vm
end
Expand Down

0 comments on commit 388be48

Please sign in to comment.