diff options
author | Matthew Heon <matthew.heon@gmail.com> | 2017-11-01 11:24:59 -0400 |
---|---|---|
committer | Matthew Heon <matthew.heon@gmail.com> | 2017-11-01 11:24:59 -0400 |
commit | a031b83a09a8628435317a03f199cdc18b78262f (patch) | |
tree | bc017a96769ce6de33745b8b0b1304ccf38e9df0 /vendor/k8s.io/kubernetes/pkg/kubelet/network/hostport/fake_iptables.go | |
parent | 2b74391cd5281f6fdf391ff8ad50fd1490f6bf89 (diff) | |
download | podman-a031b83a09a8628435317a03f199cdc18b78262f.tar.gz podman-a031b83a09a8628435317a03f199cdc18b78262f.tar.bz2 podman-a031b83a09a8628435317a03f199cdc18b78262f.zip |
Initial checkin from CRI-O repo
Signed-off-by: Matthew Heon <matthew.heon@gmail.com>
Diffstat (limited to 'vendor/k8s.io/kubernetes/pkg/kubelet/network/hostport/fake_iptables.go')
-rw-r--r-- | vendor/k8s.io/kubernetes/pkg/kubelet/network/hostport/fake_iptables.go | 331 |
1 files changed, 331 insertions, 0 deletions
diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/network/hostport/fake_iptables.go b/vendor/k8s.io/kubernetes/pkg/kubelet/network/hostport/fake_iptables.go new file mode 100644 index 000000000..42f7c6811 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/network/hostport/fake_iptables.go @@ -0,0 +1,331 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package hostport + +import ( + "bytes" + "fmt" + "net" + "strings" + + utiliptables "k8s.io/kubernetes/pkg/util/iptables" +) + +type fakeChain struct { + name utiliptables.Chain + rules []string +} + +type fakeTable struct { + name utiliptables.Table + chains map[string]*fakeChain +} + +type fakeIPTables struct { + tables map[string]*fakeTable +} + +func NewFakeIPTables() *fakeIPTables { + return &fakeIPTables{ + tables: make(map[string]*fakeTable, 0), + } +} + +func (f *fakeIPTables) GetVersion() (string, error) { + return "1.4.21", nil +} + +func (f *fakeIPTables) getTable(tableName utiliptables.Table) (*fakeTable, error) { + table, ok := f.tables[string(tableName)] + if !ok { + return nil, fmt.Errorf("Table %s does not exist", tableName) + } + return table, nil +} + +func (f *fakeIPTables) getChain(tableName utiliptables.Table, chainName utiliptables.Chain) (*fakeTable, *fakeChain, error) { + table, err := f.getTable(tableName) + if err != nil { + return nil, nil, err + } + + chain, ok := table.chains[string(chainName)] + if !ok { + return table, nil, fmt.Errorf("Chain %s/%s does not exist", tableName, chainName) + } + + return table, chain, nil +} + +func (f *fakeIPTables) ensureChain(tableName utiliptables.Table, chainName utiliptables.Chain) (bool, *fakeChain) { + table, chain, err := f.getChain(tableName, chainName) + if err != nil { + // either table or table+chain don't exist yet + if table == nil { + table = &fakeTable{ + name: tableName, + chains: make(map[string]*fakeChain), + } + f.tables[string(tableName)] = table + } + chain := &fakeChain{ + name: chainName, + rules: make([]string, 0), + } + table.chains[string(chainName)] = chain + return false, chain + } + return true, chain +} + +func (f *fakeIPTables) EnsureChain(tableName utiliptables.Table, chainName utiliptables.Chain) (bool, error) { + existed, _ := f.ensureChain(tableName, chainName) + return existed, nil +} + +func (f *fakeIPTables) FlushChain(tableName utiliptables.Table, chainName utiliptables.Chain) error { + _, chain, err := f.getChain(tableName, chainName) + if err != nil { + return err + } + chain.rules = make([]string, 0) + return nil +} + +func (f *fakeIPTables) DeleteChain(tableName utiliptables.Table, chainName utiliptables.Chain) error { + table, _, err := f.getChain(tableName, chainName) + if err != nil { + return err + } + delete(table.chains, string(chainName)) + return nil +} + +// Returns index of rule in array; < 0 if rule is not found +func findRule(chain *fakeChain, rule string) int { + for i, candidate := range chain.rules { + if rule == candidate { + return i + } + } + return -1 +} + +func (f *fakeIPTables) ensureRule(position utiliptables.RulePosition, tableName utiliptables.Table, chainName utiliptables.Chain, rule string) (bool, error) { + _, chain, err := f.getChain(tableName, chainName) + if err != nil { + _, chain = f.ensureChain(tableName, chainName) + } + + rule, err = normalizeRule(rule) + if err != nil { + return false, err + } + ruleIdx := findRule(chain, rule) + if ruleIdx >= 0 { + return true, nil + } + + if position == utiliptables.Prepend { + chain.rules = append([]string{rule}, chain.rules...) + } else if position == utiliptables.Append { + chain.rules = append(chain.rules, rule) + } else { + return false, fmt.Errorf("Unknown position argument %q", position) + } + + return false, nil +} + +func normalizeRule(rule string) (string, error) { + normalized := "" + remaining := strings.TrimSpace(rule) + for { + var end int + + if strings.HasPrefix(remaining, "--to-destination=") { + remaining = strings.Replace(remaining, "=", " ", 1) + } + + if remaining[0] == '"' { + end = strings.Index(remaining[1:], "\"") + if end < 0 { + return "", fmt.Errorf("Invalid rule syntax: mismatched quotes") + } + end += 2 + } else { + end = strings.Index(remaining, " ") + if end < 0 { + end = len(remaining) + } + } + arg := remaining[:end] + + // Normalize un-prefixed IP addresses like iptables does + if net.ParseIP(arg) != nil { + arg = arg + "/32" + } + + if len(normalized) > 0 { + normalized += " " + } + normalized += strings.TrimSpace(arg) + if len(remaining) == end { + break + } + remaining = remaining[end+1:] + } + return normalized, nil +} + +func (f *fakeIPTables) EnsureRule(position utiliptables.RulePosition, tableName utiliptables.Table, chainName utiliptables.Chain, args ...string) (bool, error) { + ruleArgs := make([]string, 0) + for _, arg := range args { + // quote args with internal spaces (like comments) + if strings.Index(arg, " ") >= 0 { + arg = fmt.Sprintf("\"%s\"", arg) + } + ruleArgs = append(ruleArgs, arg) + } + return f.ensureRule(position, tableName, chainName, strings.Join(ruleArgs, " ")) +} + +func (f *fakeIPTables) DeleteRule(tableName utiliptables.Table, chainName utiliptables.Chain, args ...string) error { + _, chain, err := f.getChain(tableName, chainName) + if err == nil { + rule := strings.Join(args, " ") + ruleIdx := findRule(chain, rule) + if ruleIdx < 0 { + return nil + } + chain.rules = append(chain.rules[:ruleIdx], chain.rules[ruleIdx+1:]...) + } + return nil +} + +func (f *fakeIPTables) IsIpv6() bool { + return false +} + +func saveChain(chain *fakeChain, data *bytes.Buffer) { + for _, rule := range chain.rules { + data.WriteString(fmt.Sprintf("-A %s %s\n", chain.name, rule)) + } +} + +func (f *fakeIPTables) SaveInto(tableName utiliptables.Table, buffer *bytes.Buffer) error { + table, err := f.getTable(tableName) + if err != nil { + return err + } + + buffer.WriteString(fmt.Sprintf("*%s\n", table.name)) + + rules := bytes.NewBuffer(nil) + for _, chain := range table.chains { + buffer.WriteString(fmt.Sprintf(":%s - [0:0]\n", string(chain.name))) + saveChain(chain, rules) + } + buffer.Write(rules.Bytes()) + buffer.WriteString("COMMIT\n") + return nil +} + +func (f *fakeIPTables) restore(restoreTableName utiliptables.Table, data []byte, flush utiliptables.FlushFlag) error { + buf := bytes.NewBuffer(data) + var tableName utiliptables.Table + for { + line, err := buf.ReadString('\n') + if err != nil { + break + } + if line[0] == '#' { + continue + } + + line = strings.TrimSuffix(line, "\n") + if strings.HasPrefix(line, "*") { + tableName = utiliptables.Table(line[1:]) + } + if tableName != "" { + if restoreTableName != "" && restoreTableName != tableName { + continue + } + if strings.HasPrefix(line, ":") { + chainName := utiliptables.Chain(strings.Split(line[1:], " ")[0]) + if flush == utiliptables.FlushTables { + table, chain, _ := f.getChain(tableName, chainName) + if chain != nil { + delete(table.chains, string(chainName)) + } + } + _, _ = f.ensureChain(tableName, chainName) + } else if strings.HasPrefix(line, "-A") { + parts := strings.Split(line, " ") + if len(parts) < 3 { + return fmt.Errorf("Invalid iptables rule '%s'", line) + } + chainName := utiliptables.Chain(parts[1]) + rule := strings.TrimPrefix(line, fmt.Sprintf("-A %s ", chainName)) + _, err := f.ensureRule(utiliptables.Append, tableName, chainName, rule) + if err != nil { + return err + } + } else if strings.HasPrefix(line, "-I") { + parts := strings.Split(line, " ") + if len(parts) < 3 { + return fmt.Errorf("Invalid iptables rule '%s'", line) + } + chainName := utiliptables.Chain(parts[1]) + rule := strings.TrimPrefix(line, fmt.Sprintf("-I %s ", chainName)) + _, err := f.ensureRule(utiliptables.Prepend, tableName, chainName, rule) + if err != nil { + return err + } + } else if strings.HasPrefix(line, "-X") { + parts := strings.Split(line, " ") + if len(parts) < 2 { + return fmt.Errorf("Invalid iptables rule '%s'", line) + } + if err := f.DeleteChain(tableName, utiliptables.Chain(parts[1])); err != nil { + return err + } + } else if line == "COMMIT" { + if restoreTableName == tableName { + return nil + } + tableName = "" + } + } + } + + return nil +} + +func (f *fakeIPTables) Restore(tableName utiliptables.Table, data []byte, flush utiliptables.FlushFlag, counters utiliptables.RestoreCountersFlag) error { + return f.restore(tableName, data, flush) +} + +func (f *fakeIPTables) RestoreAll(data []byte, flush utiliptables.FlushFlag, counters utiliptables.RestoreCountersFlag) error { + return f.restore("", data, flush) +} + +func (f *fakeIPTables) AddReloadFunc(reloadFunc func()) { +} + +func (f *fakeIPTables) Destroy() { +} |