COPY system /etc/config/system
COPY ipsec /etc/config/ipsec
+COPY ipsec_exec /etc/init.d/ipsec
COPY rest_v1 /usr/lib/lua/luci/controller/rest_v1
ENV http_proxy=
COPY system /etc/config/system
COPY ipsec /etc/config/ipsec
+COPY ipsec_exec /etc/init.d/ipsec
COPY rest_v1 /usr/lib/lua/luci/controller/rest_v1
USER root
--- /dev/null
+#!/bin/sh /etc/rc.common
+
+START=90
+STOP=10
+
+USE_PROCD=1
+PROG=/usr/lib/ipsec/starter
+
+. $IPKG_INSTROOT/lib/functions.sh
+. $IPKG_INSTROOT/lib/functions/network.sh
+
+IPSEC_SECRETS_FILE=/etc/ipsec.secrets
+IPSEC_CONN_FILE=/etc/ipsec.conf
+STRONGSWAN_CONF_FILE=/etc/strongswan.conf
+
+IPSEC_VAR_SECRETS_FILE=/var/ipsec/ipsec.secrets
+IPSEC_VAR_CONN_FILE=/var/ipsec/ipsec.conf
+STRONGSWAN_VAR_CONF_FILE=/var/ipsec/strongswan.conf
+
+WAIT_FOR_INTF=0
+
+file_reset() {
+ : > "$1"
+}
+
+xappend() {
+ local file="$1"
+ shift
+
+ echo "${@}" >> "${file}"
+}
+
+remove_include() {
+ local file="$1"
+ local include="$2"
+
+ sed -i "\_${include}_d" "${file}"
+}
+
+remove_includes() {
+ remove_include "${IPSEC_CONN_FILE}" "${IPSEC_VAR_CONN_FILE}"
+ remove_include "${IPSEC_SECRETS_FILE}" "${IPSEC_VAR_SECRETS_FILE}"
+ remove_include "${STRONGSWAN_CONF_FILE}" "${STRONGSWAN_VAR_CONF_FILE}"
+}
+
+do_include() {
+ local conf="$1"
+ local uciconf="$2"
+ local backup=`mktemp -t -p /tmp/ ipsec-init-XXXXXX`
+
+ [ ! -f "${conf}" ] && rm -rf "${conf}"
+ touch "${conf}"
+
+ cat "${conf}" | grep -v "${uciconf}" > "${backup}"
+ mv "${backup}" "${conf}"
+ xappend "${conf}" "include ${uciconf}"
+ file_reset "${uciconf}"
+}
+
+ipsec_reset() {
+ do_include "${IPSEC_CONN_FILE}" "${IPSEC_VAR_CONN_FILE}"
+}
+
+ipsec_xappend() {
+ xappend "${IPSEC_VAR_CONN_FILE}" "$@"
+}
+
+swan_reset() {
+ do_include "${STRONGSWAN_CONF_FILE}" "${STRONGSWAN_VAR_CONF_FILE}"
+}
+
+swan_xappend() {
+ xappend "${STRONGSWAN_VAR_CONF_FILE}" "$@"
+}
+
+secret_reset() {
+ do_include "${IPSEC_SECRETS_FILE}" "${IPSEC_VAR_SECRETS_FILE}"
+}
+
+secret_xappend() {
+ xappend "${IPSEC_VAR_SECRETS_FILE}" "$@"
+}
+
+warning() {
+ echo "WARNING: $@" >&2
+}
+
+add_crypto_proposal() {
+ local encryption_algorithm
+ local hash_algorithm
+ local dh_group
+
+ config_get encryption_algorithm "$1" encryption_algorithm
+ config_get hash_algorithm "$1" hash_algorithm
+ config_get dh_group "$1" dh_group
+
+ [ -n "${encryption_algorithm}" ] && \
+ crypto="${crypto:+${crypto},}${encryption_algorithm}${hash_algorithm:+-${hash_algorithm}}${dh_group:+-${dh_group}}"
+}
+
+set_crypto_proposal() {
+ local conf="$1"
+ local proposal
+
+ crypto=""
+
+ config_get crypto_proposal "$conf" crypto_proposal ""
+ for proposal in $crypto_proposal; do
+ add_crypto_proposal "$proposal"
+ done
+
+ [ -n "${crypto}" ] && {
+ local force_crypto_proposal
+
+ config_get_bool force_crypto_proposal "$conf" force_crypto_proposal
+
+ [ "${force_crypto_proposal}" = "1" ] && crypto="${crypto}!"
+ }
+
+ crypto_proposal="${crypto}"
+}
+
+config_conn() {
+ # Generic ipsec conn section shared by tunnel and transport
+ local mode
+ local mark
+ local local_subnet
+ local local_nat
+ local local_sourceip
+ local local_updown
+ local local_firewall
+ local remote_subnet
+ local remote_sourceip
+ local remote_updown
+ local remote_firewall
+ local ikelifetime
+ local lifetime
+ local margintime
+ local keyingtries
+ local dpdaction
+ local dpddelay
+ local inactivity
+ local keyexchange
+
+ config_get mode "$1" mode "route"
+ config_get local_subnet "$1" local_subnet ""
+ config_get local_nat "$1" local_nat ""
+ config_get local_sourceip "$1" local_sourceip ""
+ config_get local_updown "$1" local_updown ""
+ config_get local_firewall "$1" local_firewall ""
+ config_get remote_subnet "$1" remote_subnet ""
+ config_get remote_sourceip "$1" remote_sourceip ""
+ config_get remote_updown "$1" remote_updown ""
+ config_get remote_firewall "$1" remote_firewall ""
+ config_get ikelifetime "$1" ikelifetime "3h"
+ config_get lifetime "$1" lifetime "1h"
+ config_get margintime "$1" margintime "9m"
+ config_get keyingtries "$1" keyingtries "3"
+ config_get dpdaction "$1" dpdaction "none"
+ config_get dpddelay "$1" dpddelay "30s"
+ config_get inactivity "$1" inactivity
+ config_get keyexchange "$1" keyexchange "ikev2"
+ config_get mark "$1" mark ""
+
+ [ -n "$local_nat" ] && local_subnet=$local_nat
+
+ ipsec_xappend "conn $config_name-$1"
+ ipsec_xappend " left=%any"
+ ipsec_xappend " right=$remote_gateway"
+
+ [ -n "$local_sourceip" ] && ipsec_xappend " leftsourceip=$local_sourceip"
+ [ -n "$local_subnet" ] && ipsec_xappend " leftsubnet=$local_subnet"
+
+ [ -n "$local_firewall" ] && ipsec_xappend " leftfirewall=$local_firewall"
+ [ -n "$remote_firewall" ] && ipsec_xappend " rightfirewall=$remote_firewall"
+
+ ipsec_xappend " ikelifetime=$ikelifetime"
+ ipsec_xappend " lifetime=$lifetime"
+ ipsec_xappend " margintime=$margintime"
+ ipsec_xappend " keyingtries=$keyingtries"
+ ipsec_xappend " dpdaction=$dpdaction"
+ ipsec_xappend " dpddelay=$dpddelay"
+
+ [ -n "$inactivity" ] && ipsec_xappend " inactivity=$inactivity"
+
+ if [ "$auth_method" = "psk" ]; then
+ ipsec_xappend " leftauth=psk"
+ ipsec_xappend " rightauth=psk"
+
+ [ "$remote_sourceip" != "" ] && ipsec_xappend " rightsourceip=$remote_sourceip"
+ [ "$remote_subnet" != "" ] && ipsec_xappend " rightsubnet=$remote_subnet"
+
+ ipsec_xappend " auto=$mode"
+ elif [ "$auth_method" = "pubkey" ]; then
+ ipsec_xappend " leftauth=pubkey"
+ ipsec_xappend " rightauth=pubkey"
+
+ [ "$remote_sourceip" != "" ] && ipsec_xappend " rightsourceip=$remote_sourceip"
+ [ "$remote_subnet" != "" ] && ipsec_xappend " rightsubnet=$remote_subnet"
+
+ ipsec_xappend " auto=$mode"
+ else
+ warning "AuthenticationMethod $auth_method not supported"
+ fi
+
+ [ -n "$local_identifier" ] && ipsec_xappend " leftid=$local_identifier"
+ [ -n "$remote_identifier" ] && ipsec_xappend " rightid=$remote_identifier"
+ [ -n "$local_updown" ] && ipsec_xappend " leftupdown=$local_updown"
+ [ -n "$remote_updown" ] && ipsec_xappend " rightupdown=$remote_updown"
+ ipsec_xappend " keyexchange=$keyexchange"
+
+ [ "$type" = "VTI-based" ] && ipsec_xappend " mark=$mark"
+
+ set_crypto_proposal "$1"
+ [ -n "${crypto_proposal}" ] && ipsec_xappend " esp=$crypto_proposal"
+ [ -n "${ike_proposal}" ] && ipsec_xappend " ike=$ike_proposal"
+}
+
+config_tunnel() {
+ config_conn "$1"
+
+ # Specific for the tunnel part
+ ipsec_xappend " type=tunnel"
+}
+
+config_transport() {
+ config_conn "$1"
+
+ # Specific for the transport part
+ ipsec_xappend " type=transport"
+}
+
+config_remote() {
+ local enabled
+ local gateway
+ local pre_shared_key
+ local auth_method
+ local type
+
+ config_name=$1
+
+ config_get_bool enabled "$1" enabled 0
+ [ $enabled -eq 0 ] && return
+
+ config_get gateway "$1" gateway
+ config_get pre_shared_key "$1" pre_shared_key
+ config_get auth_method "$1" authentication_method
+ config_get local_identifier "$1" local_identifier ""
+ config_get remote_identifier "$1" remote_identifier ""
+ config_get type "$1" type "policy-based"
+
+ [ "$gateway" = "any" ] && remote_gateway="%any" || remote_gateway="$gateway"
+
+ [ -z "$local_identifier" ] && {
+ local ipdest
+
+ [ "$remote_gateway" = "%any" ] && ipdest="1.1.1.1" || ipdest="$remote_gateway"
+ local_gateway=`ip route get $ipdest | awk -F"src" '/src/{gsub(/ /,"");print $2}'`
+ }
+
+ [ -n "$local_identifier" ] && secret_xappend -n "$local_identifier " || secret_xappend -n "$local_gateway "
+ [ -n "$remote_identifier" ] && secret_xappend -n "$remote_identifier " || secret_xappend -n "$remote_gateway "
+
+ secret_xappend ": PSK \"$pre_shared_key\""
+
+ set_crypto_proposal "$1"
+ ike_proposal="$crypto_proposal"
+
+ config_list_foreach "$1" tunnel config_tunnel
+
+ config_list_foreach "$1" transport config_transport
+
+ ipsec_xappend ""
+}
+
+config_ipsec() {
+ local debug
+ local rtinstall_enabled
+ local routing_tables_ignored
+ local routing_table
+ local routing_table_id
+ local interface
+ local device_list
+
+ ipsec_reset
+ secret_reset
+ swan_reset
+
+ ipsec_xappend "# generated by /etc/init.d/ipsec"
+ ipsec_xappend "version 2"
+ ipsec_xappend ""
+
+ secret_xappend "# generated by /etc/init.d/ipsec"
+
+ config_get debug "$1" debug 0
+ config_get_bool rtinstall_enabled "$1" rtinstall_enabled 1
+ [ $rtinstall_enabled -eq 1 ] && install_routes=yes || install_routes=no
+
+ # prepare extra charon config option ignore_routing_tables
+ for routing_table in $(config_get "$1" "ignore_routing_tables"); do
+ if [ "$routing_table" -ge 0 ] 2>/dev/null; then
+ routing_table_id=$routing_table
+ else
+ routing_table_id=$(sed -n '/[ \t]*[0-9]\+[ \t]\+'$routing_table'[ \t]*$/s/[ \t]*\([0-9]\+\).*/\1/p' /etc/iproute2/rt_tables)
+ fi
+
+ [ -n "$routing_table_id" ] && append routing_tables_ignored "$routing_table_id"
+ done
+
+ local interface_list=$(config_get "$1" "interface")
+ if [ -z "$interface_list" ]; then
+ WAIT_FOR_INTF=0
+ else
+ for interface in $interface_list; do
+ network_get_device device $interface
+ [ -n "$device" ] && append device_list "$device" ","
+ done
+ [ -n "$device_list" ] && WAIT_FOR_INTF=0 || WAIT_FOR_INTF=1
+ fi
+
+ swan_xappend "# generated by /etc/init.d/ipsec"
+ swan_xappend "charon {"
+ swan_xappend " load_modular = yes"
+ swan_xappend " install_routes = $install_routes"
+ [ -n "$routing_tables_ignored" ] && swan_xappend " ignore_routing_tables = $routing_tables_ignored"
+ [ -n "$device_list" ] && swan_xappend " interfaces_use = $device_list"
+ swan_xappend " plugins {"
+ swan_xappend " include /etc/strongswan.d/charon/*.conf"
+ swan_xappend " }"
+ swan_xappend " syslog {"
+ swan_xappend " identifier = ipsec"
+ swan_xappend " daemon {"
+ swan_xappend " default = $debug"
+ swan_xappend " }"
+ swan_xappend " auth {"
+ swan_xappend " default = $debug"
+ swan_xappend " }"
+ swan_xappend " }"
+ swan_xappend "}"
+}
+
+prepare_env() {
+ mkdir -p /var/ipsec
+ remove_includes
+ config_load ipsec
+ config_foreach config_ipsec ipsec
+ config_foreach config_remote remote
+}
+
+service_running() {
+ ipsec status > /dev/null 2>&1
+}
+
+reload_service() {
+ running && {
+ prepare_env
+ [ $WAIT_FOR_INTF -eq 0 ] && {
+ ipsec rereadall
+ ipsec reload
+ return
+ }
+ }
+
+ start
+}
+
+check_ipsec_interface() {
+ local intf
+
+ for intf in $(config_get "$1" interface); do
+ procd_add_interface_trigger "interface.*" "$intf" /etc/init.d/ipsec reload
+ done
+}
+
+service_triggers() {
+ procd_add_reload_trigger "ipsec"
+ config load "ipsec"
+ config_foreach check_ipsec_interface ipsec
+}
+
+start_service() {
+ prepare_env
+
+ [ $WAIT_FOR_INTF -eq 1 ] && return
+
+ procd_open_instance
+
+ procd_set_param command $PROG --daemon charon --nofork
+
+ procd_set_param file $IPSEC_CONN_FILE
+ procd_append_param file $IPSEC_SECRETS_FILE
+ procd_append_param file $STRONGSWAN_CONF_FILE
+ procd_append_param file /etc/strongswan.d/*.conf
+ procd_append_param file /etc/strongswan.d/charon/*.conf
+
+ procd_set_param respawn
+
+ procd_close_instance
+}
}
connection_validator = {
-config_type=function(value) return value["type"] end,
+config_type=function(value) return value["conn_type"] end,
{name="name", required=true},
- {name="type", required=true, validator=function(value) return utils.in_array(value, {"tunnel", "transport"}) end, load_func=function(value) return value[".type"] end, save_func=function(value) return true, "" end, message="invalid type"},
+ {name="conn_type", required=true, validator=function(value) return utils.in_array(value, {"tunnel", "transport"}) end, load_func=function(value) return value[".type"] end, save_func=function(value) return true, "" end, message="invalid type"},
{name="mode", required=true, validator=function(value) return utils.in_array(value, {"start", "add", "route"}) end, message="invalid connection mode"},
{name="local_subnet"},
{name="local_nat"},
{name="remote_updown"},
{name="remote_firewall", validator=function(value) return utils.in_array(value, {"yes", "no"}) end},
{name="crypto_proposal", is_list=true, item_validator=function(value) return is_proposal_available(value) end, message="invalid crypto_proposal"},
+ {name="mark"},
}
-site_validator = {
+remote_validator = {
config_type="remote",
object_validator=function(value) return check_auth_method(value) end,
{name="name"},
+ {name="type"},
{name="gateway", required=true},
{name="enabled", default="1"},
{name="authentication_method", required=true, validator=function(value) return utils.in_array(value, {"psk", "pubkey"}) end},
ipsec_processor = {
proposal={update="update_proposal", delete="delete_proposal", validator=proposal_validator},
- site={validator=site_validator},
+ remote={validator=remote_validator},
configuration=uci_conf
}
ver = "v1"
configuration = "ipsec"
entry({"sdewan", configuration, ver, "proposals"}, call("handle_request")).leaf = true
- entry({"sdewan", configuration, ver, "sites"}, call("handle_request")).leaf = true
+ entry({"sdewan", configuration, ver, "remotes"}, call("handle_request")).leaf = true
end
-- Validate authentication method and secrets
local connections = value["connections"]
local ret_value = {_standard_format=true}
for i=1, #connections do
- add_to_key_list(ret_value, connections[i]["type"], connections[i])
+ add_to_key_list(ret_value, connections[i]["conn_type"], connections[i])
end
return true, ret_value
```
kubectl apply -f examples/attach-network-ovn.yaml
kubectl apply -f examples/ovn-net1.yaml
- kubectl apply -f examples/ovn-net2.yml
+ kubectl apply -f examples/ovn-net2.yaml
```
2. Launch CNF deployment. **NOTE:** CNF deployment is supposed to bind to a Node.
For the sample cnf yaml, we bind it to master node. You can bind to other node by modifying the `nodeSelector`.
- FirewallRule
- FirewallDNAT
- FirewallSNAT
+ - IpsecProposal
+ - IpsecHost
### What we don't have yet
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.2.5
+ creationTimestamp: null
+ name: ipsechosts.batch.sdewan.akraino.org
+spec:
+ group: batch.sdewan.akraino.org
+ names:
+ kind: IpsecHost
+ listKind: IpsecHostList
+ plural: ipsechosts
+ singular: ipsechost
+ scope: Namespaced
+ subresources:
+ status: {}
+ validation:
+ openAPIV3Schema:
+ description: IpsecHost is the Schema for the ipsechosts API
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation
+ of an object. Servers should convert recognized schemas to the latest
+ internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this
+ object represents. Servers may infer this from the endpoint the client
+ submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ properties:
+ authentication_method:
+ type: string
+ connections:
+ items:
+ properties:
+ conn_type:
+ type: string
+ crypto_proposal:
+ items:
+ type: string
+ type: array
+ if_id:
+ type: string
+ local_firewall:
+ type: string
+ local_sourceip:
+ type: string
+ local_updown:
+ type: string
+ mark:
+ type: string
+ mode:
+ type: string
+ name:
+ type: string
+ remote_firewall:
+ type: string
+ remote_sourceip:
+ type: string
+ remote_subnet:
+ type: string
+ remote_updown:
+ type: string
+ required:
+ - conn_type
+ - mode
+ - name
+ type: object
+ type: array
+ crypto_proposal:
+ items:
+ type: string
+ type: array
+ force_crypto_proposal:
+ type: string
+ local_identifier:
+ type: string
+ local_private_cert:
+ type: string
+ local_public_cert:
+ type: string
+ name:
+ type: string
+ pre_shared_key:
+ type: string
+ remote:
+ type: string
+ remote_identifier:
+ type: string
+ shared_ca:
+ type: string
+ type:
+ type: string
+ required:
+ - authentication_method
+ - connections
+ - crypto_proposal
+ - remote
+ type: object
+ status:
+ description: status subsource used for Sdewan rule CRDs
+ properties:
+ appliedGeneration:
+ format: int64
+ type: integer
+ appliedTime:
+ format: date-time
+ type: string
+ message:
+ type: string
+ state:
+ type: string
+ required:
+ - state
+ type: object
+ type: object
+ version: v1alpha1
+ versions:
+ - name: v1alpha1
+ served: true
+ storage: true
+status:
+ acceptedNames:
+ kind: ""
+ plural: ""
+ conditions: []
+ storedVersions: []
+---
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.2.5
- get
- patch
- update
+- apiGroups:
+ - batch.sdewan.akraino.org
+ resources:
+ - ipsechosts
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - batch.sdewan.akraino.org
+ resources:
+ - ipsechosts/status
+ verbs:
+ - get
+ - patch
+ - update
- apiGroups:
- batch.sdewan.akraino.org
resources:
- firewallrules
- firewallsnats
- firewalldnats
- - ipsecproposal
+ - ipsecproposals
+ - ipsechosts
- group: batch
kind: IpsecProposal
version: v1alpha1
+- group: batch
+ kind: IpsecHost
+ version: v1alpha1
version: "2"
return nil
}
-// +kubebuilder:webhook:path=/validate-sdewan-bucket-permission,mutating=false,failurePolicy=fail,groups="batch.sdewan.akraino.org",resources=mwan3policies;mwan3rules;firewallzones;firewallforwardings;firewallrules;firewallsnats;firewalldnats;ipsecproposal,verbs=create;update;delete,versions=v1alpha1,name=validate-sdewan-bucket.akraino.org
+// +kubebuilder:webhook:path=/validate-sdewan-bucket-permission,mutating=false,failurePolicy=fail,groups="batch.sdewan.akraino.org",resources=mwan3policies;mwan3rules;firewallzones;firewallforwardings;firewallrules;firewallsnats;firewalldnats;ipsecproposals;ipsechosts,verbs=create;update;delete,versions=v1alpha1,name=validate-sdewan-bucket.akraino.org
// bucketPermissionValidator validates Pods
type bucketPermissionValidator struct {
// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterroles;roles;rolebindings;clusterrolebindings,verbs=get;list;watch
-// bucketPermissionValidator admits a pod iff a specific annotation exists.
+// bucketPermissionValidator admits a pod if a specific annotation exists.
func (v *bucketPermissionValidator) Handle(ctx context.Context, req admission.Request) admission.Response {
if req.Kind.Group != "batch.sdewan.akraino.org" {
return admission.Errored(
obj = &FirewallDNAT{}
case "FirewallSNAT":
obj = &FirewallSNAT{}
+ case "IpsecProposal":
+ obj = &IpsecProposal{}
+ case "IpsecHost":
+ obj = &IpsecHost{}
default:
return admission.Errored(
http.StatusBadRequest,
--- /dev/null
+/*
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1alpha1
+
+import (
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+type Connection struct {
+ Name string `json:"name"`
+ ConnectionType string `json:"conn_type"`
+ Mode string `json:"mode"`
+ LocalSourceIp string `json:"local_sourceip,omitempty"`
+ LocalUpDown string `json:"local_updown,omitempty"`
+ LocalFirewall string `json:"local_firewall,omitempty"`
+ RemoteSubnet string `json:"remote_subnet,omitempty"`
+ RemoteSourceIp string `json:"remote_sourceip,omitempty"`
+ RemoteUpDown string `json:"remote_updown,omitempty"`
+ RemoteFirewall string `json:"remote_firewall,omitempty"`
+ CryptoProposal []string `json:"crypto_proposal,omitempty"`
+ Mark string `json:"mark,omitempty"`
+ IfId string `json:"if_id,omitempty"`
+}
+
+type IpsecHostSpec struct {
+ Name string `json:"name,omitempty"`
+ Type string `json:"type,omitempty"`
+ Remote string `json:"remote"`
+ AuthenticationMethod string `json:"authentication_method"`
+ CryptoProposal []string `json:"crypto_proposal"`
+ LocalIdentifier string `json:"local_identifier,omitempty"`
+ RemoteIdentifier string `json:"remote_identifier,omitempty"`
+ ForceCryptoProposal string `json:"force_crypto_proposal,omitempty"`
+ PresharedKey string `json:"pre_shared_key,omitempty"`
+ LocalPublicCert string `json:"local_public_cert,omitempty"`
+ LocalPrivateCert string `json:"local_private_cert,omitempty"`
+ SharedCA string `json:"shared_ca,omitempty"`
+ Connections []Connection `json:"connections"`
+}
+
+// +kubebuilder:object:root=true
+// +kubebuilder:subresource:status
+
+// IpsecHost is the Schema for the ipsechosts API
+type IpsecHost struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ObjectMeta `json:"metadata,omitempty"`
+
+ Spec IpsecHostSpec `json:"spec,omitempty"`
+ Status SdewanStatus `json:"status,omitempty"`
+}
+
+// +kubebuilder:object:root=true
+
+// IpsecHostList contains a list of IpsecHost
+type IpsecHostList struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ListMeta `json:"metadata,omitempty"`
+ Items []IpsecHost `json:"items"`
+}
+
+func init() {
+ SchemeBuilder.Register(&IpsecHost{}, &IpsecHostList{})
+}
return *out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Connection) DeepCopyInto(out *Connection) {
+ *out = *in
+ if in.CryptoProposal != nil {
+ in, out := &in.CryptoProposal, &out.CryptoProposal
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Connection.
+func (in *Connection) DeepCopy() *Connection {
+ if in == nil {
+ return nil
+ }
+ out := new(Connection)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FirewallDNAT) DeepCopyInto(out *FirewallDNAT) {
*out = *in
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *IpsecHost) DeepCopyInto(out *IpsecHost) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+ in.Spec.DeepCopyInto(&out.Spec)
+ in.Status.DeepCopyInto(&out.Status)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IpsecHost.
+func (in *IpsecHost) DeepCopy() *IpsecHost {
+ if in == nil {
+ return nil
+ }
+ out := new(IpsecHost)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *IpsecProposal) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return nil
}
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *IpsecHost) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IpsecProposalList) DeepCopyInto(out *IpsecProposalList) {
*out = *in
}
}
+func (in *IpsecHostList) DeepCopyInto(out *IpsecHostList) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ListMeta.DeepCopyInto(&out.ListMeta)
+ if in.Items != nil {
+ in, out := &in.Items, &out.Items
+ *out = make([]IpsecHost, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+}
+
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IpsecProposalList.
func (in *IpsecProposalList) DeepCopy() *IpsecProposalList {
if in == nil {
return out
}
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IpsecHostList.
+func (in *IpsecHostList) DeepCopy() *IpsecHostList {
+ if in == nil {
+ return nil
+ }
+ out := new(IpsecHostList)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *IpsecProposalList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return nil
}
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *IpsecHostList) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IpsecProposalSpec) DeepCopyInto(out *IpsecProposalSpec) {
*out = *in
return out
}
+func (in *IpsecHostSpec) DeepCopyInto(out *IpsecHostSpec) {
+ *out = *in
+ if in.CryptoProposal != nil {
+ in, out := &in.CryptoProposal, &out.CryptoProposal
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
+ if in.Connections != nil {
+ in, out := &in.Connections, &out.Connections
+ *out = make([]Connection, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IpsecHostSpec.
+func (in *IpsecHostSpec) DeepCopy() *IpsecHostSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(IpsecHostSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Mwan3Policy) DeepCopyInto(out *Mwan3Policy) {
*out = *in
--- /dev/null
+
+---
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.2.5
+ creationTimestamp: null
+ name: ipsechosts.batch.sdewan.akraino.org
+spec:
+ group: batch.sdewan.akraino.org
+ names:
+ kind: IpsecHost
+ listKind: IpsecHostList
+ plural: ipsechosts
+ singular: ipsechost
+ scope: Namespaced
+ subresources:
+ status: {}
+ validation:
+ openAPIV3Schema:
+ description: IpsecHost is the Schema for the ipsechosts API
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation
+ of an object. Servers should convert recognized schemas to the latest
+ internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this
+ object represents. Servers may infer this from the endpoint the client
+ submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ properties:
+ authentication_method:
+ type: string
+ connections:
+ items:
+ properties:
+ crypto_proposal:
+ items:
+ type: string
+ type: array
+ if_id:
+ type: string
+ local_firewall:
+ type: string
+ local_sourceip:
+ type: string
+ local_updown:
+ type: string
+ mark:
+ type: string
+ mode:
+ type: string
+ name:
+ type: string
+ remote_firewall:
+ type: string
+ remote_sourceip:
+ type: string
+ remote_subnet:
+ type: string
+ remote_updown:
+ type: string
+ type:
+ type: string
+ required:
+ - mode
+ - name
+ - type
+ type: object
+ type: array
+ crypto_proposal:
+ items:
+ type: string
+ type: array
+ force_crypto_proposal:
+ type: string
+ local_identifier:
+ type: string
+ local_private_cert:
+ type: string
+ local_public_cert:
+ type: string
+ name:
+ type: string
+ pre_shared_key:
+ type: string
+ remote:
+ type: string
+ remote_identifier:
+ type: string
+ shared_ca:
+ type: string
+ required:
+ - authentication_method
+ - connections
+ - crypto_proposal
+ - remote
+ type: object
+ status:
+ description: status subsource used for Sdewan rule CRDs
+ properties:
+ appliedGeneration:
+ format: int64
+ type: integer
+ appliedTime:
+ format: date-time
+ type: string
+ message:
+ type: string
+ state:
+ type: string
+ required:
+ - state
+ type: object
+ type: object
+ version: v1alpha1
+ versions:
+ - name: v1alpha1
+ served: true
+ storage: true
+status:
+ acceptedNames:
+ kind: ""
+ plural: ""
+ conditions: []
+ storedVersions: []
- bases/batch.sdewan.akraino.org_firewalldnats.yaml
- bases/batch.sdewan.akraino.org_firewallforwardings.yaml
- bases/batch.sdewan.akraino.org_ipsecproposals.yaml
+- bases/batch.sdewan.akraino.org_ipsechosts.yaml
# +kubebuilder:scaffold:crdkustomizeresource
patchesStrategicMerge:
#- patches/webhook_in_firewalldnats.yaml
#- patches/webhook_in_firewallforwardings.yaml
#- patches/webhook_in_ipsecproposals.yaml
+#- patches/webhook_in_ipsechosts.yaml
# +kubebuilder:scaffold:crdkustomizewebhookpatch
# [CERTMANAGER] To enable webhook, uncomment all the sections with [CERTMANAGER] prefix.
#- patches/cainjection_in_firewalldnats.yaml
#- patches/cainjection_in_firewallforwardings.yaml
#- patches/cainjection_in_ipsecproposals.yaml
+#- patches/cainjection_in_ipsechosts.yaml
# +kubebuilder:scaffold:crdkustomizecainjectionpatch
# the following config is for teaching kustomize how to do kustomization for CRDs.
--- /dev/null
+# The following patch adds a directive for certmanager to inject CA into the CRD
+# CRD conversion requires k8s 1.13 or later.
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
+ name: ipsechosts.batch.sdewan.akraino.org
--- /dev/null
+# The following patch enables conversion webhook for CRD
+# CRD conversion requires k8s 1.13 or later.
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: ipsechosts.batch.sdewan.akraino.org
+spec:
+ conversion:
+ strategy: Webhook
+ webhookClientConfig:
+ caBundle: Cg==
+ service:
+ namespace: system
+ name: webhook-service
+ path: /convert
- firewallrules
- firewallsnats
- firewallzones
+ - ipsechosts
+ - ipsecproposals
scope: '*'
sideEffects: Unknown
timeoutSeconds: 30
- get
- patch
- update
+- apiGroups:
+ - batch.sdewan.akraino.org
+ resources:
+ - ipsechosts
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - batch.sdewan.akraino.org
+ resources:
+ - ipsechosts/status
+ verbs:
+ - get
+ - patch
+ - update
- apiGroups:
- batch.sdewan.akraino.org
resources:
--- /dev/null
+apiVersion: batch.sdewan.akraino.org/v1alpha1
+kind: IpsecHost
+metadata:
+ name: ipsechost
+ namespace: default
+ labels:
+ sdewanPurpose: cnf1
+spec:
+ name: hostA
+ type: "VTI-based"
+ remote: 10.10.10.35
+ pre_shared_key: test_key
+ authentication_method: psk
+ local_identifier: host
+ remote_identifier: Hub
+ crypto_proposal:
+ - ipsecproposal
+ force_crypto_proposal: "0"
+ connections:
+ - name: connA
+ conn_type: tunnel
+ mode: start
+ mark: "42"
+ local_sourceip: "%config"
+ remote_subnet: 192.168.1.1/24,10.10.10.35/32
+ crypto_proposal:
+ - ipsecproposal
+
- firewallrules
- firewallsnats
- firewalldnats
- - ipsecproposal
+ - ipsecproposals
+ - ipsechosts
--- /dev/null
+/*
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package controllers
+
+import (
+ "context"
+ "reflect"
+
+ "github.com/go-logr/logr"
+ appsv1 "k8s.io/api/apps/v1"
+ "k8s.io/apimachinery/pkg/runtime"
+ ctrl "sigs.k8s.io/controller-runtime"
+ "sigs.k8s.io/controller-runtime/pkg/builder"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/predicate"
+
+ batchv1alpha1 "sdewan.akraino.org/sdewan/api/v1alpha1"
+ "sdewan.akraino.org/sdewan/openwrt"
+)
+
+var ipsecHostHandler = new(IpsecHostHandler)
+
+type IpsecHostHandler struct {
+}
+
+func (m *IpsecHostHandler) GetType() string {
+ return "IpsecHost"
+}
+
+func (m *IpsecHostHandler) GetName(instance runtime.Object) string {
+ host := instance.(*batchv1alpha1.IpsecHost)
+ return host.Name
+}
+
+func (m *IpsecHostHandler) GetFinalizer() string {
+ return "ipsec.host.finalizers.sdewan.akraino.org"
+}
+
+func (m *IpsecHostHandler) GetInstance(r client.Client, ctx context.Context, req ctrl.Request) (runtime.Object, error) {
+ instance := &batchv1alpha1.IpsecHost{}
+ err := r.Get(ctx, req.NamespacedName, instance)
+ return instance, err
+}
+
+func (m *IpsecHostHandler) Convert(instance runtime.Object, deployment appsv1.Deployment) (openwrt.IOpenWrtObject, error) {
+ host := instance.(*batchv1alpha1.IpsecHost)
+ numOfConn := len(host.Spec.Connections)
+ conn := host.Spec.Connections
+ openwrtConn := make([]openwrt.SdewanIpsecConnection, numOfConn)
+ for i := 0; i < numOfConn; i++ {
+ openwrtConn[i] = openwrt.SdewanIpsecConnection{
+ Name: conn[i].Name,
+ ConnType: conn[i].ConnectionType,
+ Mode: conn[i].Mode,
+ LocalSourceip: conn[i].LocalSourceIp,
+ LocalUpdown: conn[i].LocalUpDown,
+ LocalFirewall: conn[i].LocalFirewall,
+ RemoteSubnet: conn[i].RemoteSubnet,
+ RemoteSourceip: conn[i].RemoteSourceIp,
+ RemoteUpdown: conn[i].RemoteUpDown,
+ RemoteFirewall: conn[i].RemoteFirewall,
+ CryptoProposal: conn[i].CryptoProposal,
+ Mark: conn[i].Mark,
+ IfId: conn[i].IfId,
+ }
+ }
+ hostObject := openwrt.SdewanIpsecRemote{
+ Name: host.Name,
+ Gateway: host.Spec.Remote,
+ Type: host.Spec.Type,
+ AuthenticationMethod: host.Spec.AuthenticationMethod,
+ PreSharedKey: host.Spec.PresharedKey,
+ LocalIdentifier: host.Spec.LocalIdentifier,
+ RemoteIdentifier: host.Spec.RemoteIdentifier,
+ CryptoProposal: host.Spec.CryptoProposal,
+ ForceCryptoProposal: host.Spec.ForceCryptoProposal,
+ LocalPublicCert: host.Spec.LocalPublicCert,
+ LocalPrivateCert: host.Spec.LocalPrivateCert,
+ SharedCa: host.Spec.SharedCA,
+ Connections: openwrtConn,
+ }
+ return &hostObject, nil
+}
+
+func (m *IpsecHostHandler) IsEqual(instance1 openwrt.IOpenWrtObject, instance2 openwrt.IOpenWrtObject) bool {
+ host1 := instance1.(*openwrt.SdewanIpsecRemote)
+ host2 := instance2.(*openwrt.SdewanIpsecRemote)
+ return reflect.DeepEqual(*host1, *host2)
+}
+
+func (m *IpsecHostHandler) GetObject(clientInfo *openwrt.OpenwrtClientInfo, name string) (openwrt.IOpenWrtObject, error) {
+ openwrtClient := openwrt.GetOpenwrtClient(*clientInfo)
+ ipsec := openwrt.IpsecClient{OpenwrtClient: openwrtClient}
+ ret, err := ipsec.GetRemote(name)
+ return ret, err
+}
+
+func (m *IpsecHostHandler) CreateObject(clientInfo *openwrt.OpenwrtClientInfo, instance openwrt.IOpenWrtObject) (openwrt.IOpenWrtObject, error) {
+ openwrtClient := openwrt.GetOpenwrtClient(*clientInfo)
+ ipsec := openwrt.IpsecClient{OpenwrtClient: openwrtClient}
+ host := instance.(*openwrt.SdewanIpsecRemote)
+ return ipsec.CreateRemote(*host)
+}
+
+func (m *IpsecHostHandler) UpdateObject(clientInfo *openwrt.OpenwrtClientInfo, instance openwrt.IOpenWrtObject) (openwrt.IOpenWrtObject, error) {
+ openwrtClient := openwrt.GetOpenwrtClient(*clientInfo)
+ ipsec := openwrt.IpsecClient{OpenwrtClient: openwrtClient}
+ host := instance.(*openwrt.SdewanIpsecRemote)
+ return ipsec.UpdateRemote(*host)
+}
+
+func (m *IpsecHostHandler) DeleteObject(clientInfo *openwrt.OpenwrtClientInfo, name string) error {
+ openwrtClient := openwrt.GetOpenwrtClient(*clientInfo)
+ ipsec := openwrt.IpsecClient{OpenwrtClient: openwrtClient}
+ return ipsec.DeleteRemote(name)
+}
+
+func (m *IpsecHostHandler) Restart(clientInfo *openwrt.OpenwrtClientInfo) (bool, error) {
+ openwrtClient := openwrt.GetOpenwrtClient(*clientInfo)
+ service := openwrt.ServiceClient{OpenwrtClient: openwrtClient}
+ return service.ExecuteService("ipsec", "restart")
+}
+
+// IpsecHostReconciler reconciles a IpsecHost object
+type IpsecHostReconciler struct {
+ client.Client
+ Log logr.Logger
+ Scheme *runtime.Scheme
+}
+
+// +kubebuilder:rbac:groups=batch.sdewan.akraino.org,resources=ipsechosts,verbs=get;list;watch;create;update;patch;delete
+// +kubebuilder:rbac:groups=batch.sdewan.akraino.org,resources=ipsechosts/status,verbs=get;update;patch
+
+func (r *IpsecHostReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
+ return ProcessReconcile(r, r.Log, req, ipsecHostHandler)
+}
+
+func (r *IpsecHostReconciler) SetupWithManager(mgr ctrl.Manager) error {
+ ps := builder.WithPredicates(predicate.GenerationChangedPredicate{})
+ return ctrl.NewControllerManagedBy(mgr).
+ For(&batchv1alpha1.IpsecHost{}, ps).
+ Complete(r)
+}
err = batchv1alpha1.AddToScheme(scheme.Scheme)
Expect(err).NotTo(HaveOccurred())
+ err = batchv1alpha1.AddToScheme(scheme.Scheme)
+ Expect(err).NotTo(HaveOccurred())
+
// +kubebuilder:scaffold:scheme
k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
setupLog.Error(err, "unable to create controller", "controller", "FirewallForwarding")
os.Exit(1)
}
+
if err = (&controllers.IpsecProposalReconciler{
Client: mgr.GetClient(),
Log: ctrl.Log.WithName("controllers").WithName("IpsecProposal"),
setupLog.Error(err, "unable to create controller", "controller", "IpsecProposal")
os.Exit(1)
}
+
+ if err = (&controllers.IpsecHostReconciler{
+ Client: mgr.GetClient(),
+ Log: ctrl.Log.WithName("controllers").WithName("IpsecHost"),
+ Scheme: mgr.GetScheme(),
+ }).SetupWithManager(mgr); err != nil {
+ setupLog.Error(err, "unable to create controller", "controller", "IpsecHost")
+ os.Exit(1)
+ }
// +kubebuilder:scaffold:builder
setupLog.Info("starting manager")
return o.Name
}
-// Sites
+// Remotes
type SdewanIpsecConnection struct {
Name string `json:"name"`
- Type string `json:"type"`
+ ConnType string `json:"conn_type"`
Mode string `json:"mode"`
LocalSubnet string `json:"local_subnet"`
LocalNat string `json:"local_nat"`
RemoteUpdown string `json:"remote_updown"`
RemoteFirewall string `json:"remote_firewall"`
CryptoProposal []string `json:"crypto_proposal"`
+ Mark string `json:"mark"`
+ IfId string `json:"if_id"`
}
-type SdewanIpsecSite struct {
+type SdewanIpsecRemote struct {
Name string `json:"name"`
+ Type string `json:"type"`
Gateway string `json:"gateway"`
PreSharedKey string `json:"pre_shared_key"`
AuthenticationMethod string `json:"authentication_method"`
Connections []SdewanIpsecConnection `json:"connections"`
}
-type SdewanIpsecSites struct {
- Sites []SdewanIpsecSite `json:"sites"`
+type SdewanIpsecRemotes struct {
+ Remotes []SdewanIpsecRemote `json:"remotes"`
+}
+
+func (o *SdewanIpsecRemote) GetName() string {
+ return o.Name
}
// Proposal APIs
return &sdewanIpsecProposal, nil
}
-// Site APIs
-// get sites
-func (f *IpsecClient) GetSites() (*SdewanIpsecSites, error) {
+// Remote APIs
+// get remotes
+func (f *IpsecClient) GetRemotes() (*SdewanIpsecRemotes, error) {
var response string
var err error
- response, err = f.OpenwrtClient.Get(ipsecBaseURL + "sites")
+ response, err = f.OpenwrtClient.Get(ipsecBaseURL + "remotes")
if err != nil {
return nil, err
}
- var sdewanIpsecSites SdewanIpsecSites
- err = json.Unmarshal([]byte(response), &sdewanIpsecSites)
+ var sdewanIpsecRemotes SdewanIpsecRemotes
+ err = json.Unmarshal([]byte(response), &sdewanIpsecRemotes)
if err != nil {
return nil, err
}
- return &sdewanIpsecSites, nil
+ return &sdewanIpsecRemotes, nil
}
-// get site
-func (m *IpsecClient) GetSite(site string) (*SdewanIpsecSite, error) {
+// get remote
+func (m *IpsecClient) GetRemote(remote string) (*SdewanIpsecRemote, error) {
var response string
var err error
- response, err = m.OpenwrtClient.Get(ipsecBaseURL + "sites/" + site)
+ response, err = m.OpenwrtClient.Get(ipsecBaseURL + "remotes/" + remote)
if err != nil {
return nil, err
}
- var sdewanIpsecSite SdewanIpsecSite
- err = json.Unmarshal([]byte(response), &sdewanIpsecSite)
+ var sdewanIpsecRemote SdewanIpsecRemote
+ err = json.Unmarshal([]byte(response), &sdewanIpsecRemote)
if err != nil {
return nil, err
}
- return &sdewanIpsecSite, nil
+ return &sdewanIpsecRemote, nil
}
-// create site
-func (m *IpsecClient) CreateSite(site SdewanIpsecSite) (*SdewanIpsecSite, error) {
+// create remote
+func (m *IpsecClient) CreateRemote(remote SdewanIpsecRemote) (*SdewanIpsecRemote, error) {
var response string
var err error
- site_obj, _ := json.Marshal(site)
- response, err = m.OpenwrtClient.Post(ipsecBaseURL+"sites", string(site_obj))
+ remote_obj, _ := json.Marshal(remote)
+ response, err = m.OpenwrtClient.Post(ipsecBaseURL+"remotes", string(remote_obj))
if err != nil {
return nil, err
}
- var sdewanIpsecSite SdewanIpsecSite
- err = json.Unmarshal([]byte(response), &sdewanIpsecSite)
+ var sdewanIpsecRemote SdewanIpsecRemote
+ err = json.Unmarshal([]byte(response), &sdewanIpsecRemote)
if err != nil {
return nil, err
}
- return &sdewanIpsecSite, nil
+ return &sdewanIpsecRemote, nil
}
-// delete site
-func (m *IpsecClient) DeleteSite(site_name string) error {
- _, err := m.OpenwrtClient.Delete(ipsecBaseURL + "sites/" + site_name)
+// delete remote
+func (m *IpsecClient) DeleteRemote(remote_name string) error {
+ _, err := m.OpenwrtClient.Delete(ipsecBaseURL + "remotes/" + remote_name)
if err != nil {
return err
}
return nil
}
-// update site
-func (m *IpsecClient) UpdateSite(site SdewanIpsecSite) (*SdewanIpsecSite, error) {
+// update remote
+func (m *IpsecClient) UpdateRemote(remote SdewanIpsecRemote) (*SdewanIpsecRemote, error) {
var response string
var err error
- site_obj, _ := json.Marshal(site)
- site_name := site.Name
- response, err = m.OpenwrtClient.Put(ipsecBaseURL+"sites/"+site_name, string(site_obj))
+ remote_obj, _ := json.Marshal(remote)
+ remote_name := remote.Name
+ response, err = m.OpenwrtClient.Put(ipsecBaseURL+"remotes/"+remote_name, string(remote_obj))
if err != nil {
return nil, err
}
- var sdewanIpsecSite SdewanIpsecSite
- err = json.Unmarshal([]byte(response), &sdewanIpsecSite)
+ var sdewanIpsecRemote SdewanIpsecRemote
+ err = json.Unmarshal([]byte(response), &sdewanIpsecRemote)
if err != nil {
return nil, err
}
- return &sdewanIpsecSite, nil
+ return &sdewanIpsecRemote, nil
}