Skip to content

Commit

Permalink
Functionality restriction to EVH only
Browse files Browse the repository at this point in the history
  • Loading branch information
akshayhavile committed Sep 8, 2024
1 parent 26e5c29 commit abd581d
Show file tree
Hide file tree
Showing 12 changed files with 304 additions and 353 deletions.
9 changes: 0 additions & 9 deletions internal/cache/cache_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -563,12 +563,3 @@ func (c *AviCache) ShallowCopy() map[interface{}]interface{} {
}
return newMap
}
func (c *AviCache) AviGetAllFQDNKeys() []string {
c.cache_lock.RLock()
defer c.cache_lock.RUnlock()
var keys []string
for key := range c.cache {
keys = append(keys, key.(string))
}
return keys
}
30 changes: 2 additions & 28 deletions internal/k8s/ako_init.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/cache"
servicesapi "sigs.k8s.io/service-apis/apis/v1alpha1"
Expand Down Expand Up @@ -1114,32 +1113,13 @@ func (c *AviController) FullSyncK8s(sync bool) error {
// sort the list as per the timestamp. Sorting logic can be kept irrespective of strict or non-strict policy
sort.Slice(ingObjList, func(i, j int) bool { return lib.IngressLessthan(ingObjList[i], ingObjList[j]) })

// TODO: Check this: There will be complication in handling ingress with multiple hosts as it can happen one hostname is accepted
// other is rejected.
for _, ingObj := range ingObjList {
key := ingObj.Namespace + "/" + ingObj.Name
isValid := true

// TODO: try to covert if loop to function
if lib.AKOFQDNReusePolicy() == lib.FQDNReusePolicyStrict {
routeNamespaceName := objects.RouteNamspaceName{
RouteNSRouteName: utils.Ingress + "/" + key,
CreationTime: ingObj.CreationTimestamp,
}
// get the hostnames in the ingress
hosts := sets.NewString()
for _, rule := range ingObj.Spec.Rules {
hosts.Insert(rule.Host)
}
isValid = false
for _, host := range hosts.List() {
isValid, _, _ = objects.SharedUniqueNamespaceLister().UpdateHostnameToRoute(host, routeNamespaceName)
// TODO: multihost needs to be handled in Graph layer
if isValid {
utils.AviLog.Debugf("Ingress %s is added to active list. Enqueuing it", key)
break
}
}
isValid = isIngAcceptedWithFQDNRestriction(key, ingObj)
}
if isValid {
key := utils.Ingress + "/" + key
Expand Down Expand Up @@ -1174,14 +1154,8 @@ func (c *AviController) FullSyncK8s(sync bool) error {
key := utils.OshiftRoute + "/" + utils.ObjKey(routeObj)
isValid := true

// TODO: try to covert if loop to function
if lib.AKOFQDNReusePolicy() == lib.FQDNReusePolicyStrict {
routeNamespaceName := objects.RouteNamspaceName{
RouteNSRouteName: utils.OshiftRoute + "/" + key,
CreationTime: routeObj.CreationTimestamp,
}

isValid, _, _ = objects.SharedUniqueNamespaceLister().UpdateHostnameToRoute(routeObj.Spec.Host, routeNamespaceName)
isValid = isRouteAcceptedWithFQDNRestriction(key, routeObj)
if isValid {
utils.AviLog.Debugf("Route %s is added to active list. Enqueuing it", key)
}
Expand Down
217 changes: 103 additions & 114 deletions internal/k8s/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,15 @@ func AddIngressFromNSToIngestionQueue(numWorkers uint32, c *AviController, names
for _, ingObj := range ingObjs {
key := utils.Ingress + "/" + utils.ObjKey(ingObj)
bkt := utils.Bkt(namespace, numWorkers)
c.workqueue[bkt].AddRateLimited(key)
lib.IncrementQueueCounter(utils.ObjectIngestionLayer)
utils.AviLog.Debugf("key: %s, msg: %s for namespace: %s", key, msg, namespace)
isAdded := true
if lib.AKOFQDNReusePolicy() == lib.FQDNReusePolicyStrict {
isAdded = isIngAcceptedWithFQDNRestriction(key, ingObj)
}
if isAdded {
c.workqueue[bkt].AddRateLimited(key)
lib.IncrementQueueCounter(utils.ObjectIngestionLayer)
utils.AviLog.Debugf("key: %s, msg: %s for namespace: %s", key, msg, namespace)
}
}
}

Expand All @@ -214,9 +220,15 @@ func AddRoutesFromNSToIngestionQueue(numWorkers uint32, c *AviController, namesp
for _, routeObj := range routeObjs {
key := utils.OshiftRoute + "/" + utils.ObjKey(routeObj)
bkt := utils.Bkt(namespace, numWorkers)
c.workqueue[bkt].AddRateLimited(key)
lib.IncrementQueueCounter(utils.ObjectIngestionLayer)
utils.AviLog.Debugf("key: %s, msg: %s for namespace: %s", key, msg, namespace)
isAdded := true
if lib.AKOFQDNReusePolicy() == lib.FQDNReusePolicyStrict {
isAdded = isRouteAcceptedWithFQDNRestriction(key, routeObj)
}
if isAdded {
c.workqueue[bkt].AddRateLimited(key)
lib.IncrementQueueCounter(utils.ObjectIngestionLayer)
utils.AviLog.Debugf("key: %s, msg: %s for namespace: %s", key, msg, namespace)
}
}
}

Expand Down Expand Up @@ -503,7 +515,6 @@ func AddNamespaceAnnotationEventHandler(numWorkers uint32, c *AviController) cac
return nsEventHandler
}

// TODO: Add same logic of restricting fqdn as that of ingress
func AddRouteEventHandler(numWorkers uint32, c *AviController) cache.ResourceEventHandler {
routeEventHandler := cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
Expand All @@ -522,13 +533,22 @@ func AddRouteEventHandler(numWorkers uint32, c *AviController) cache.ResourceEve
utils.AviLog.Debugf("key : %s, msg: same resource version returning", key)
return
}
bkt := utils.Bkt(namespace, numWorkers)
if !lib.HasValidBackends(route.Spec, route.Name, namespace, key) {
status.UpdateRouteStatusWithErrMsg(key, route.Name, namespace, lib.DuplicateBackends)
isAdded := true
if lib.AKOFQDNReusePolicy() == lib.FQDNReusePolicyStrict {
isAdded = isRouteAcceptedWithFQDNRestriction(key, route)
}
if isAdded {
bkt := utils.Bkt(namespace, numWorkers)
if !lib.HasValidBackends(route.Spec, route.Name, namespace, key) {
status.UpdateRouteStatusWithErrMsg(key, route.Name, namespace, lib.DuplicateBackends)
}
c.workqueue[bkt].AddRateLimited(key)
lib.IncrementQueueCounter(utils.ObjectIngestionLayer)
utils.AviLog.Debugf("key: %s, msg: ADD", key)
} else {
// update the status - already host claimed
status.UpdateRouteStatusWithErrMsg(key, route.Name, namespace, lib.HostAlreadyClaimed)
}
c.workqueue[bkt].AddRateLimited(key)
lib.IncrementQueueCounter(utils.ObjectIngestionLayer)
utils.AviLog.Debugf("key: %s, msg: ADD", key)
},
DeleteFunc: func(obj interface{}) {
if c.DisableSync {
Expand All @@ -553,6 +573,14 @@ func AddRouteEventHandler(numWorkers uint32, c *AviController) cache.ResourceEve
utils.AviLog.Debugf("key: %s, msg: Route delete event: Namespace: %s didn't qualify filter. Not deleting route", key, namespace)
return
}

if lib.AKOFQDNReusePolicy() == lib.FQDNReusePolicyStrict {
routeNamespaceName := objects.RouteNamspaceName{
RouteNSRouteName: key,
CreationTime: route.CreationTimestamp,
}
objects.SharedUniqueNamespaceLister().DeleteHostnameToRoute(route.Spec.Host, routeNamespaceName)
}
bkt := utils.Bkt(namespace, numWorkers)
c.workqueue[bkt].AddRateLimited(key)
lib.IncrementQueueCounter(utils.ObjectIngestionLayer)
Expand All @@ -576,9 +604,28 @@ func AddRouteEventHandler(numWorkers uint32, c *AviController) cache.ResourceEve
if !lib.HasValidBackends(newRoute.Spec, newRoute.Name, namespace, key) {
status.UpdateRouteStatusWithErrMsg(key, newRoute.Name, namespace, lib.DuplicateBackends)
}
c.workqueue[bkt].AddRateLimited(key)
lib.IncrementQueueCounter(utils.ObjectIngestionLayer)
utils.AviLog.Debugf("key: %s, msg: UPDATE", key)
if oldRoute.Spec.Host == newRoute.Spec.Host {
// same hosts
isAccepted := isRouteAcceptedWithFQDNRestriction(key, newRoute)
if isAccepted {
c.workqueue[bkt].AddRateLimited(key)
lib.IncrementQueueCounter(utils.ObjectIngestionLayer)
utils.AviLog.Debugf("key: %s, msg: UPDATE", key)
}
} else {
isOldAccepted := isRouteAcceptedWithFQDNRestriction(key, oldRoute)
isNewAccepted := isRouteAcceptedWithFQDNRestriction(key, newRoute)
if isOldAccepted || isNewAccepted {
c.workqueue[bkt].AddRateLimited(key)
lib.IncrementQueueCounter(utils.ObjectIngestionLayer)
utils.AviLog.Debugf("key: %s, msg: UPDATE", key)
} else {
// set status
// update the status - already host claimed
status.UpdateRouteStatusWithErrMsg(key, newRoute.Name, namespace, lib.HostAlreadyClaimed)
}

}
}
},
}
Expand Down Expand Up @@ -1256,30 +1303,14 @@ func (c *AviController) SetupEventHandlers(k8sinfo K8sinformers) {
bkt := utils.Bkt(namespace, numWorkers)
isAdded := true
if lib.AKOFQDNReusePolicy() == lib.FQDNReusePolicyStrict {
routeNamespaceName := objects.RouteNamspaceName{
RouteNSRouteName: key,
CreationTime: ingress.CreationTimestamp,
}
ingHosts := sets.NewString()
for _, rule := range ingress.Spec.Rules {
ingHosts.Insert(rule.Host)
}
// TODO: handle case of Ingress with multiple hostnames. Current behaviour if one of fqdn is false, not added.
isAdded := false
for _, host := range ingHosts.List() {
isAdded, _, _ = objects.SharedUniqueNamespaceLister().UpdateHostnameToRoute(host, routeNamespaceName)
if !isAdded {
break
}
}
isAdded = isIngAcceptedWithFQDNRestriction(key, ingress)
}
if isAdded {
c.workqueue[bkt].AddRateLimited(key)
lib.IncrementQueueCounter(utils.ObjectIngestionLayer)
utils.AviLog.Debugf("key: %s, msg: ADD", key)
} else {
utils.AviLog.Warnf("key: %s, msg: Ingress is not added due to conflict in hostname", key)
// TODO: set status here.
}

},
Expand Down Expand Up @@ -1316,7 +1347,6 @@ func (c *AviController) SetupEventHandlers(k8sinfo K8sinformers) {
// Add validation here
bkt := utils.Bkt(namespace, numWorkers)

var addedKeys []string
if lib.AKOFQDNReusePolicy() == lib.FQDNReusePolicyStrict {
routeNamespaceName := objects.RouteNamspaceName{
RouteNSRouteName: key,
Expand All @@ -1327,24 +1357,14 @@ func (c *AviController) SetupEventHandlers(k8sinfo K8sinformers) {
ingHosts.Insert(rule.Host)
}
for _, host := range ingHosts.List() {
// deletion of route, may result in adding ingresses from other namespace of same fqdn
addedRoutes, _ := objects.SharedUniqueNamespaceLister().DeleteHostnameToRoute(host, routeNamespaceName)
if len(addedRoutes) != 0 {
addedKeys = append(addedKeys, addedRoutes...)
}
objects.SharedUniqueNamespaceLister().DeleteHostnameToRoute(host, routeNamespaceName)
}
}

lib.IncrementQueueCounter(utils.ObjectIngestionLayer)
utils.AviLog.Debugf("key: %s, msg: DELETE", key)
// This will enqueue key irrespective of model present or not. Can be optimized.
c.workqueue[bkt].AddRateLimited(key)
// Now add the keys
for _, key := range addedKeys {
c.workqueue[bkt].AddRateLimited(key)
lib.IncrementQueueCounter(utils.ObjectIngestionLayer)
utils.AviLog.Debugf("key: %s, msg: ADD", key)
}

},
UpdateFunc: func(old, cur interface{}) {
Expand All @@ -1363,79 +1383,16 @@ func (c *AviController) SetupEventHandlers(k8sinfo K8sinformers) {
bkt := utils.Bkt(namespace, numWorkers)

if lib.AKOFQDNReusePolicy() == lib.FQDNReusePolicyStrict {
oldIngHostNames := sets.NewString()
newIngHostNames := sets.NewString()
for _, rule := range oldobj.Spec.Rules {
oldIngHostNames.Insert(rule.Host)
}
for _, rule := range ingress.Spec.Rules {
newIngHostNames.Insert(rule.Host)
}
hostsToAdd := newIngHostNames.Difference(oldIngHostNames)
hostsToDelete := oldIngHostNames.Difference(newIngHostNames)
if hostsToAdd.Len() == 0 && hostsToDelete.Len() == 0 {
// that means there is no change in hosts
oldIngAccepted := isIngAcceptedWithFQDNRestriction(key, oldobj)
newIngAccepted := isIngAcceptedWithFQDNRestriction(key, ingress)
if oldIngAccepted || newIngAccepted {
// oldIng or newIng accepted, we should enqueue
c.workqueue[bkt].AddRateLimited(key)
lib.IncrementQueueCounter(utils.ObjectIngestionLayer)
utils.AviLog.Debugf("key: %s, msg: UPDATE", key)
} else {
// TODO: Following logic can be turned into function
routeNamespaceName := objects.RouteNamspaceName{
RouteNSRouteName: key,
CreationTime: ingress.CreationTimestamp,
}
if hostsToAdd.Len() != 0 {
// new FQDNs are there
// so now we need to update it against given ingress
var addedKeys []string
var deletedKeys []string

for _, host := range hostsToAdd.List() {
flag, addedRoutes, deletedRoutes := objects.SharedUniqueNamespaceLister().UpdateHostnameToRoute(host, routeNamespaceName)
if flag {
// If true, this means route has to be added
addedKeys = append(addedKeys, key)
}
if len(addedRoutes) != 0 {
addedKeys = append(addedKeys, addedRoutes...)
}
if len(deletedRoutes) != 0 {
deletedKeys = append(deletedKeys, deletedRoutes...)
}
}
uniqueAddKeys := sets.NewString(addedKeys...)
for _, key := range uniqueAddKeys.List() {
c.workqueue[bkt].AddRateLimited(key)
lib.IncrementQueueCounter(utils.ObjectIngestionLayer)
utils.AviLog.Debugf("key: %s, msg: UPDATE", key)
}
// This logic was added as part of timestamp based approach.
// With approach being, keep fqdn to namespace whoever claims first, this might not run
uniqueDeleteKeys := sets.NewString(deletedKeys...)
for _, key := range uniqueDeleteKeys.List() {
c.workqueue[bkt].AddRateLimited(key)
lib.IncrementQueueCounter(utils.ObjectIngestionLayer)
utils.AviLog.Debugf("key: %s, msg: DELETE", key)
}

}
// TODO: Check whether this is unnecessary
if hostsToDelete.Len() != 0 {
var addedKeys []string
for _, host := range hostsToDelete.List() {
addedRoutes, _ := objects.SharedUniqueNamespaceLister().DeleteHostnameToRoute(host, routeNamespaceName)
if len(addedRoutes) != 0 {
addedKeys = append(addedKeys, addedRoutes...)
}
}
// Now add the keys
uniqueAddKeys := sets.NewString(addedKeys...)
for _, key := range uniqueAddKeys.List() {
c.workqueue[bkt].AddRateLimited(key)
lib.IncrementQueueCounter(utils.ObjectIngestionLayer)
utils.AviLog.Debugf("key: %s, msg: ADD", key)
}
}
} else {
utils.AviLog.Warnf("key: %s, msg: Ingress is not added due to conflict in hostname", key)
}

} else {
Expand Down Expand Up @@ -1809,3 +1766,35 @@ func (c *AviController) Run(stopCh <-chan struct{}) error {
func (c *AviController) GetValidator() Validator {
return NewValidator()
}
func isIngAcceptedWithFQDNRestriction(key string, ingress *networkingv1.Ingress) bool {
routeNamespaceName := objects.RouteNamspaceName{
RouteNSRouteName: key,
CreationTime: ingress.CreationTimestamp,
}
ingHosts := sets.NewString()
for _, rule := range ingress.Spec.Rules {
ingHosts.Insert(rule.Host)
}
// Current behaviour if one of fqdn is false, not added.
isAdded := false
for _, host := range ingHosts.List() {
isAdded, _, _ = objects.SharedUniqueNamespaceLister().UpdateHostnameToRoute(host, routeNamespaceName)
if !isAdded {
utils.AviLog.Warnf("key:%s, msg: ingress is not accepted as host %s is already claimed", key, host)
err_msg := fmt.Sprintf("Host %s already claimed", host)
lib.AKOControlConfig().IngressEventf(ingress.ObjectMeta, corev1.EventTypeWarning, lib.IngressUpdateEvent, err_msg)
break
}
}
return isAdded
}

func isRouteAcceptedWithFQDNRestriction(key string, route *routev1.Route) bool {
routeNamespaceName := objects.RouteNamspaceName{
RouteNSRouteName: key,
CreationTime: route.CreationTimestamp,
}
isAdded := false
isAdded, _, _ = objects.SharedUniqueNamespaceLister().UpdateHostnameToRoute(route.Spec.Host, routeNamespaceName)
return isAdded
}
Loading

0 comments on commit abd581d

Please sign in to comment.