-
Notifications
You must be signed in to change notification settings - Fork 57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AV-203833: Initial commit for restricting fqdn #1520
Changes from all commits
33dc537
f606abb
815151e
05aadf4
7338f0e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,7 @@ import ( | |
"sync" | ||
|
||
"github.com/vmware/load-balancer-and-ingress-services-for-kubernetes/internal/lib" | ||
"github.com/vmware/load-balancer-and-ingress-services-for-kubernetes/internal/objects" | ||
akov1beta1 "github.com/vmware/load-balancer-and-ingress-services-for-kubernetes/pkg/apis/ako/v1beta1" | ||
|
||
pq "github.com/jupp0r/go-priority-queue" | ||
|
@@ -2186,8 +2187,17 @@ func (c *AviObjCache) AviObjVSCachePopulate(client *clients.AviClient, cloud str | |
if err := json.Unmarshal([]byte(svc_mdata_intf.(string)), | ||
&svc_mdata_obj); err != nil { | ||
utils.AviLog.Warnf("Error parsing service metadata during vs cache :%v", err) | ||
} else if lib.AKOControlConfig().GetAKOFQDNReusePolicy() == lib.FQDNReusePolicyStrict { | ||
// call this only when FQDN policy is strict | ||
hostToIngMapping := svc_mdata_obj.HostToNamespaceIngressName | ||
utils.AviLog.Debugf("HosttoIng mapping is %v", utils.Stringify(hostToIngMapping)) | ||
if hostToIngMapping != nil { | ||
// Now populate the map | ||
PopulateHostToIngMapping(hostToIngMapping) | ||
} | ||
} | ||
} | ||
|
||
var sni_child_collection []string | ||
vh_child, found := vs["vh_child_vs_uuid"] | ||
if found { | ||
|
@@ -2397,7 +2407,6 @@ func (c *AviObjCache) AviObjVSCachePopulate(client *clients.AviClient, cloud str | |
} | ||
c.VsCacheLocal.AviCacheAdd(k, &vsMetaObj) | ||
utils.AviLog.Debugf("Added VS cache key :%s", utils.Stringify(&vsMetaObj)) | ||
|
||
} | ||
} | ||
if resp["next"] != nil { | ||
|
@@ -2415,6 +2424,48 @@ func (c *AviObjCache) AviObjVSCachePopulate(client *clients.AviClient, cloud str | |
return nil | ||
} | ||
|
||
// Upfront populate mapping so that during FullSyncK8s, it will be used to assign ingresses/routes to appropriate hosts list. | ||
func PopulateHostToIngMapping(hostsToIng map[string][]string) { | ||
isRoute := false | ||
if utils.GetInformers().RouteInformer != nil { | ||
isRoute = true | ||
} | ||
var routeNamespaceName objects.RouteNamspaceName | ||
for host, ings := range hostsToIng { | ||
// append each ingress in active list | ||
utils.AviLog.Debugf("Populating Ingress mapping for host : %s", host) | ||
for _, ing := range ings { | ||
namespace, _, name := lib.ExtractTypeNameNamespace(ing) | ||
// Fetch ingress using clientset. From informer couldn't fetch it. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove stale comment |
||
if !isRoute { | ||
ingObj, err := utils.GetInformers().IngressInformer.Lister().Ingresses(namespace).Get(name) | ||
if err != nil { | ||
utils.AviLog.Errorf("Unable to retrieve the ingress %s/%s during populating host to ingress map in populate cache: %s", namespace, name, err) | ||
continue | ||
} | ||
routeNamespaceName = objects.RouteNamspaceName{ | ||
RouteNSRouteName: utils.Ingress + "/" + ing, | ||
CreationTime: ingObj.CreationTimestamp, | ||
} | ||
} else { | ||
routeObj, err := utils.GetInformers().RouteInformer.Lister().Routes(namespace).Get(name) | ||
if err != nil { | ||
utils.AviLog.Errorf("Unable to retrieve the ingress %s/%s during populating host to ingress map in populate cache: %s", namespace, name, err) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unable to retrieve the ingress -> Unable to retrieve the route |
||
continue | ||
} | ||
routeNamespaceName = objects.RouteNamspaceName{ | ||
RouteNSRouteName: utils.OshiftRoute + "/" + ing, | ||
CreationTime: routeObj.CreationTimestamp, | ||
} | ||
} | ||
|
||
// Add it to the structure | ||
objects.SharedUniqueNamespaceLister().UpdateHostnameToRoute(host, routeNamespaceName) | ||
|
||
} | ||
} | ||
} | ||
|
||
func (c *AviObjCache) AviObjOneVSCachePopulate(client *clients.AviClient, cloud string, vsName, tenant string) error { | ||
// This method should be called only from layer-3 during a retry. | ||
var rest_response interface{} | ||
|
@@ -2458,6 +2509,14 @@ func (c *AviObjCache) AviObjOneVSCachePopulate(client *clients.AviClient, cloud | |
if err := json.Unmarshal([]byte(svc_mdata_intf.(string)), | ||
&svc_mdata_obj); err != nil { | ||
utils.AviLog.Warnf("Error parsing service metadata during vs cache :%v", err) | ||
} else if lib.AKOControlConfig().GetAKOFQDNReusePolicy() == lib.FQDNReusePolicyStrict { | ||
// call this only when FQDN policy is strict | ||
hostToIngMapping := svc_mdata_obj.HostToNamespaceIngressName | ||
utils.AviLog.Debugf("HosttoIng mapping is %v", utils.Stringify(hostToIngMapping)) | ||
if hostToIngMapping != nil { | ||
// Now populate the map | ||
PopulateHostToIngMapping(hostToIngMapping) | ||
} | ||
} | ||
} | ||
var sni_child_collection []string | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -530,16 +530,15 @@ func (c *AviController) InitController(informers K8sinformers, registeredInforme | |
statusQueueParams := utils.WorkerQueue{NumWorkers: numGraphWorkers, WorkqueueName: utils.StatusQueue} | ||
graphQueue = utils.SharedWorkQueue(&ingestionQueueParams, &graphQueueParams, &slowRetryQParams, &fastRetryQParams, &statusQueueParams).GetQueueByName(utils.GraphLayer) | ||
|
||
c.addIndexers() | ||
c.Start(stopCh) | ||
err := PopulateCache() | ||
if err != nil { | ||
c.DisableSync = true | ||
utils.AviLog.Errorf("failed to populate cache, disabling sync") | ||
lib.ShutdownApi() | ||
} | ||
|
||
c.addIndexers() | ||
c.Start(stopCh) | ||
|
||
fullSyncInterval := os.Getenv(utils.FULL_SYNC_INTERVAL) | ||
interval, err := strconv.ParseInt(fullSyncInterval, 10, 64) | ||
|
||
|
@@ -1100,36 +1099,69 @@ func (c *AviController) FullSyncK8s(sync bool) error { | |
} | ||
//Ingress Section | ||
if utils.GetInformers().IngressInformer != nil { | ||
ingObjList := make([]*networkingv1.Ingress, 0) | ||
// create list of ingresses. | ||
for namespace := range acceptedNamespaces { | ||
ingObjs, err := utils.GetInformers().IngressInformer.Lister().Ingresses(namespace).List(labels.Set(nil).AsSelector()) | ||
if err != nil { | ||
utils.AviLog.Errorf("Unable to retrieve the ingresses during full sync: %s", err) | ||
} else { | ||
for _, ingObj := range ingObjs { | ||
key := utils.Ingress + "/" + utils.ObjKey(ingObj) | ||
meta, err := meta.Accessor(ingObj) | ||
if err == nil { | ||
resVer := meta.GetResourceVersion() | ||
objects.SharedResourceVerInstanceLister().Save(key, resVer) | ||
} | ||
utils.AviLog.Debugf("Dequeue for ingress key: %v", key) | ||
lib.IncrementQueueCounter(utils.ObjectIngestionLayer) | ||
nodes.DequeueIngestion(key, true) | ||
continue | ||
} | ||
ingObjList = append(ingObjList, ingObjs...) | ||
} | ||
// 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]) }) | ||
|
||
for _, ingObj := range ingObjList { | ||
key := utils.Ingress + "/" + ingObj.Namespace + "/" + ingObj.Name | ||
isValid := true | ||
|
||
if lib.AKOControlConfig().GetAKOFQDNReusePolicy() == lib.FQDNReusePolicyStrict { | ||
// get the hostnames in the ingress | ||
isValid, _ = isIngAcceptedWithFQDNRestriction(key, ingObj) | ||
} | ||
if isValid { | ||
meta, err := meta.Accessor(ingObj) | ||
if err == nil { | ||
resVer := meta.GetResourceVersion() | ||
objects.SharedResourceVerInstanceLister().Save(key, resVer) | ||
} | ||
utils.AviLog.Debugf("Dequeue for ingress key: %v", key) | ||
lib.IncrementQueueCounter(utils.ObjectIngestionLayer) | ||
nodes.DequeueIngestion(key, true) | ||
} else { | ||
utils.AviLog.Warnf("key: %s, msg: Ingress is not accepted due to FQDN restriction policy", key) | ||
} | ||
} | ||
// TODO: free ingObjList | ||
} | ||
//Route Section | ||
if utils.GetInformers().RouteInformer != nil { | ||
routeObjs, err := utils.GetInformers().RouteInformer.Lister().List(labels.Set(nil).AsSelector()) | ||
if err != nil { | ||
utils.AviLog.Errorf("Unable to retrieve the routes during full sync: %s", err) | ||
} else { | ||
for _, routeObj := range routeObjs { | ||
if _, ok := acceptedNamespaces[routeObj.Namespace]; !ok { | ||
continue | ||
routeObjList := make([]*routev1.Route, 0) | ||
for namespace := range acceptedNamespaces { | ||
routeObjs, err := utils.GetInformers().RouteInformer.Lister().Routes(namespace).List(labels.Set(nil).AsSelector()) | ||
if err != nil { | ||
utils.AviLog.Errorf("Unable to retrieve the ingresses during full sync: %s", err) | ||
continue | ||
} | ||
routeObjList = append(routeObjList, routeObjs...) | ||
} | ||
|
||
// sort on timestamp | ||
sort.Slice(routeObjList, func(i, j int) bool { return lib.RouteLessthan(routeObjList[i], routeObjList[j]) }) | ||
DixitAakash marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
for _, routeObj := range routeObjList { | ||
key := utils.OshiftRoute + "/" + utils.ObjKey(routeObj) | ||
pkoshtavmware marked this conversation as resolved.
Show resolved
Hide resolved
|
||
isValid := true | ||
|
||
if lib.AKOControlConfig().GetAKOFQDNReusePolicy() == lib.FQDNReusePolicyStrict { | ||
isValid = isRouteAcceptedWithFQDNRestriction(key, routeObj) | ||
if isValid { | ||
utils.AviLog.Debugf("Route %s is added to active list. Enqueuing it", key) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMO, we should log the routes/ingress which we are not adding to the active list. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
} | ||
key := utils.OshiftRoute + "/" + utils.ObjKey(routeObj) | ||
} | ||
if isValid { | ||
// Enqueue it only in case of valid | ||
meta, err := meta.Accessor(routeObj) | ||
if err == nil { | ||
resVer := meta.GetResourceVersion() | ||
|
@@ -1138,8 +1170,11 @@ func (c *AviController) FullSyncK8s(sync bool) error { | |
utils.AviLog.Debugf("Dequeue for route key: %v", key) | ||
lib.IncrementQueueCounter(utils.ObjectIngestionLayer) | ||
nodes.DequeueIngestion(key, true) | ||
} else { | ||
utils.AviLog.Warnf("key: %s, msg: Route is not accepted due to FQDN restriction policy", key) | ||
} | ||
} | ||
// TODO: Free routelist | ||
} | ||
if lib.UseServicesAPI() { | ||
gatewayObjs, err := lib.AKOControlConfig().SvcAPIInformers().GatewayInformer.Lister().Gateways(metav1.NamespaceAll).List(labels.Set(nil).AsSelector()) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of making Get calls using k8s client, should we start the informers before calling PopulateCache and use them here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Populate cache may fail and then AKO will error out from there. So my intention was to avoid initialising delay by keeping booting sequence same.
What is your thoughts on this?