Skip to content

Commit

Permalink
Release 2.1.0 (#74)
Browse files Browse the repository at this point in the history
Bug Fixes:
- Proper tenant selection for on-demand created L4LB resources whose backends are from the nested subnet.
New Features:
- Added option to set the default Tenant for L4LB resources. It's useful for situations when there is a need to choose from which tenant the L4LB frontend IP Address should be selected.
  • Loading branch information
pogossian authored Dec 22, 2022
1 parent c5bab8c commit c3112c7
Show file tree
Hide file tree
Showing 18 changed files with 132 additions and 99 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ KUSTOMIZE = $(shell pwd)/bin/kustomize
kustomize: ## Download kustomize locally if necessary.
$(call go-get-tool,$(KUSTOMIZE),sigs.k8s.io/kustomize/kustomize/[email protected])

# go-get-tool will 'go get' any package $2 and install it to $1.
# go-get-tool will 'go install' any package $2 and install it to $1.
PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST))))
define go-get-tool
@[ -f $(1) ] || { \
Expand All @@ -97,7 +97,7 @@ TMP_DIR=$$(mktemp -d) ;\
cd $$TMP_DIR ;\
go mod init tmp ;\
echo "Downloading $(2)" ;\
GOBIN=$(PROJECT_DIR)/bin go get $(2) ;\
GOBIN=$(PROJECT_DIR)/bin go install $(2) ;\
rm -rf $$TMP_DIR ;\
}
endef
Expand Down
87 changes: 53 additions & 34 deletions calicowatcher/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import (

"github.com/go-logr/logr"
"github.com/netrisai/netris-operator/api/v1alpha1"
k8sv1alpha1 "github.com/netrisai/netris-operator/api/v1alpha1"
"github.com/netrisai/netris-operator/calicowatcher/calico"
"github.com/netrisai/netris-operator/configloader"
"github.com/netrisai/netris-operator/netrisstorage"
Expand Down Expand Up @@ -70,8 +69,8 @@ type Watcher struct {

type data struct {
deleteMode bool
generatedBGPs []*k8sv1alpha1.BGP
bgpList []*k8sv1alpha1.BGP
generatedBGPs []*v1alpha1.BGP
bgpList []*v1alpha1.BGP
bgpConfs []*calico.BGPConfiguration

nodesMap map[string]*nodeIP
Expand All @@ -98,7 +97,7 @@ type Options struct {
// NewWatcher is the main initialization function.
func NewWatcher(nStorage *netrisstorage.Storage, mgr manager.Manager, options Options) (*Watcher, error) {
if nStorage == nil {
return nil, fmt.Errorf("Please provide NStorage")
return nil, fmt.Errorf("please provide NStorage")
}

watcher := &Watcher{
Expand Down Expand Up @@ -170,7 +169,7 @@ func (w *Watcher) Start() {
case <-w.stop:
ticker.Stop()
close(w.stop)
break
return
}
}
}
Expand Down Expand Up @@ -347,7 +346,7 @@ func (w *Watcher) deleteProcess() error {
return err
}

w.data.generatedBGPs = []*k8sv1alpha1.BGP{}
w.data.generatedBGPs = []*v1alpha1.BGP{}

debugLogger.Info("Geting BGPs from k8s", "deleteMode", w.data.deleteMode)
bgps, err := w.getBGPs()
Expand Down Expand Up @@ -431,22 +430,29 @@ func (w *Watcher) updateBGPConfMesh(enabled bool) error {
}

func (w *Watcher) generateBGPs() error {
generatedBGPs := []*k8sv1alpha1.BGP{}
generatedBGPs := []*v1alpha1.BGP{}

nameReg, _ := regexp.Compile("[^a-z0-9.]+")
for name, node := range w.data.nodesMap {
asn, err := strconv.Atoi(node.ASN)
if err != nil {
return err
}
PrefixListInboundList := []string{fmt.Sprintf("permit %s/%d", node.IPIP, w.data.blockSize)}

// Get the network address using node IP
_, ipipNetAddr, err := net.ParseCIDR(fmt.Sprintf("%s/%d", node.IPIP, w.data.blockSize))
if err != nil {
return fmt.Errorf("node ip: %s", err)
}

PrefixListInboundList := []string{fmt.Sprintf("permit %s", ipipNetAddr.String())}
for _, cidr := range w.data.serviceCIDRs {
PrefixListInboundList = append(PrefixListInboundList, fmt.Sprintf("permit %s le %d", cidr, 32))
}

name := fmt.Sprintf("%s-%s", name, strings.Split(node.IP, "/")[0])

bgp := &k8sv1alpha1.BGP{
bgp := &v1alpha1.BGP{
ObjectMeta: metav1.ObjectMeta{
Name: nameReg.ReplaceAllString(name, "-"),
Namespace: "default",
Expand All @@ -455,7 +461,7 @@ func (w *Watcher) generateBGPs() error {
Kind: "BGP",
APIVersion: "k8s.netris.ai/v1alpha1",
},
Spec: k8sv1alpha1.BGPSpec{
Spec: v1alpha1.BGPSpec{
Site: w.data.site.Name,
NeighborAS: asn,
Hardware: w.data.switchName,
Expand All @@ -468,7 +474,7 @@ func (w *Watcher) generateBGPs() error {
PrefixListInbound: PrefixListInboundList,
PrefixListOutbound: []string{
"permit 0.0.0.0/0",
fmt.Sprintf("deny %s/%d", node.IPIP, w.data.blockSize),
fmt.Sprintf("deny %s", ipipNetAddr.String()),
fmt.Sprintf("permit %s le %d", w.data.clusterCIDR, w.data.blockSize),
},
},
Expand All @@ -483,7 +489,7 @@ func (w *Watcher) generateBGPs() error {
return nil
}

func (w *Watcher) createBGPs(BGPs []*k8sv1alpha1.BGP) []error {
func (w *Watcher) createBGPs(BGPs []*v1alpha1.BGP) []error {
var errors []error
for _, bgp := range BGPs {
if err := w.createBGP(bgp); err != nil {
Expand All @@ -493,13 +499,13 @@ func (w *Watcher) createBGPs(BGPs []*k8sv1alpha1.BGP) []error {
return errors
}

func (w *Watcher) createBGP(bgp *k8sv1alpha1.BGP) error {
func (w *Watcher) createBGP(bgp *v1alpha1.BGP) error {
ctx, cancel := context.WithTimeout(cntxt, contextTimeout)
defer cancel()
return w.client.Create(ctx, bgp.DeepCopyObject(), &client.CreateOptions{})
}

func (w *Watcher) updateBGPs(BGPs []*k8sv1alpha1.BGP) []error {
func (w *Watcher) updateBGPs(BGPs []*v1alpha1.BGP) []error {
var errors []error
for _, bgp := range BGPs {
if err := w.updateBGP(bgp); err != nil {
Expand All @@ -509,13 +515,13 @@ func (w *Watcher) updateBGPs(BGPs []*k8sv1alpha1.BGP) []error {
return errors
}

func (w *Watcher) updateBGP(bgp *k8sv1alpha1.BGP) error {
func (w *Watcher) updateBGP(bgp *v1alpha1.BGP) error {
ctx, cancel := context.WithTimeout(cntxt, contextTimeout)
defer cancel()
return w.client.Update(ctx, bgp.DeepCopyObject(), &client.UpdateOptions{})
}

func (w *Watcher) deleteBGPs(BGPs []*k8sv1alpha1.BGP) []error {
func (w *Watcher) deleteBGPs(BGPs []*v1alpha1.BGP) []error {
var errors []error
for _, bgp := range BGPs {
if err := w.deleteBGP(bgp); err != nil {
Expand All @@ -525,19 +531,19 @@ func (w *Watcher) deleteBGPs(BGPs []*k8sv1alpha1.BGP) []error {
return errors
}

func (w *Watcher) deleteBGP(bgp *k8sv1alpha1.BGP) error {
func (w *Watcher) deleteBGP(bgp *v1alpha1.BGP) error {
ctx, cancel := context.WithTimeout(cntxt, contextTimeout)
defer cancel()
return w.client.Delete(ctx, bgp.DeepCopyObject(), &client.DeleteAllOfOptions{})
}

func (w *Watcher) compareBGPs() ([]*k8sv1alpha1.BGP, []*k8sv1alpha1.BGP, []*k8sv1alpha1.BGP) {
genBGPsMap := make(map[string]*k8sv1alpha1.BGP)
BGPsMap := make(map[string]*k8sv1alpha1.BGP)
func (w *Watcher) compareBGPs() ([]*v1alpha1.BGP, []*v1alpha1.BGP, []*v1alpha1.BGP) {
genBGPsMap := make(map[string]*v1alpha1.BGP)
BGPsMap := make(map[string]*v1alpha1.BGP)

bgpsForCreate := []*k8sv1alpha1.BGP{}
bgpsForDelete := []*k8sv1alpha1.BGP{}
bgpsForUpdate := []*k8sv1alpha1.BGP{}
bgpsForCreate := []*v1alpha1.BGP{}
bgpsForDelete := []*v1alpha1.BGP{}
bgpsForUpdate := []*v1alpha1.BGP{}

for _, bgp := range w.data.generatedBGPs {
genBGPsMap[bgp.Name] = bgp
Expand Down Expand Up @@ -568,10 +574,10 @@ func (w *Watcher) compareBGPs() ([]*k8sv1alpha1.BGP, []*k8sv1alpha1.BGP, []*k8sv
return bgpsForCreate, bgpsForDelete, bgpsForUpdate
}

func (w *Watcher) getBGPs() (*k8sv1alpha1.BGPList, error) {
func (w *Watcher) getBGPs() (*v1alpha1.BGPList, error) {
ctx, cancel := context.WithTimeout(cntxt, contextTimeout)
defer cancel()
bgps := &k8sv1alpha1.BGPList{}
bgps := &v1alpha1.BGPList{}
err := w.client.List(ctx, bgps, &client.ListOptions{})
if err != nil {
return nil, err
Expand Down Expand Up @@ -605,7 +611,7 @@ func (w *Watcher) getNodes() error {
}

if len(nodes.Items) == 0 {
return fmt.Errorf("Nodes are missing")
return fmt.Errorf("nodes are missing")
}
w.data.nodes = nodes
return nil
Expand Down Expand Up @@ -716,7 +722,7 @@ func (w *Watcher) nodesProcessing() error {
asn := ""

if _, ok := anns["projectcalico.org/ASNumber"]; !ok {
return fmt.Errorf("Couldn't get as number for node %s", node.Name)
return fmt.Errorf("couldn't get as number for node %s", node.Name)
}

asn = anns["projectcalico.org/ASNumber"]
Expand All @@ -734,17 +740,30 @@ func (w *Watcher) nodesProcessing() error {
}

if siteName == "" {
id, gateway, err := w.findSiteByIP(ip)
sbnt, err := findIPAMByIP(ip, w.NStorage.SubnetsStorage.GetAll())
if err != nil {
fmt.Println(err)
continue
}

_, ipNet, err := net.ParseCIDR(sbnt.Prefix)
if err != nil {
fmt.Println(err)
continue
}

subnet = ipNet.String()
id := 0

if len(sbnt.Sites) > 0 {
id = sbnt.Sites[0].ID
}

var ok bool
if site, ok = w.NStorage.SitesStorage.FindByID(id); ok {
siteName = site.Name
}
subnet = gateway
if vn, ok := w.NStorage.VNetStorage.FindByGateway(gateway); ok {
if vn, ok := w.NStorage.VNetStorage.FindByGateway(subnet); ok {
vnet = vn
}
}
Expand All @@ -753,14 +772,14 @@ func (w *Watcher) nodesProcessing() error {
}

if siteName == "" {
return fmt.Errorf("Couldn't find site")
return fmt.Errorf("couldn't find site")
}

if vnet == nil {
return fmt.Errorf("Couldn't find vnet")
return fmt.Errorf("couldn't find vnet")
}
if vnet.ID == 0 {
return fmt.Errorf("Couldn't find vnet")
return fmt.Errorf("couldn't find vnet")
}

vnetName = vnet.Name
Expand Down Expand Up @@ -816,7 +835,7 @@ func (w *Watcher) validateASNRange(asns string) (int, int, error) {
return a, b, nil
}

// patchStringValue specifies a patch operation for a string.
// patchStringValue specifies a patch operation for a string.
type patchStringValue struct {
Op string `json:"op"`
Path string `json:"path"`
Expand Down
29 changes: 16 additions & 13 deletions calicowatcher/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,27 +23,30 @@ import (
"github.com/netrisai/netriswebapi/v2/types/ipam"
)

func (w *Watcher) findSiteByIP(ip string) (int, string, error) {
siteID := 0
subnets := w.NStorage.SubnetsStorage.GetAll()

subnetChilds := []*ipam.IPAM{}
func findIPAMByIP(ip string, subnets []*ipam.IPAM) (*ipam.IPAM, error) {
for _, subnet := range subnets {
subnetChilds = append(subnetChilds, subnet.Children...)
}

for _, subnet := range subnetChilds {
ipAddr := net.ParseIP(ip)
_, ipNet, err := net.ParseCIDR(subnet.Prefix)
if err != nil {
return siteID, "", err
return nil, err
}

if ipNet.Contains(ipAddr) {
if len(subnet.Sites) > 0 {
return subnet.Sites[0].ID, ipNet.String(), nil
if len(subnet.Children) > 0 {
ip, err := findIPAMByIP(ip, subnet.Children)
if ip != nil {
return ip, err
}
}

return subnet, nil

}
}

return siteID, "", fmt.Errorf("There are no sites for specified IP address %s", ip)
return nil, fmt.Errorf("there are no subnet for specified IP address %s", ip)
}

func FindIPAMByIP(ip string, subnets []*ipam.IPAM) (*ipam.IPAM, error) {
return findIPAMByIP(ip, subnets)
}
2 changes: 2 additions & 0 deletions config/manager/custom-env.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,5 @@ spec:
value: "15"
- name: NOPERATOR_CALICO_ASN_RANGE
value: "4230000000-4239999999"
- name: NOPERATOR_L4LB_TENANT
value: ""
1 change: 1 addition & 0 deletions configloader/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ type config struct {
LogDevMode bool `yaml:"logdevmode" envconfig:"NOPERATOR_DEV_MODE"`
RequeueInterval int `yaml:"requeueinterval" envconfig:"NOPERATOR_REQUEUE_INTERVAL"`
CalicoASNRange string `yaml:"calicoasnrange" envconfig:"NOPERATOR_CALICO_ASN_RANGE"`
L4lbTenant string `yaml:"l4lbtenant" envconfig:"NOPERATOR_L4LB_TENANT"`
}

type controller struct {
Expand Down
1 change: 1 addition & 0 deletions configloader/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ controller:
# logdevmode: false # overwrite env: NOPERATOR_DEV_MODE
# requeueinterval: 15 # overwrite env: NOPERATOR_REQUEUE_INTERVAL
# calicoasnrange: 4230000000-4239999999 # overwrite env: NOPERATOR_CALICO_ASN_RANGE
# l4lbtenant: # overwrite env: NOPERATOR_L4LB_TENANT
9 changes: 5 additions & 4 deletions controllers/l4lb_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@ import (
// L4LBReconciler reconciles a L4LB object
type L4LBReconciler struct {
client.Client
Log logr.Logger
Scheme *runtime.Scheme
Cred *api.Clientset
NStorage *netrisstorage.Storage
Log logr.Logger
Scheme *runtime.Scheme
Cred *api.Clientset
NStorage *netrisstorage.Storage
L4LBTenant string
}

// +kubebuilder:rbac:groups=k8s.netris.ai,resources=l4lbs,verbs=get;list;watch;create;update;patch;delete
Expand Down
14 changes: 10 additions & 4 deletions controllers/l4lb_translations.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"strings"

k8sv1alpha1 "github.com/netrisai/netris-operator/api/v1alpha1"
"github.com/netrisai/netris-operator/calicowatcher"
"github.com/netrisai/netriswebapi/v2/types/ipam"
"github.com/netrisai/netriswebapi/v2/types/l4lb"
"github.com/r3labs/diff/v2"
Expand Down Expand Up @@ -58,11 +59,16 @@ func (r *L4LBReconciler) L4LBToL4LBMeta(l4lb *k8sv1alpha1.L4LB) (*k8sv1alpha1.L4
}

if l4lb.Spec.OwnerTenant == "" {
tenantid, err := r.findTenantByIP(ipForTenant)
if err != nil {
return nil, err
if r.L4LBTenant != "" {
l4lb.Spec.OwnerTenant = r.L4LBTenant
} else {
subnet, err := calicowatcher.FindIPAMByIP(ipForTenant, r.NStorage.SubnetsStorage.GetAll())
if err != nil {
return nil, err
}

tenantID = subnet.Tenant.ID
}
tenantID = tenantid
}

if tenantID == 0 {
Expand Down
4 changes: 2 additions & 2 deletions deploy/charts/netris-operator/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 1.0.1
version: 1.1.0

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
appVersion: v2.0.1
appVersion: v2.1.0
home: https://github.com/netrisai/netris-operator
icon: https://www.netris.ai/wp-content/uploads/2021/01/logo-300.png # [todo] Change url to permalink
keywords:
Expand Down
Loading

0 comments on commit c3112c7

Please sign in to comment.