mirror of
https://github.com/optim-enterprises-bv/kubernetes.git
synced 2025-11-26 19:35:10 +00:00
Make Node authorizer's index authoritative for unauthorized calls
This commit is contained in:
@@ -52,7 +52,7 @@ func TestDeleteEdgesLocked(t *testing.T) {
|
||||
g.getOrCreateVertexLocked(configMapVertexType, "namespace1", "configmap2")
|
||||
nodeVertex := g.getOrCreateVertexLocked(nodeVertexType, "", "node1")
|
||||
configmapVertex := g.getOrCreateVertexLocked(configMapVertexType, "namespace1", "configmap1")
|
||||
g.graph.SetEdge(newDestinationEdge(configmapVertex, nodeVertex, nodeVertex))
|
||||
g.addEdgeLocked(configmapVertex, nodeVertex, nodeVertex)
|
||||
return g
|
||||
}(),
|
||||
expect: func() *Graph {
|
||||
@@ -74,8 +74,8 @@ func TestDeleteEdgesLocked(t *testing.T) {
|
||||
nodeVertex1 := g.getOrCreateVertexLocked(nodeVertexType, "", "node1")
|
||||
nodeVertex2 := g.getOrCreateVertexLocked(nodeVertexType, "", "node2")
|
||||
configmapVertex := g.getOrCreateVertexLocked(configMapVertexType, "namespace1", "configmap1")
|
||||
g.graph.SetEdge(newDestinationEdge(configmapVertex, nodeVertex1, nodeVertex1))
|
||||
g.graph.SetEdge(newDestinationEdge(configmapVertex, nodeVertex2, nodeVertex2))
|
||||
g.addEdgeLocked(configmapVertex, nodeVertex1, nodeVertex1)
|
||||
g.addEdgeLocked(configmapVertex, nodeVertex2, nodeVertex2)
|
||||
return g
|
||||
}(),
|
||||
expect: func() *Graph {
|
||||
@@ -83,7 +83,7 @@ func TestDeleteEdgesLocked(t *testing.T) {
|
||||
nodeVertex1 := g.getOrCreateVertexLocked(nodeVertexType, "", "node1")
|
||||
g.getOrCreateVertexLocked(nodeVertexType, "", "node2")
|
||||
configmapVertex := g.getOrCreateVertexLocked(configMapVertexType, "namespace1", "configmap1")
|
||||
g.graph.SetEdge(newDestinationEdge(configmapVertex, nodeVertex1, nodeVertex1))
|
||||
g.addEdgeLocked(configmapVertex, nodeVertex1, nodeVertex1)
|
||||
return g
|
||||
}(),
|
||||
},
|
||||
@@ -344,3 +344,558 @@ func TestIndex(t *testing.T) {
|
||||
"serviceAccount:ns/sa1": {"node:node1=1", "node:node2=1", "node:node3=1"},
|
||||
})
|
||||
}
|
||||
|
||||
func TestIndex2(t *testing.T) {
|
||||
NewTestGraph := func() *Graph {
|
||||
g := NewGraph()
|
||||
g.destinationEdgeThreshold = 3
|
||||
return g
|
||||
}
|
||||
|
||||
pod := func(podName, nodeName, saName string, volumes []corev1.Volume, resourceClaims []corev1.PodResourceClaim) *corev1.Pod {
|
||||
p := &corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: podName, Namespace: "ns", UID: types.UID(fmt.Sprintf("pod%suid", podName))},
|
||||
Spec: corev1.PodSpec{
|
||||
NodeName: nodeName,
|
||||
},
|
||||
}
|
||||
if saName != "" {
|
||||
p.Spec.ServiceAccountName = saName
|
||||
}
|
||||
if volumes != nil {
|
||||
p.Spec.Volumes = volumes
|
||||
}
|
||||
if resourceClaims != nil {
|
||||
p.Spec.ResourceClaims = resourceClaims
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
podWithSAAndCMs := func(podName, nodeName string) *corev1.Pod {
|
||||
cm := func(name string) corev1.Volume {
|
||||
return corev1.Volume{Name: name, VolumeSource: corev1.VolumeSource{ConfigMap: &corev1.ConfigMapVolumeSource{LocalObjectReference: corev1.LocalObjectReference{Name: name}}}}
|
||||
}
|
||||
return pod(podName, nodeName, "sa1", []corev1.Volume{
|
||||
cm("cm1"),
|
||||
cm("cm2"),
|
||||
cm("cm3"),
|
||||
}, nil)
|
||||
}
|
||||
|
||||
podWithSecrets := func(podName, nodeName string) *corev1.Pod {
|
||||
secret := func(name string) corev1.Volume {
|
||||
return corev1.Volume{Name: name, VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: name}}}
|
||||
}
|
||||
return pod(podName, nodeName, "", []corev1.Volume{
|
||||
secret("s1"),
|
||||
secret("s2"),
|
||||
secret("s3"),
|
||||
}, nil)
|
||||
}
|
||||
|
||||
podWithPVCs := func(podName, nodeName string) *corev1.Pod {
|
||||
pvc := func(name string) corev1.Volume {
|
||||
return corev1.Volume{Name: name, VolumeSource: corev1.VolumeSource{PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ClaimName: name}}}
|
||||
}
|
||||
return pod(podName, nodeName, "", []corev1.Volume{
|
||||
pvc("pvc1"),
|
||||
pvc("pvc2"),
|
||||
pvc("pvc3"),
|
||||
}, nil)
|
||||
}
|
||||
|
||||
podWithResourceClaims := func(podName, nodeName string) *corev1.Pod {
|
||||
rc := func(name string) corev1.PodResourceClaim {
|
||||
return corev1.PodResourceClaim{ResourceClaimName: &name}
|
||||
}
|
||||
return pod(podName, nodeName, "", nil, []corev1.PodResourceClaim{
|
||||
rc("rc1"),
|
||||
rc("rc2"),
|
||||
rc("rc3"),
|
||||
})
|
||||
}
|
||||
|
||||
pv := func(pvName, pvcName, secretName string) *corev1.PersistentVolume {
|
||||
pv := &corev1.PersistentVolume{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: pvName, UID: types.UID(fmt.Sprintf("pv%suid", pvName))},
|
||||
Spec: corev1.PersistentVolumeSpec{
|
||||
ClaimRef: &corev1.ObjectReference{
|
||||
Name: pvcName,
|
||||
Namespace: "ns",
|
||||
},
|
||||
},
|
||||
}
|
||||
if secretName != "" {
|
||||
pv.Spec.PersistentVolumeSource = corev1.PersistentVolumeSource{
|
||||
CSI: &corev1.CSIPersistentVolumeSource{
|
||||
NodePublishSecretRef: &corev1.SecretReference{
|
||||
Name: secretName,
|
||||
Namespace: "ns",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
return pv
|
||||
}
|
||||
|
||||
toString := func(g *Graph, id int) string {
|
||||
for _, namespaceName := range g.vertices {
|
||||
for _, nameVertex := range namespaceName {
|
||||
for _, vertex := range nameVertex {
|
||||
if vertex.id == id {
|
||||
return vertex.String()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
expectGraph := func(t *testing.T, g *Graph, expect map[string][]string) {
|
||||
t.Helper()
|
||||
actual := map[string][]string{}
|
||||
for _, node := range g.graph.Nodes() {
|
||||
sortedTo := []string{}
|
||||
for _, to := range g.graph.From(node) {
|
||||
sortedTo = append(sortedTo, toString(g, to.ID()))
|
||||
}
|
||||
sort.Strings(sortedTo)
|
||||
actual[toString(g, node.ID())] = sortedTo
|
||||
}
|
||||
if !reflect.DeepEqual(expect, actual) {
|
||||
e, _ := json.MarshalIndent(expect, "", " ")
|
||||
a, _ := json.MarshalIndent(actual, "", " ")
|
||||
t.Errorf("expected graph:\n%s\ngot:\n%s", string(e), string(a))
|
||||
}
|
||||
}
|
||||
expectIndex := func(t *testing.T, g *Graph, expect map[string][]string) {
|
||||
t.Helper()
|
||||
actual := map[string][]string{}
|
||||
for from, to := range g.destinationEdgeIndex {
|
||||
sortedValues := []string{}
|
||||
for member, count := range to.members {
|
||||
sortedValues = append(sortedValues, fmt.Sprintf("%s=%d", toString(g, member), count))
|
||||
}
|
||||
sort.Strings(sortedValues)
|
||||
actual[toString(g, from)] = sortedValues
|
||||
}
|
||||
if !reflect.DeepEqual(expect, actual) {
|
||||
e, _ := json.MarshalIndent(expect, "", " ")
|
||||
a, _ := json.MarshalIndent(actual, "", " ")
|
||||
t.Errorf("expected index:\n%s\ngot:\n%s", string(e), string(a))
|
||||
}
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
startingGraph *Graph
|
||||
graphTransformer func(*Graph)
|
||||
expectedGraph map[string][]string
|
||||
expectedIndex map[string][]string
|
||||
}{
|
||||
{
|
||||
desc: "empty graph",
|
||||
startingGraph: NewTestGraph(),
|
||||
graphTransformer: func(_ *Graph) {},
|
||||
expectedGraph: map[string][]string{},
|
||||
expectedIndex: map[string][]string{},
|
||||
},
|
||||
{
|
||||
desc: "outdeg below destination edge index threshold",
|
||||
startingGraph: NewTestGraph(),
|
||||
graphTransformer: func(g *Graph) {
|
||||
g.AddPod(podWithSAAndCMs("pod1", "node1"))
|
||||
g.AddPod(podWithSAAndCMs("pod2", "node2"))
|
||||
},
|
||||
expectedGraph: map[string][]string{
|
||||
"node:node1": {},
|
||||
"node:node2": {},
|
||||
"pod:ns/pod1": {"node:node1"},
|
||||
"pod:ns/pod2": {"node:node2"},
|
||||
"configmap:ns/cm1": {"pod:ns/pod1", "pod:ns/pod2"},
|
||||
"configmap:ns/cm2": {"pod:ns/pod1", "pod:ns/pod2"},
|
||||
"configmap:ns/cm3": {"pod:ns/pod1", "pod:ns/pod2"},
|
||||
"serviceAccount:ns/sa1": {"pod:ns/pod1", "pod:ns/pod2"},
|
||||
},
|
||||
expectedIndex: map[string][]string{},
|
||||
},
|
||||
{
|
||||
desc: "index built for configmaps and serviceaccounts",
|
||||
startingGraph: func() *Graph {
|
||||
g := NewTestGraph()
|
||||
g.AddPod(podWithSAAndCMs("pod1", "node1"))
|
||||
g.AddPod(podWithSAAndCMs("pod2", "node2"))
|
||||
return g
|
||||
}(),
|
||||
graphTransformer: func(g *Graph) {
|
||||
g.AddPod(podWithSAAndCMs("pod3", "node3"))
|
||||
},
|
||||
expectedGraph: map[string][]string{
|
||||
"node:node1": {},
|
||||
"node:node2": {},
|
||||
"node:node3": {},
|
||||
"pod:ns/pod1": {"node:node1"},
|
||||
"pod:ns/pod2": {"node:node2"},
|
||||
"pod:ns/pod3": {"node:node3"},
|
||||
"configmap:ns/cm1": {"pod:ns/pod1", "pod:ns/pod2", "pod:ns/pod3"},
|
||||
"configmap:ns/cm2": {"pod:ns/pod1", "pod:ns/pod2", "pod:ns/pod3"},
|
||||
"configmap:ns/cm3": {"pod:ns/pod1", "pod:ns/pod2", "pod:ns/pod3"},
|
||||
"serviceAccount:ns/sa1": {"pod:ns/pod1", "pod:ns/pod2", "pod:ns/pod3"},
|
||||
},
|
||||
expectedIndex: map[string][]string{
|
||||
"configmap:ns/cm1": {"node:node1=1", "node:node2=1", "node:node3=1"},
|
||||
"configmap:ns/cm2": {"node:node1=1", "node:node2=1", "node:node3=1"},
|
||||
"configmap:ns/cm3": {"node:node1=1", "node:node2=1", "node:node3=1"},
|
||||
"serviceAccount:ns/sa1": {"node:node1=1", "node:node2=1", "node:node3=1"},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "no index for configmaps and serviceaccounts - dropping below threshold",
|
||||
startingGraph: func() *Graph {
|
||||
g := NewTestGraph()
|
||||
g.AddPod(podWithSAAndCMs("pod1", "node1"))
|
||||
g.AddPod(podWithSAAndCMs("pod2", "node2"))
|
||||
g.AddPod(podWithSAAndCMs("pod3", "node3"))
|
||||
return g
|
||||
}(),
|
||||
graphTransformer: func(g *Graph) {
|
||||
g.DeletePod("pod1", "ns")
|
||||
},
|
||||
expectedGraph: map[string][]string{
|
||||
"node:node2": {},
|
||||
"node:node3": {},
|
||||
"pod:ns/pod2": {"node:node2"},
|
||||
"pod:ns/pod3": {"node:node3"},
|
||||
"configmap:ns/cm1": {"pod:ns/pod2", "pod:ns/pod3"},
|
||||
"configmap:ns/cm2": {"pod:ns/pod2", "pod:ns/pod3"},
|
||||
"configmap:ns/cm3": {"pod:ns/pod2", "pod:ns/pod3"},
|
||||
"serviceAccount:ns/sa1": {"pod:ns/pod2", "pod:ns/pod3"},
|
||||
},
|
||||
expectedIndex: map[string][]string{},
|
||||
},
|
||||
{
|
||||
desc: "removing pod but staying above threshold",
|
||||
startingGraph: func() *Graph {
|
||||
g := NewTestGraph()
|
||||
g.AddPod(podWithSAAndCMs("pod1", "node1"))
|
||||
g.AddPod(podWithSAAndCMs("pod2", "node2"))
|
||||
g.AddPod(podWithSAAndCMs("pod3", "node3"))
|
||||
g.AddPod(podWithSAAndCMs("pod4", "node1"))
|
||||
return g
|
||||
}(),
|
||||
graphTransformer: func(g *Graph) {
|
||||
g.DeletePod("pod1", "ns")
|
||||
},
|
||||
expectedGraph: map[string][]string{
|
||||
"node:node1": {},
|
||||
"node:node2": {},
|
||||
"node:node3": {},
|
||||
"pod:ns/pod2": {"node:node2"},
|
||||
"pod:ns/pod3": {"node:node3"},
|
||||
"pod:ns/pod4": {"node:node1"},
|
||||
"configmap:ns/cm1": {"pod:ns/pod2", "pod:ns/pod3", "pod:ns/pod4"},
|
||||
"configmap:ns/cm2": {"pod:ns/pod2", "pod:ns/pod3", "pod:ns/pod4"},
|
||||
"configmap:ns/cm3": {"pod:ns/pod2", "pod:ns/pod3", "pod:ns/pod4"},
|
||||
"serviceAccount:ns/sa1": {"pod:ns/pod2", "pod:ns/pod3", "pod:ns/pod4"},
|
||||
},
|
||||
expectedIndex: map[string][]string{
|
||||
"configmap:ns/cm1": {"node:node1=1", "node:node2=1", "node:node3=1"},
|
||||
"configmap:ns/cm2": {"node:node1=1", "node:node2=1", "node:node3=1"},
|
||||
"configmap:ns/cm3": {"node:node1=1", "node:node2=1", "node:node3=1"},
|
||||
"serviceAccount:ns/sa1": {"node:node1=1", "node:node2=1", "node:node3=1"},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "index built for secrets",
|
||||
startingGraph: func() *Graph {
|
||||
g := NewTestGraph()
|
||||
g.AddPod(podWithSecrets("pod1", "node1"))
|
||||
g.AddPod(podWithSecrets("pod2", "node2"))
|
||||
return g
|
||||
}(),
|
||||
graphTransformer: func(g *Graph) {
|
||||
g.AddPod(podWithSecrets("pod3", "node3"))
|
||||
},
|
||||
expectedGraph: map[string][]string{
|
||||
"node:node1": {},
|
||||
"node:node2": {},
|
||||
"node:node3": {},
|
||||
"pod:ns/pod1": {"node:node1"},
|
||||
"pod:ns/pod2": {"node:node2"},
|
||||
"pod:ns/pod3": {"node:node3"},
|
||||
"secret:ns/s1": {"pod:ns/pod1", "pod:ns/pod2", "pod:ns/pod3"},
|
||||
"secret:ns/s2": {"pod:ns/pod1", "pod:ns/pod2", "pod:ns/pod3"},
|
||||
"secret:ns/s3": {"pod:ns/pod1", "pod:ns/pod2", "pod:ns/pod3"},
|
||||
},
|
||||
expectedIndex: map[string][]string{
|
||||
"secret:ns/s1": {"node:node1=1", "node:node2=1", "node:node3=1"},
|
||||
"secret:ns/s2": {"node:node1=1", "node:node2=1", "node:node3=1"},
|
||||
"secret:ns/s3": {"node:node1=1", "node:node2=1", "node:node3=1"},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "no index for secrets - dropping below threshold",
|
||||
startingGraph: func() *Graph {
|
||||
g := NewTestGraph()
|
||||
g.AddPod(podWithSecrets("pod1", "node1"))
|
||||
g.AddPod(podWithSecrets("pod2", "node2"))
|
||||
g.AddPod(podWithSecrets("pod3", "node3"))
|
||||
return g
|
||||
}(),
|
||||
graphTransformer: func(g *Graph) {
|
||||
g.DeletePod("pod1", "ns")
|
||||
},
|
||||
expectedGraph: map[string][]string{
|
||||
"node:node2": {},
|
||||
"node:node3": {},
|
||||
"pod:ns/pod2": {"node:node2"},
|
||||
"pod:ns/pod3": {"node:node3"},
|
||||
"secret:ns/s1": {"pod:ns/pod2", "pod:ns/pod3"},
|
||||
"secret:ns/s2": {"pod:ns/pod2", "pod:ns/pod3"},
|
||||
"secret:ns/s3": {"pod:ns/pod2", "pod:ns/pod3"},
|
||||
},
|
||||
expectedIndex: map[string][]string{},
|
||||
},
|
||||
{
|
||||
desc: "index built for pvcs",
|
||||
startingGraph: func() *Graph {
|
||||
g := NewTestGraph()
|
||||
g.AddPod(podWithPVCs("pod1", "node1"))
|
||||
g.AddPod(podWithPVCs("pod2", "node2"))
|
||||
return g
|
||||
}(),
|
||||
graphTransformer: func(g *Graph) {
|
||||
g.AddPod(podWithPVCs("pod3", "node3"))
|
||||
},
|
||||
expectedGraph: map[string][]string{
|
||||
"node:node1": {},
|
||||
"node:node2": {},
|
||||
"node:node3": {},
|
||||
"pod:ns/pod1": {"node:node1"},
|
||||
"pod:ns/pod2": {"node:node2"},
|
||||
"pod:ns/pod3": {"node:node3"},
|
||||
"pvc:ns/pvc1": {"pod:ns/pod1", "pod:ns/pod2", "pod:ns/pod3"},
|
||||
"pvc:ns/pvc2": {"pod:ns/pod1", "pod:ns/pod2", "pod:ns/pod3"},
|
||||
"pvc:ns/pvc3": {"pod:ns/pod1", "pod:ns/pod2", "pod:ns/pod3"},
|
||||
},
|
||||
expectedIndex: map[string][]string{
|
||||
"pvc:ns/pvc1": {"node:node1=1", "node:node2=1", "node:node3=1"},
|
||||
"pvc:ns/pvc2": {"node:node1=1", "node:node2=1", "node:node3=1"},
|
||||
"pvc:ns/pvc3": {"node:node1=1", "node:node2=1", "node:node3=1"},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "no index for pvcs - dropping below threshold",
|
||||
startingGraph: func() *Graph {
|
||||
g := NewTestGraph()
|
||||
g.AddPod(podWithPVCs("pod1", "node1"))
|
||||
g.AddPod(podWithPVCs("pod2", "node2"))
|
||||
g.AddPod(podWithPVCs("pod3", "node3"))
|
||||
return g
|
||||
}(),
|
||||
graphTransformer: func(g *Graph) {
|
||||
g.DeletePod("pod1", "ns")
|
||||
},
|
||||
expectedGraph: map[string][]string{
|
||||
"node:node2": {},
|
||||
"node:node3": {},
|
||||
"pod:ns/pod2": {"node:node2"},
|
||||
"pod:ns/pod3": {"node:node3"},
|
||||
"pvc:ns/pvc1": {"pod:ns/pod2", "pod:ns/pod3"},
|
||||
"pvc:ns/pvc2": {"pod:ns/pod2", "pod:ns/pod3"},
|
||||
"pvc:ns/pvc3": {"pod:ns/pod2", "pod:ns/pod3"},
|
||||
},
|
||||
expectedIndex: map[string][]string{},
|
||||
},
|
||||
{
|
||||
desc: "index built for resourceclaims",
|
||||
startingGraph: NewTestGraph(),
|
||||
graphTransformer: func(g *Graph) {
|
||||
g.AddPod(podWithResourceClaims("pod1", "node1"))
|
||||
g.AddPod(podWithResourceClaims("pod2", "node2"))
|
||||
g.AddPod(podWithResourceClaims("pod3", "node3"))
|
||||
},
|
||||
expectedGraph: map[string][]string{
|
||||
"node:node1": {},
|
||||
"node:node2": {},
|
||||
"node:node3": {},
|
||||
"pod:ns/pod1": {"node:node1"},
|
||||
"pod:ns/pod2": {"node:node2"},
|
||||
"pod:ns/pod3": {"node:node3"},
|
||||
"resourceclaim:ns/rc1": {"pod:ns/pod1", "pod:ns/pod2", "pod:ns/pod3"},
|
||||
"resourceclaim:ns/rc2": {"pod:ns/pod1", "pod:ns/pod2", "pod:ns/pod3"},
|
||||
"resourceclaim:ns/rc3": {"pod:ns/pod1", "pod:ns/pod2", "pod:ns/pod3"},
|
||||
},
|
||||
expectedIndex: map[string][]string{
|
||||
"resourceclaim:ns/rc1": {"node:node1=1", "node:node2=1", "node:node3=1"},
|
||||
"resourceclaim:ns/rc2": {"node:node1=1", "node:node2=1", "node:node3=1"},
|
||||
"resourceclaim:ns/rc3": {"node:node1=1", "node:node2=1", "node:node3=1"},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "no index for resourceclaims - dropping below threshold",
|
||||
startingGraph: func() *Graph {
|
||||
g := NewTestGraph()
|
||||
g.AddPod(podWithResourceClaims("pod1", "node1"))
|
||||
g.AddPod(podWithResourceClaims("pod2", "node2"))
|
||||
g.AddPod(podWithResourceClaims("pod3", "node3"))
|
||||
return g
|
||||
}(),
|
||||
graphTransformer: func(g *Graph) {
|
||||
g.DeletePod("pod1", "ns")
|
||||
},
|
||||
expectedGraph: map[string][]string{
|
||||
"node:node2": {},
|
||||
"node:node3": {},
|
||||
"pod:ns/pod2": {"node:node2"},
|
||||
"pod:ns/pod3": {"node:node3"},
|
||||
"resourceclaim:ns/rc1": {"pod:ns/pod2", "pod:ns/pod3"},
|
||||
"resourceclaim:ns/rc2": {"pod:ns/pod2", "pod:ns/pod3"},
|
||||
"resourceclaim:ns/rc3": {"pod:ns/pod2", "pod:ns/pod3"},
|
||||
},
|
||||
expectedIndex: map[string][]string{},
|
||||
},
|
||||
{
|
||||
desc: "resourceslices adding",
|
||||
startingGraph: NewTestGraph(),
|
||||
graphTransformer: func(g *Graph) {
|
||||
g.AddResourceSlice("s1", "node1")
|
||||
g.AddResourceSlice("s2", "node2")
|
||||
g.AddResourceSlice("s3", "node3")
|
||||
},
|
||||
expectedGraph: map[string][]string{
|
||||
"node:node1": {},
|
||||
"node:node2": {},
|
||||
"node:node3": {},
|
||||
"resourceslice:s1": {"node:node1"},
|
||||
"resourceslice:s2": {"node:node2"},
|
||||
"resourceslice:s3": {"node:node3"},
|
||||
},
|
||||
expectedIndex: map[string][]string{},
|
||||
},
|
||||
{
|
||||
desc: "resourceslices deleting",
|
||||
startingGraph: func() *Graph {
|
||||
g := NewTestGraph()
|
||||
g.AddResourceSlice("s1", "node1")
|
||||
g.AddResourceSlice("s2", "node2")
|
||||
g.AddResourceSlice("s3", "node3")
|
||||
return g
|
||||
}(),
|
||||
graphTransformer: func(g *Graph) {
|
||||
g.DeleteResourceSlice("s1")
|
||||
},
|
||||
expectedGraph: map[string][]string{
|
||||
"node:node2": {},
|
||||
"node:node3": {},
|
||||
"resourceslice:s2": {"node:node2"},
|
||||
"resourceslice:s3": {"node:node3"},
|
||||
},
|
||||
expectedIndex: map[string][]string{},
|
||||
},
|
||||
{
|
||||
desc: "volumeattachments adding",
|
||||
startingGraph: NewTestGraph(),
|
||||
graphTransformer: func(g *Graph) {
|
||||
g.AddVolumeAttachment("va1", "node1")
|
||||
g.AddVolumeAttachment("va2", "node2")
|
||||
g.AddVolumeAttachment("va3", "node3")
|
||||
},
|
||||
expectedGraph: map[string][]string{
|
||||
"node:node1": {},
|
||||
"node:node2": {},
|
||||
"node:node3": {},
|
||||
"volumeattachment:va1": {"node:node1"},
|
||||
"volumeattachment:va2": {"node:node2"},
|
||||
"volumeattachment:va3": {"node:node3"},
|
||||
},
|
||||
expectedIndex: map[string][]string{},
|
||||
},
|
||||
{
|
||||
desc: "volumeattachments deleting",
|
||||
startingGraph: func() *Graph {
|
||||
g := NewTestGraph()
|
||||
g.AddVolumeAttachment("va1", "node1")
|
||||
g.AddVolumeAttachment("va2", "node2")
|
||||
g.AddVolumeAttachment("va3", "node3")
|
||||
return g
|
||||
}(),
|
||||
graphTransformer: func(g *Graph) {
|
||||
g.DeleteVolumeAttachment("va1")
|
||||
},
|
||||
expectedGraph: map[string][]string{
|
||||
"node:node2": {},
|
||||
"node:node3": {},
|
||||
"volumeattachment:va2": {"node:node2"},
|
||||
"volumeattachment:va3": {"node:node3"},
|
||||
},
|
||||
expectedIndex: map[string][]string{},
|
||||
},
|
||||
{
|
||||
desc: "persistentvolumes adding",
|
||||
startingGraph: NewTestGraph(),
|
||||
graphTransformer: func(g *Graph) {
|
||||
g.AddPV(pv("pv1", "pvc1", ""))
|
||||
g.AddPV(pv("pv2", "pvc2", ""))
|
||||
g.AddPV(pv("pv3", "pvc3", ""))
|
||||
},
|
||||
expectedGraph: map[string][]string{
|
||||
"pv:pv1": {"pvc:ns/pvc1"},
|
||||
"pv:pv2": {"pvc:ns/pvc2"},
|
||||
"pv:pv3": {"pvc:ns/pvc3"},
|
||||
"pvc:ns/pvc1": {},
|
||||
"pvc:ns/pvc2": {},
|
||||
"pvc:ns/pvc3": {},
|
||||
},
|
||||
expectedIndex: map[string][]string{},
|
||||
},
|
||||
{
|
||||
desc: "persistentvolumes deleting",
|
||||
startingGraph: func() *Graph {
|
||||
g := NewTestGraph()
|
||||
g.AddPV(pv("pv1", "pvc1", ""))
|
||||
g.AddPV(pv("pv2", "pvc2", ""))
|
||||
g.AddPV(pv("pv3", "pvc3", ""))
|
||||
return g
|
||||
}(),
|
||||
graphTransformer: func(g *Graph) {
|
||||
g.DeletePV("pv1")
|
||||
},
|
||||
expectedGraph: map[string][]string{
|
||||
"pv:pv2": {"pvc:ns/pvc2"},
|
||||
"pv:pv3": {"pvc:ns/pvc3"},
|
||||
"pvc:ns/pvc2": {},
|
||||
"pvc:ns/pvc3": {},
|
||||
},
|
||||
expectedIndex: map[string][]string{},
|
||||
},
|
||||
{
|
||||
desc: "persistentvolumes with secrets",
|
||||
startingGraph: NewTestGraph(),
|
||||
graphTransformer: func(g *Graph) {
|
||||
g.AddPV(pv("pv1", "pvc1", "s1"))
|
||||
g.AddPV(pv("pv2", "pvc2", "s2"))
|
||||
g.AddPV(pv("pv3", "pvc3", "s3"))
|
||||
},
|
||||
expectedGraph: map[string][]string{
|
||||
"pv:pv1": {"pvc:ns/pvc1"},
|
||||
"pv:pv2": {"pvc:ns/pvc2"},
|
||||
"pv:pv3": {"pvc:ns/pvc3"},
|
||||
"pvc:ns/pvc1": {},
|
||||
"pvc:ns/pvc2": {},
|
||||
"pvc:ns/pvc3": {},
|
||||
"secret:ns/s1": {"pv:pv1"},
|
||||
"secret:ns/s2": {"pv:pv2"},
|
||||
"secret:ns/s3": {"pv:pv3"},
|
||||
},
|
||||
expectedIndex: map[string][]string{},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
tc.graphTransformer(tc.startingGraph)
|
||||
expectGraph(t, tc.startingGraph, tc.expectedGraph)
|
||||
expectIndex(t, tc.startingGraph, tc.expectedIndex)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user