Remove OVSDB client implementation, because it was already useless in my use case
This commit is contained in:
parent
4965bc60ec
commit
09f6266ab6
4 changed files with 1 additions and 482 deletions
22
lib/ovsdb.ex
22
lib/ovsdb.ex
|
|
@ -1,22 +0,0 @@
|
|||
defmodule OVSDB do
|
||||
@moduledoc false
|
||||
|
||||
@behaviour :supervisor
|
||||
|
||||
def start_link do
|
||||
:supervisor.start_link({:local, __MODULE__}, __MODULE__, [])
|
||||
end
|
||||
|
||||
def init([]) do
|
||||
child = OVSDB.OpenvSwitch
|
||||
strategy = :simple_one_for_one
|
||||
max_r = 1000
|
||||
intensity = 3600
|
||||
sup_flags = {strategy, max_r, intensity}
|
||||
{:ok, {sup_flags, [{child, {child, :start_link, []}, :temporary, 1000, :worker, [child]}]}}
|
||||
end
|
||||
|
||||
def start_child(server) do
|
||||
:supervisor.start_child(__MODULE__, [server])
|
||||
end
|
||||
end
|
||||
|
|
@ -1,414 +0,0 @@
|
|||
defmodule OVSDB.OpenvSwitch do
|
||||
use GenServer
|
||||
|
||||
defmodule State do
|
||||
defstruct server: nil,
|
||||
client_pid: nil,
|
||||
monitor_pid: nil,
|
||||
ovs_uuid: nil
|
||||
end
|
||||
|
||||
@database "Open_vSwitch"
|
||||
|
||||
@open_vswitch "Open_vSwitch"
|
||||
@interface "Interface"
|
||||
@port "Port"
|
||||
@controller "Controller"
|
||||
@bridge "Bridge"
|
||||
|
||||
def find_by_name(pid, table, name) do
|
||||
GenServer.call(pid, {:find_by_name, table, name})
|
||||
end
|
||||
|
||||
# API functions
|
||||
|
||||
@doc """
|
||||
Create a bridge:
|
||||
|
||||
## options:
|
||||
iex> OpenvSwitch.add_br(
|
||||
client_pid,
|
||||
name: "br0",
|
||||
fail_mode: "standalone",
|
||||
datapath_id: "0000000000000001",
|
||||
disable_in_band: "true"
|
||||
)
|
||||
"""
|
||||
def add_br(pid, [_ | _] = options) do
|
||||
br_uuids = GenServer.call(pid, {:sync_get, @open_vswitch, "bridges"})
|
||||
|
||||
add_br_options = [
|
||||
bridge: options[:name],
|
||||
fail_mode: options[:fail_mode] || "standalone",
|
||||
datapath_id: options[:datapath_id],
|
||||
disable_in_band: options[:disable_in_band],
|
||||
br_uuids: br_uuids
|
||||
]
|
||||
|
||||
GenServer.call(pid, {:add_br, add_br_options})
|
||||
end
|
||||
|
||||
@doc """
|
||||
Delete a bridge
|
||||
|
||||
iex> OpenvSwitch.del_br(client_pid, "br0")
|
||||
"""
|
||||
def del_br(pid, bridge) do
|
||||
case find_by_name(pid, @bridge, bridge) do
|
||||
%{"_uuid" => uuid} ->
|
||||
new_bridges =
|
||||
case GenServer.call(pid, {:sync_get, @open_vswitch, "bridges"}) do
|
||||
["set", bridges] -> %{"bridges" => ["set", bridges -- [uuid]]}
|
||||
^uuid -> %{"bridges" => ["set", []]}
|
||||
curr_bridges -> %{"bridges" => curr_bridges}
|
||||
end
|
||||
|
||||
GenServer.call(pid, {:del_br, new_bridges})
|
||||
|
||||
:not_found ->
|
||||
{:error, :not_found}
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Set a controller to the switch
|
||||
|
||||
iex> OpenvSwitch.set_controller(
|
||||
client_pid,
|
||||
bridge: "br0",
|
||||
target: "tcp:127.0.0.1:6653",
|
||||
connection_mode: "out-of-band",
|
||||
controller_rate_limit: 100,
|
||||
controller_burst_limit: 25,
|
||||
protocol: "OpenFlow13"
|
||||
)
|
||||
"""
|
||||
def set_controller(pid, [_ | _] = options) do
|
||||
case find_by_name(pid, @bridge, options[:bridge]) do
|
||||
:not_found ->
|
||||
{:error, :not_found}
|
||||
|
||||
%{"_uuid" => _uuid} ->
|
||||
set_ctl_opts = [
|
||||
bridge: options[:bridge],
|
||||
target: options[:target] || "tcp:127.0.0.1:6653",
|
||||
connection_mode: options[:connection_mode] || "out-of-band",
|
||||
controller_rate_limit: options[:controller_rate_limit] || 1000,
|
||||
controller_burst_limit: options[:controller_burst_limit] || 100,
|
||||
protocol: options[:protocol] || "OpenFlow13"
|
||||
]
|
||||
|
||||
GenServer.call(pid, {:set_controller, set_ctl_opts})
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
iex> OpenvSwitch.add_port(
|
||||
client_pid,
|
||||
bridge: "br0",
|
||||
name: "vxlan5",
|
||||
type: "vxlan",
|
||||
remote_ip: "flow",
|
||||
ofport_request: 99
|
||||
)
|
||||
"""
|
||||
def add_port(pid, [_ | _] = options) do
|
||||
case find_by_name(pid, @bridge, options[:bridge]) do
|
||||
:not_found ->
|
||||
{:error, :not_found}
|
||||
|
||||
%{"_uuid" => _uuid, "ports" => ports} ->
|
||||
port_opts = [
|
||||
bridge: options[:bridge],
|
||||
name: options[:name],
|
||||
type: options[:type] || "system",
|
||||
ofport_request: options[:ofport_request],
|
||||
remote_ip: options[:remote_ip],
|
||||
local_ip: options[:local_ip],
|
||||
in_key: options[:in_key],
|
||||
out_key: options[:out_key],
|
||||
key: options[:key],
|
||||
tos: options[:tos],
|
||||
ttl: options[:ttl],
|
||||
df_default: options[:df_default],
|
||||
csum: options[:csum],
|
||||
peer_cert: options[:peer_cert],
|
||||
certificate: options[:certificate],
|
||||
private_key: options[:private_key],
|
||||
psk: options[:psk],
|
||||
ingress_policing_rate: options[:ingress_policing_rate] || 0,
|
||||
ingress_policing_burst: options[:ingress_policing_burst] || 0,
|
||||
ports: ports
|
||||
]
|
||||
|
||||
GenServer.call(pid, {:add_port, port_opts})
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
iex> OpenvSwitch.del_port(client_pid, bridge: "br0", port: "vxlan5")
|
||||
"""
|
||||
def del_port(pid, [_ | _] = options) do
|
||||
case find_by_name(pid, @bridge, options[:bridge]) do
|
||||
:not_found ->
|
||||
{:error, :not_found}
|
||||
|
||||
%{"_uuid" => _uuid, "ports" => ports} ->
|
||||
case find_by_name(pid, @port, options[:port]) do
|
||||
:not_found ->
|
||||
{:error, :not_found}
|
||||
|
||||
%{"_uuid" => port_uuid} ->
|
||||
new_ports = del_elem_from_set(ports, port_uuid)
|
||||
|
||||
port_opts = [
|
||||
bridge: options[:bridge],
|
||||
ports: new_ports
|
||||
]
|
||||
|
||||
GenServer.call(pid, {:del_port, port_opts})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# GenServer callback functions
|
||||
|
||||
def start_link(server) do
|
||||
GenServer.start_link(__MODULE__, [server])
|
||||
end
|
||||
|
||||
def init([server]) do
|
||||
state =
|
||||
server
|
||||
|> String.to_charlist()
|
||||
|> init_client
|
||||
|
||||
{:ok, state}
|
||||
end
|
||||
|
||||
def handle_call({:sync_get, table, col_name}, _from, state) do
|
||||
[%{"rows" => [%{^col_name => values} | _]}] =
|
||||
[col_name]
|
||||
|> :eovsdb_op.select(table, [])
|
||||
|> xact(state.client_pid)
|
||||
|
||||
{:reply, values, state}
|
||||
end
|
||||
|
||||
def handle_call({:add_br, options}, _from, state) do
|
||||
%State{client_pid: pid, ovs_uuid: ovs} = state
|
||||
br_iface = %{name: options[:bridge], type: :internal}
|
||||
br_port = %{name: options[:bridge], interfaces: ["named-uuid", "interface"]}
|
||||
|
||||
other_config = [
|
||||
["datapath-id", options[:datapath_id]],
|
||||
["dp-desc", options[:dp_desc]],
|
||||
["disable-in-band", options[:disable_in_band]],
|
||||
["in-band-queue", options[:in_band_queue]]
|
||||
]
|
||||
|
||||
new_bridge = %{
|
||||
name: options[:bridge],
|
||||
ports: ["named-uuid", "port"],
|
||||
fail_mode: options[:fail_mode],
|
||||
other_config: make_ovsdb_map(other_config)
|
||||
}
|
||||
|
||||
named_uuid = ["named-uuid", "bridge"]
|
||||
new_bridges = %{bridges: add_elem_to_set(options[:br_uuids], named_uuid)}
|
||||
|
||||
next_config = [{"next_cfg", "+=", 1}]
|
||||
eq_ovs_uuid = [{"_uuid", "==", ovs}]
|
||||
|
||||
replies =
|
||||
xact(
|
||||
[
|
||||
:eovsdb_op.insert(@interface, br_iface, "interface"),
|
||||
:eovsdb_op.insert(@port, br_port, "port"),
|
||||
:eovsdb_op.insert(@bridge, new_bridge, "bridge"),
|
||||
:eovsdb_op.update(@open_vswitch, eq_ovs_uuid, new_bridges),
|
||||
:eovsdb_op.mutate(@open_vswitch, eq_ovs_uuid, next_config)
|
||||
],
|
||||
pid
|
||||
)
|
||||
|
||||
{:reply, replies, state}
|
||||
end
|
||||
|
||||
def handle_call({:del_br, new_bridges}, _from, state) do
|
||||
%State{client_pid: pid, ovs_uuid: ovs} = state
|
||||
eq_ovs_uuid = [{"_uuid", "==", ovs}]
|
||||
next_config = [{"next_cfg", "+=", 1}]
|
||||
|
||||
replies =
|
||||
xact(
|
||||
[
|
||||
:eovsdb_op.update(@open_vswitch, eq_ovs_uuid, new_bridges),
|
||||
:eovsdb_op.mutate(@open_vswitch, eq_ovs_uuid, next_config)
|
||||
],
|
||||
pid
|
||||
)
|
||||
|
||||
{:reply, replies, state}
|
||||
end
|
||||
|
||||
def handle_call({:del_port, options}, _from, state) do
|
||||
%State{client_pid: pid, ovs_uuid: ovs} = state
|
||||
eq_br_name = [{"name", "==", options[:bridge]}]
|
||||
eq_ovs_uuid = [{"_uuid", "==", ovs}]
|
||||
next_config = [{"next_cfg", "+=", 1}]
|
||||
|
||||
bridge = %{ports: options[:ports]}
|
||||
|
||||
replies =
|
||||
xact(
|
||||
[
|
||||
:eovsdb_op.update(@bridge, eq_br_name, bridge),
|
||||
:eovsdb_op.mutate(@open_vswitch, eq_ovs_uuid, next_config)
|
||||
],
|
||||
pid
|
||||
)
|
||||
|
||||
{:reply, replies, state}
|
||||
end
|
||||
|
||||
def handle_call({:set_controller, options}, _from, state) do
|
||||
%State{client_pid: pid, ovs_uuid: ovs} = state
|
||||
|
||||
controller = %{
|
||||
target: options[:target],
|
||||
connection_mode: options[:connection_mode],
|
||||
controller_rate_limit: options[:controller_rate_limit],
|
||||
controller_burst_limit: options[:controller_burst_limit]
|
||||
}
|
||||
|
||||
bridge = %{
|
||||
protocols: options[:protocol],
|
||||
controller: ["named-uuid", "controller"]
|
||||
}
|
||||
|
||||
replies =
|
||||
xact(
|
||||
[
|
||||
:eovsdb_op.insert(@controller, controller, "controller"),
|
||||
:eovsdb_op.update(@bridge, [{"name", "==", options[:bridge]}], bridge),
|
||||
:eovsdb_op.mutate(@open_vswitch, [{"_uuid", "==", ovs}], [{"next_cfg", "+=", 1}])
|
||||
],
|
||||
pid
|
||||
)
|
||||
|
||||
{:reply, replies, state}
|
||||
end
|
||||
|
||||
def handle_call({:add_port, options}, _from, state) do
|
||||
%State{client_pid: pid, ovs_uuid: ovs} = state
|
||||
|
||||
port = %{
|
||||
name: options[:name],
|
||||
interfaces: ["named-uuid", "interface"]
|
||||
}
|
||||
|
||||
iface_options = [
|
||||
["remote_ip", options[:remote_ip]],
|
||||
["local_ip", options[:local_ip]],
|
||||
["in_key", options[:in_key]],
|
||||
["out_key", options[:out_key]],
|
||||
["key", options[:key]],
|
||||
["tos", options[:tos]],
|
||||
["ttl", options[:ttl]],
|
||||
["df_default", options[:df_default]],
|
||||
["csum", options[:csum]],
|
||||
["peer_cert", options[:peer_cert]],
|
||||
["certificate", options[:certificate]],
|
||||
["private_key", options[:private_key]],
|
||||
["psk", options[:psk]]
|
||||
]
|
||||
|
||||
interface = %{
|
||||
name: options[:name],
|
||||
type: options[:type],
|
||||
ingress_policing_rate: options[:ingress_policing_rate],
|
||||
ingress_policing_burst: options[:ingress_policing_burst],
|
||||
ofport_request: make_ovsdb_set(options[:ofport_request]),
|
||||
options: make_ovsdb_map(iface_options)
|
||||
}
|
||||
|
||||
bridge = %{ports: add_elem_to_set(options[:ports], ["named-uuid", "port"])}
|
||||
|
||||
next_config = [{"next_cfg", "+=", 1}]
|
||||
eq_br_name = [{"name", "==", options[:bridge]}]
|
||||
eq_ovs_uuid = [{"_uuid", "==", ovs}]
|
||||
|
||||
replies =
|
||||
xact(
|
||||
[
|
||||
:eovsdb_op.insert(@interface, interface, "interface"),
|
||||
:eovsdb_op.insert(@port, port, "port"),
|
||||
:eovsdb_op.update(@bridge, eq_br_name, bridge),
|
||||
:eovsdb_op.mutate(@open_vswitch, eq_ovs_uuid, next_config)
|
||||
],
|
||||
pid
|
||||
)
|
||||
|
||||
{:reply, replies, state}
|
||||
end
|
||||
|
||||
def handle_call({:find_by_name, table, name}, _from, state) do
|
||||
%State{client_pid: pid} = state
|
||||
reply = do_find_by_name(pid, table, name)
|
||||
{:reply, reply, state}
|
||||
end
|
||||
|
||||
def handle_cast({:async_get, "_uuid"}, state) do
|
||||
[%{"rows" => [%{"_uuid" => values} | _]}] =
|
||||
["_uuid"]
|
||||
|> :eovsdb_op.select(@open_vswitch, [])
|
||||
|> xact(state.client_pid)
|
||||
|
||||
{:noreply, %{state | ovs_uuid: values}}
|
||||
end
|
||||
|
||||
# private functions
|
||||
|
||||
defp init_client(server) do
|
||||
{:ok, pid} = :eovsdb_client.connect(server, database: @database)
|
||||
:eovsdb_client.regist_schema(pid)
|
||||
:ok = GenServer.cast(self(), {:async_get, "_uuid"})
|
||||
%State{server: server, client_pid: pid}
|
||||
end
|
||||
|
||||
defp xact(query, pid) when is_list(query) do
|
||||
{:ok, res} = :eovsdb_client.transaction(pid, query)
|
||||
res
|
||||
end
|
||||
|
||||
defp xact(query, pid) when is_map(query) do
|
||||
xact([query], pid)
|
||||
end
|
||||
|
||||
defp do_find_by_name(pid, table, name) do
|
||||
query = :eovsdb_op.select('*', table, [{"name", "==", name}])
|
||||
|
||||
case xact(query, pid) do
|
||||
[%{"rows" => []}] -> :not_found
|
||||
[%{"rows" => [row]}] -> row
|
||||
end
|
||||
end
|
||||
|
||||
defp make_ovsdb_map(map), do: make_ovsdb_map([], map)
|
||||
|
||||
defp make_ovsdb_map(acc, []), do: ["map", Enum.reverse(acc)]
|
||||
defp make_ovsdb_map(acc, [[_key, nil] | rest]), do: make_ovsdb_map(acc, rest)
|
||||
defp make_ovsdb_map(acc, [attr | rest]), do: make_ovsdb_map([attr | acc], rest)
|
||||
|
||||
defp make_ovsdb_set(nil), do: ["set", []]
|
||||
defp make_ovsdb_set([_ | _] = list), do: ["set", list]
|
||||
defp make_ovsdb_set(value), do: value
|
||||
|
||||
defp add_elem_to_set(["set", []], value), do: value
|
||||
defp add_elem_to_set(["set", values], value), do: ["set", values ++ [value]]
|
||||
defp add_elem_to_set(["uuid", _] = uuid, value), do: ["set", [uuid] ++ [value]]
|
||||
|
||||
defp del_elem_from_set(["set", values], value), do: ["set", values -- [value]]
|
||||
defp del_elem_from_set(["uuid", _], _value), do: ["set", []]
|
||||
end
|
||||
|
|
@ -12,8 +12,7 @@ defmodule Tres.Application do
|
|||
children = [
|
||||
worker(Registry, [[keys: :unique, name: SwitchRegistry]], id: SwitchRegistry),
|
||||
worker(Registry, [[keys: :unique, name: HandlerRegistry]], id: HandlerRegistry),
|
||||
supervisor(Tres.MessageHandlerSup, [], id: MessageHandlerSup),
|
||||
supervisor(OVSDB, [], id: OVSDB)
|
||||
supervisor(Tres.MessageHandlerSup, [], id: MessageHandlerSup)
|
||||
]
|
||||
|
||||
opts = [strategy: :one_for_one, name: Tres.Supervisor]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue