Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
712 changes: 712 additions & 0 deletions npm/pkg/controlplane/controllers/v2/nameSpaceController_test.go

Large diffs are not rendered by default.

85 changes: 42 additions & 43 deletions npm/pkg/controlplane/controllers/v2/namespacecontroller.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ func (nsc *NamespaceController) needSync(obj interface{}, event string) (string,
var err error
if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil {
utilruntime.HandleError(err)
metrics.SendErrorLogAndMetric(util.NSID, "[NAMESPACE %s EVENT] Error: NamespaceKey is empty for %s namespace", event, util.GetNSNameWithPrefix(nsObj.Name))
metrics.SendErrorLogAndMetric(util.NSID, "[NAMESPACE %s EVENT] Error: NamespaceKey is empty for %s namespace", event, nsObj.Name)
return key, needSync
}

Expand Down Expand Up @@ -181,7 +181,7 @@ func (nsc *NamespaceController) deleteNamespace(obj interface{}) {
var key string
if key, err = cache.MetaNamespaceKeyFunc(nsObj); err != nil {
utilruntime.HandleError(err)
metrics.SendErrorLogAndMetric(util.NSID, "[NAMESPACE DELETE EVENT] Error: nameSpaceKey is empty for %s namespace", util.GetNSNameWithPrefix(nsObj.Name))
metrics.SendErrorLogAndMetric(util.NSID, "[NAMESPACE DELETE EVENT] Error: nameSpaceKey is empty for %s namespace", nsObj.Name)
return
}

Expand Down Expand Up @@ -249,10 +249,9 @@ func (nsc *NamespaceController) processNextWorkItem() bool {
}

// syncNamespace compares the actual state with the desired, and attempts to converge the two.
func (nsc *NamespaceController) syncNamespace(key string) error {
func (nsc *NamespaceController) syncNamespace(nsKey string) error {
// Get the Namespace resource with this key
nsObj, err := nsc.nameSpaceLister.Get(key)
cachedNsKey := util.GetNSNameWithPrefix(key)
nsObj, err := nsc.nameSpaceLister.Get(nsKey)

// apply dataplane after syncing
defer func() {
Expand All @@ -267,10 +266,10 @@ func (nsc *NamespaceController) syncNamespace(key string) error {
defer nsc.npmNamespaceCache.Unlock()
if err != nil {
if k8serrors.IsNotFound(err) {
klog.Infof("Namespace %s not found, may be it is deleted", key)
klog.Infof("Namespace %s not found, may be it is deleted", nsKey)
// cleanDeletedNamespace will check if the NS exists in cache, if it does, then proceeds with deletion
// if it does not exists, then event will be no-op
err = nsc.cleanDeletedNamespace(cachedNsKey)
err = nsc.cleanDeletedNamespace(nsKey)
if err != nil {
// need to retry this cleaning-up process
metrics.SendErrorLogAndMetric(util.NSID, "Error: %v when namespace is not found", err)
Expand All @@ -281,13 +280,13 @@ func (nsc *NamespaceController) syncNamespace(key string) error {
}

if nsObj.DeletionTimestamp != nil || nsObj.DeletionGracePeriodSeconds != nil {
return nsc.cleanDeletedNamespace(cachedNsKey)
return nsc.cleanDeletedNamespace(nsKey)
}

cachedNsObj, nsExists := nsc.npmNamespaceCache.NsMap[cachedNsKey]
cachedNsObj, nsExists := nsc.npmNamespaceCache.NsMap[nsKey]
if nsExists {
if reflect.DeepEqual(cachedNsObj.LabelsMap, nsObj.ObjectMeta.Labels) {
klog.Infof("[NAMESPACE UPDATE EVENT] Namespace [%s] labels did not change", key)
klog.Infof("[NAMESPACE UPDATE EVENT] Namespace [%s] labels did not change", nsKey)
return nil
}
}
Expand All @@ -304,20 +303,18 @@ func (nsc *NamespaceController) syncNamespace(key string) error {
// syncAddNamespace handles adding namespace to ipset.
func (nsc *NamespaceController) syncAddNamespace(nsObj *corev1.Namespace) error {
namespaceSets := []*ipsets.IPSetMetadata{ipsets.NewIPSetMetadata(nsObj.ObjectMeta.Name, ipsets.Namespace)}
setsToAddNamespaceTo := []*ipsets.IPSetMetadata{}

namespaceSets = append(namespaceSets, &ipsets.IPSetMetadata{Name: nsObj.ObjectMeta.Name, Type: ipsets.Namespace})
setsToAddNamespaceTo = append(setsToAddNamespaceTo, kubeAllNamespaces)
setsToAddNamespaceTo := []*ipsets.IPSetMetadata{kubeAllNamespaces}

npmNs := newNs(nsObj.ObjectMeta.Name)
nsc.npmNamespaceCache.NsMap[nsObj.ObjectMeta.Name] = npmNs

// Add the namespace to its label's ipset list.
for nsLabelKey, nsLabelVal := range nsObj.ObjectMeta.Labels {
klog.Infof("Adding namespace %s to ipset list %s", nsObj.ObjectMeta.Name, nsLabelKey)
nsLabelKeyValue := util.GetIpSetFromLabelKV(nsLabelKey, nsLabelVal)
klog.Infof("Adding namespace %s to ipset list %s and %s", nsObj.ObjectMeta.Name, nsLabelKey, nsLabelKeyValue)
labelIPSets := []*ipsets.IPSetMetadata{
{Name: nsLabelKey, Type: ipsets.Namespace},
{Name: util.GetIpSetFromLabelKV(nsLabelKey, nsLabelVal), Type: ipsets.Namespace},
ipsets.NewIPSetMetadata(nsLabelKey, ipsets.KeyLabelOfNamespace),
ipsets.NewIPSetMetadata(nsLabelKeyValue, ipsets.KeyValueLabelOfNamespace),
}

setsToAddNamespaceTo = append(setsToAddNamespaceTo, labelIPSets...)
Expand All @@ -326,8 +323,6 @@ func (nsc *NamespaceController) syncAddNamespace(nsObj *corev1.Namespace) error
npmNs.appendLabels(map[string]string{nsLabelKey: nsLabelVal}, appendToExistingLabels)
}

nsc.dp.CreateIPSets(append(namespaceSets, setsToAddNamespaceTo...))

if err := nsc.dp.AddToLists(setsToAddNamespaceTo, namespaceSets); err != nil {
return fmt.Errorf("failed to sync add namespace with error %w", err)
}
Expand All @@ -338,7 +333,7 @@ func (nsc *NamespaceController) syncAddNamespace(nsObj *corev1.Namespace) error
// syncUpdateNamespace handles updating namespace in ipset.
func (nsc *NamespaceController) syncUpdateNamespace(newNsObj *corev1.Namespace) error {
var err error
newNsName, newNsLabel := util.GetNSNameWithPrefix(newNsObj.ObjectMeta.Name), newNsObj.ObjectMeta.Labels
newNsName, newNsLabel := newNsObj.ObjectMeta.Name, newNsObj.ObjectMeta.Labels
klog.Infof("NAMESPACE UPDATING:\n namespace: [%s/%v]", newNsName, newNsLabel)

// If previous syncAddNamespace failed for some reasons
Expand All @@ -359,14 +354,17 @@ func (nsc *NamespaceController) syncUpdateNamespace(newNsObj *corev1.Namespace)
addToIPSets, deleteFromIPSets := util.GetIPSetListCompareLabels(curNsObj.LabelsMap, newNsLabel)
// Delete the namespace from its label's ipset list.
for _, nsLabelVal := range deleteFromIPSets {
labelKey := util.GetNSNameWithPrefix(nsLabelVal)

labelKeySet := &ipsets.IPSetMetadata{Name: nsLabelVal, Type: ipsets.KeyLabelOfNamespace}
toBeAdded := []*ipsets.IPSetMetadata{ipsets.NewIPSetMetadata(newNsName, ipsets.Namespace)}
var labelSet *ipsets.IPSetMetadata
if util.IsKeyValueLabelSetName(nsLabelVal) {
labelSet = ipsets.NewIPSetMetadata(nsLabelVal, ipsets.KeyValueLabelOfNamespace)
} else {
labelSet = ipsets.NewIPSetMetadata(nsLabelVal, ipsets.KeyLabelOfNamespace)
}
toBeRemoved := []*ipsets.IPSetMetadata{ipsets.NewIPSetMetadata(newNsName, ipsets.Namespace)}

klog.Infof("Deleting namespace %s from ipset list %s", newNsName, labelKey)
if err = nsc.dp.RemoveFromList(labelKeySet, toBeAdded); err != nil {
metrics.SendErrorLogAndMetric(util.NSID, "[UpdateNamespace] Error: failed to delete namespace %s from ipset list %s with err: %v", newNsName, labelKey, err)
klog.Infof("Deleting namespace %s from ipset list %s", newNsName, nsLabelVal)
if err = nsc.dp.RemoveFromList(labelSet, toBeRemoved); err != nil {
metrics.SendErrorLogAndMetric(util.NSID, "[UpdateNamespace] Error: failed to delete namespace %s from ipset list %s with err: %v", newNsName, nsLabelVal, err)
return fmt.Errorf("failed to remove from list during sync update namespace with err %w", err)
}
// {IMPORTANT} The order of compared list will be key and then key+val. NPM should only append after both key
Expand All @@ -382,12 +380,17 @@ func (nsc *NamespaceController) syncUpdateNamespace(newNsObj *corev1.Namespace)
for _, nsLabelVal := range addToIPSets {
klog.Infof("Adding namespace %s to ipset list %s", newNsName, nsLabelVal)

labelKeySet := []*ipsets.IPSetMetadata{ipsets.NewIPSetMetadata(nsLabelVal, ipsets.KeyLabelOfNamespace)}
var labelSet []*ipsets.IPSetMetadata
if util.IsKeyValueLabelSetName(nsLabelVal) {
labelSet = []*ipsets.IPSetMetadata{ipsets.NewIPSetMetadata(nsLabelVal, ipsets.KeyValueLabelOfNamespace)}
} else {
labelSet = []*ipsets.IPSetMetadata{ipsets.NewIPSetMetadata(nsLabelVal, ipsets.KeyLabelOfNamespace)}
}
toBeAdded := []*ipsets.IPSetMetadata{ipsets.NewIPSetMetadata(newNsName, ipsets.Namespace)}

if err = nsc.dp.AddToLists(labelKeySet, toBeAdded); err != nil {
if err = nsc.dp.AddToLists(labelSet, toBeAdded); err != nil {
metrics.SendErrorLogAndMetric(util.NSID, "[UpdateNamespace] Error: failed to add namespace %s to ipset list %s with err: %v", newNsName, nsLabelVal, err)
return fmt.Errorf("failed to add %v sets to %v lists during addtolists in sync update namespace with err %w", toBeAdded, labelKeySet, err)
return fmt.Errorf("failed to add %v sets to %v lists during addtolists in sync update namespace with err %w", toBeAdded, labelSet, err)
}
// {IMPORTANT} Same as above order is assumed to be key and then key+val. NPM should only append to existing labels
// only after both ipsets for a given label's key value pair are added successfully
Expand Down Expand Up @@ -417,25 +420,21 @@ func (nsc *NamespaceController) cleanDeletedNamespace(cachedNsKey string) error
klog.Infof("NAMESPACE DELETING cached labels: [%s/%v]", cachedNsKey, cachedNsObj.LabelsMap)

var err error
toBeDeletedNs := []*ipsets.IPSetMetadata{ipsets.NewIPSetMetadata(cachedNsKey, ipsets.Namespace)}
// Delete the namespace from its label's ipset list.
for nsLabelKey, nsLabelVal := range cachedNsObj.LabelsMap {

labelKey := &ipsets.IPSetMetadata{Name: nsLabelKey, Type: ipsets.KeyLabelOfNamespace}
toBeDeletedKey := []*ipsets.IPSetMetadata{ipsets.NewIPSetMetadata(cachedNsKey, ipsets.KeyLabelOfNamespace)}

labelIpsetName := util.GetNSNameWithPrefix(nsLabelKey)
klog.Infof("Deleting namespace %s from ipset list %s", cachedNsKey, labelIpsetName)
if err = nsc.dp.RemoveFromList(labelKey, toBeDeletedKey); err != nil {
metrics.SendErrorLogAndMetric(util.NSID, "[DeleteNamespace] Error: failed to delete namespace %s from ipset list %s with err: %v", cachedNsKey, labelIpsetName, err)
labelKey := ipsets.NewIPSetMetadata(nsLabelKey, ipsets.KeyLabelOfNamespace)
klog.Infof("Deleting namespace %s from ipset list %s", cachedNsKey, labelKey)
if err = nsc.dp.RemoveFromList(labelKey, toBeDeletedNs); err != nil {
metrics.SendErrorLogAndMetric(util.NSID, "[DeleteNamespace] Error: failed to delete namespace %s from ipset list %s with err: %v", cachedNsKey, labelKey, err)
return fmt.Errorf("failed to clean deleted namespace when deleting key with err %w", err)
}

labelKeyValue := &ipsets.IPSetMetadata{Name: nsLabelKey, Type: ipsets.KeyValueLabelOfNamespace}
toBeDeletedKeyValue := []*ipsets.IPSetMetadata{ipsets.NewIPSetMetadata(cachedNsKey, ipsets.KeyValueLabelOfNamespace)}

labelIpsetName = util.GetNSNameWithPrefix(util.GetIpSetFromLabelKV(nsLabelKey, nsLabelVal))
labelIpsetName := util.GetIpSetFromLabelKV(nsLabelKey, nsLabelVal)
labelKeyValue := ipsets.NewIPSetMetadata(labelIpsetName, ipsets.KeyValueLabelOfNamespace)
klog.Infof("Deleting namespace %s from ipset list %s", cachedNsKey, labelIpsetName)
if err = nsc.dp.RemoveFromList(labelKeyValue, toBeDeletedKeyValue); err != nil {
if err = nsc.dp.RemoveFromList(labelKeyValue, toBeDeletedNs); err != nil {
metrics.SendErrorLogAndMetric(util.NSID, "[DeleteNamespace] Error: failed to delete namespace %s from ipset list %s with err: %v", cachedNsKey, labelIpsetName, err)
return fmt.Errorf("failed to clean deleted namespace when deleting key value with err %w", err)
}
Expand All @@ -444,7 +443,7 @@ func (nsc *NamespaceController) cleanDeletedNamespace(cachedNsKey string) error
cachedNsObj.removeLabelsWithKey(nsLabelKey)
}

allNamespacesSet := &ipsets.IPSetMetadata{Name: util.KubeAllNamespacesFlag, Type: ipsets.Namespace}
allNamespacesSet := ipsets.NewIPSetMetadata(util.KubeAllNamespacesFlag, ipsets.KeyLabelOfNamespace)
toBeDeletedCachedKey := []*ipsets.IPSetMetadata{ipsets.NewIPSetMetadata(cachedNsKey, ipsets.Namespace)}

// Delete the namespace from all-namespace ipset list.
Expand Down
Loading