1
16
17 package netpol
18
19 import (
20 "strings"
21
22 "k8s.io/kubernetes/test/e2e/framework"
23 )
24
25
26 type TruthTable struct {
27 Froms []string
28 Tos []string
29 toSet map[string]bool
30 Values map[string]map[string]bool
31 }
32
33
34 func NewTruthTableFromItems(items []string, defaultValue *bool) *TruthTable {
35 return NewTruthTable(items, items, defaultValue)
36 }
37
38
39 func NewTruthTable(froms []string, tos []string, defaultValue *bool) *TruthTable {
40 values := map[string]map[string]bool{}
41 for _, from := range froms {
42 values[from] = map[string]bool{}
43 for _, to := range tos {
44 if defaultValue != nil {
45 values[from][to] = *defaultValue
46 }
47 }
48 }
49 toSet := map[string]bool{}
50 for _, to := range tos {
51 toSet[to] = true
52 }
53 return &TruthTable{
54 Froms: froms,
55 Tos: tos,
56 toSet: toSet,
57 Values: values,
58 }
59 }
60
61
62 func (tt *TruthTable) IsComplete() bool {
63 for _, from := range tt.Froms {
64 for _, to := range tt.Tos {
65 if _, ok := tt.Values[from][to]; !ok {
66 return false
67 }
68 }
69 }
70 return true
71 }
72
73
74 func (tt *TruthTable) Set(from string, to string, value bool) {
75 dict, ok := tt.Values[from]
76 if !ok {
77 framework.Failf("from-key %s not found", from)
78 }
79 if _, ok := tt.toSet[to]; !ok {
80 framework.Failf("to-key %s not allowed", to)
81 }
82 dict[to] = value
83 }
84
85
86 func (tt *TruthTable) SetAllFrom(from string, value bool) {
87 dict, ok := tt.Values[from]
88 if !ok {
89 framework.Failf("from-key %s not found", from)
90 }
91 for _, to := range tt.Tos {
92 dict[to] = value
93 }
94 }
95
96
97 func (tt *TruthTable) SetAllTo(to string, value bool) {
98 if _, ok := tt.toSet[to]; !ok {
99 framework.Failf("to-key %s not found", to)
100 }
101 for _, from := range tt.Froms {
102 tt.Values[from][to] = value
103 }
104 }
105
106
107 func (tt *TruthTable) Get(from string, to string) bool {
108 dict, ok := tt.Values[from]
109 if !ok {
110 framework.Failf("from-key %s not found", from)
111 }
112 val, ok := dict[to]
113 if !ok {
114 framework.Failf("to-key %s not found in map (%+v)", to, dict)
115 }
116 return val
117 }
118
119
120
121
122 func (tt *TruthTable) Compare(other *TruthTable) *TruthTable {
123 if len(tt.Froms) != len(other.Froms) || len(tt.Tos) != len(other.Tos) {
124 framework.Failf("cannot compare tables of different dimensions")
125 }
126 for i, fr := range tt.Froms {
127 if other.Froms[i] != fr {
128 framework.Failf("cannot compare: from keys at index %d do not match (%s vs %s)", i, other.Froms[i], fr)
129 }
130 }
131 for i, to := range tt.Tos {
132 if other.Tos[i] != to {
133 framework.Failf("cannot compare: to keys at index %d do not match (%s vs %s)", i, other.Tos[i], to)
134 }
135 }
136
137 values := map[string]map[string]bool{}
138 for from, dict := range tt.Values {
139 values[from] = map[string]bool{}
140 for to, val := range dict {
141 values[from][to] = val == other.Values[from][to]
142 }
143 }
144 return &TruthTable{
145 Froms: tt.Froms,
146 Tos: tt.Tos,
147 toSet: tt.toSet,
148 Values: values,
149 }
150 }
151
152
153 func (tt *TruthTable) PrettyPrint(indent string) string {
154 header := indent + strings.Join(append([]string{"-\t"}, tt.Tos...), "\t")
155 lines := []string{header}
156 for _, from := range tt.Froms {
157 line := []string{from}
158 for _, to := range tt.Tos {
159 mark := "X"
160 val, ok := tt.Values[from][to]
161 if !ok {
162 mark = "?"
163 } else if val {
164 mark = "."
165 }
166 line = append(line, mark+"\t")
167 }
168 lines = append(lines, indent+strings.Join(line, "\t"))
169 }
170 return strings.Join(lines, "\n")
171 }
172
View as plain text