vendor: add hostport and deps
Signed-off-by: Andrew Pilloud <andrewpilloud@igneoussystems.com>
This commit is contained in:
parent
28cd8bde49
commit
a0e15abf5e
30 changed files with 5052 additions and 0 deletions
133
vendor/k8s.io/kubernetes/pkg/util/dbus/dbus.go
generated
vendored
Normal file
133
vendor/k8s.io/kubernetes/pkg/util/dbus/dbus.go
generated
vendored
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
Copyright 2015 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 dbus
|
||||
|
||||
import (
|
||||
godbus "github.com/godbus/dbus"
|
||||
)
|
||||
|
||||
// Interface is an interface that presents a subset of the godbus/dbus API. Use this
|
||||
// when you want to inject fakeable/mockable D-Bus behavior.
|
||||
type Interface interface {
|
||||
// SystemBus returns a connection to the system bus, connecting to it
|
||||
// first if necessary
|
||||
SystemBus() (Connection, error)
|
||||
// SessionBus returns a connection to the session bus, connecting to it
|
||||
// first if necessary
|
||||
SessionBus() (Connection, error)
|
||||
}
|
||||
|
||||
// Connection represents a D-Bus connection
|
||||
type Connection interface {
|
||||
// Returns an Object representing the bus itself
|
||||
BusObject() Object
|
||||
|
||||
// Object creates a representation of a remote D-Bus object
|
||||
Object(name, path string) Object
|
||||
|
||||
// Signal registers or unregisters a channel to receive D-Bus signals
|
||||
Signal(ch chan<- *godbus.Signal)
|
||||
}
|
||||
|
||||
// Object represents a remote D-Bus object
|
||||
type Object interface {
|
||||
// Call synchronously calls a D-Bus method
|
||||
Call(method string, flags godbus.Flags, args ...interface{}) Call
|
||||
}
|
||||
|
||||
// Call represents a pending or completed D-Bus method call
|
||||
type Call interface {
|
||||
// Store returns a completed call's return values, or an error
|
||||
Store(retvalues ...interface{}) error
|
||||
}
|
||||
|
||||
// Implements Interface in terms of actually talking to D-Bus
|
||||
type dbusImpl struct {
|
||||
systemBus *connImpl
|
||||
sessionBus *connImpl
|
||||
}
|
||||
|
||||
// Implements Connection as a godbus.Conn
|
||||
type connImpl struct {
|
||||
conn *godbus.Conn
|
||||
}
|
||||
|
||||
// Implements Object as a godbus.Object
|
||||
type objectImpl struct {
|
||||
object godbus.BusObject
|
||||
}
|
||||
|
||||
// Implements Call as a godbus.Call
|
||||
type callImpl struct {
|
||||
call *godbus.Call
|
||||
}
|
||||
|
||||
// New returns a new Interface which will use godbus to talk to D-Bus
|
||||
func New() Interface {
|
||||
return &dbusImpl{}
|
||||
}
|
||||
|
||||
// SystemBus is part of Interface
|
||||
func (db *dbusImpl) SystemBus() (Connection, error) {
|
||||
if db.systemBus == nil {
|
||||
bus, err := godbus.SystemBus()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
db.systemBus = &connImpl{bus}
|
||||
}
|
||||
|
||||
return db.systemBus, nil
|
||||
}
|
||||
|
||||
// SessionBus is part of Interface
|
||||
func (db *dbusImpl) SessionBus() (Connection, error) {
|
||||
if db.sessionBus == nil {
|
||||
bus, err := godbus.SessionBus()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
db.sessionBus = &connImpl{bus}
|
||||
}
|
||||
|
||||
return db.sessionBus, nil
|
||||
}
|
||||
|
||||
// BusObject is part of the Connection interface
|
||||
func (conn *connImpl) BusObject() Object {
|
||||
return &objectImpl{conn.conn.BusObject()}
|
||||
}
|
||||
|
||||
// Object is part of the Connection interface
|
||||
func (conn *connImpl) Object(name, path string) Object {
|
||||
return &objectImpl{conn.conn.Object(name, godbus.ObjectPath(path))}
|
||||
}
|
||||
|
||||
// Signal is part of the Connection interface
|
||||
func (conn *connImpl) Signal(ch chan<- *godbus.Signal) {
|
||||
conn.conn.Signal(ch)
|
||||
}
|
||||
|
||||
// Call is part of the Object interface
|
||||
func (obj *objectImpl) Call(method string, flags godbus.Flags, args ...interface{}) Call {
|
||||
return &callImpl{obj.object.Call(method, flags, args...)}
|
||||
}
|
||||
|
||||
// Store is part of the Call interface
|
||||
func (call *callImpl) Store(retvalues ...interface{}) error {
|
||||
return call.call.Store(retvalues...)
|
||||
}
|
18
vendor/k8s.io/kubernetes/pkg/util/dbus/doc.go
generated
vendored
Normal file
18
vendor/k8s.io/kubernetes/pkg/util/dbus/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2015 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 dbus provides an injectable interface and implementations for D-Bus communication
|
||||
package dbus // import "k8s.io/kubernetes/pkg/util/dbus"
|
135
vendor/k8s.io/kubernetes/pkg/util/dbus/fake_dbus.go
generated
vendored
Normal file
135
vendor/k8s.io/kubernetes/pkg/util/dbus/fake_dbus.go
generated
vendored
Normal file
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
Copyright 2015 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 dbus
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
godbus "github.com/godbus/dbus"
|
||||
)
|
||||
|
||||
// DBusFake is a simple fake Interface type.
|
||||
type DBusFake struct {
|
||||
systemBus *DBusFakeConnection
|
||||
sessionBus *DBusFakeConnection
|
||||
}
|
||||
|
||||
// DBusFakeConnection represents a fake D-Bus connection
|
||||
type DBusFakeConnection struct {
|
||||
busObject *fakeObject
|
||||
objects map[string]*fakeObject
|
||||
signalHandlers []chan<- *godbus.Signal
|
||||
}
|
||||
|
||||
// DBusFakeHandler is used to handle fake D-Bus method calls
|
||||
type DBusFakeHandler func(method string, args ...interface{}) ([]interface{}, error)
|
||||
|
||||
type fakeObject struct {
|
||||
handler DBusFakeHandler
|
||||
}
|
||||
|
||||
type fakeCall struct {
|
||||
ret []interface{}
|
||||
err error
|
||||
}
|
||||
|
||||
// NewFake returns a new Interface which will fake talking to D-Bus
|
||||
func NewFake(systemBus *DBusFakeConnection, sessionBus *DBusFakeConnection) *DBusFake {
|
||||
return &DBusFake{systemBus, sessionBus}
|
||||
}
|
||||
|
||||
func NewFakeConnection() *DBusFakeConnection {
|
||||
return &DBusFakeConnection{
|
||||
objects: make(map[string]*fakeObject),
|
||||
}
|
||||
}
|
||||
|
||||
// SystemBus is part of Interface
|
||||
func (db *DBusFake) SystemBus() (Connection, error) {
|
||||
if db.systemBus != nil {
|
||||
return db.systemBus, nil
|
||||
} else {
|
||||
return nil, fmt.Errorf("DBus is not running")
|
||||
}
|
||||
}
|
||||
|
||||
// SessionBus is part of Interface
|
||||
func (db *DBusFake) SessionBus() (Connection, error) {
|
||||
if db.sessionBus != nil {
|
||||
return db.sessionBus, nil
|
||||
} else {
|
||||
return nil, fmt.Errorf("DBus is not running")
|
||||
}
|
||||
}
|
||||
|
||||
// BusObject is part of the Connection interface
|
||||
func (conn *DBusFakeConnection) BusObject() Object {
|
||||
return conn.busObject
|
||||
}
|
||||
|
||||
// Object is part of the Connection interface
|
||||
func (conn *DBusFakeConnection) Object(name, path string) Object {
|
||||
return conn.objects[name+path]
|
||||
}
|
||||
|
||||
// Signal is part of the Connection interface
|
||||
func (conn *DBusFakeConnection) Signal(ch chan<- *godbus.Signal) {
|
||||
for i := range conn.signalHandlers {
|
||||
if conn.signalHandlers[i] == ch {
|
||||
conn.signalHandlers = append(conn.signalHandlers[:i], conn.signalHandlers[i+1:]...)
|
||||
return
|
||||
}
|
||||
}
|
||||
conn.signalHandlers = append(conn.signalHandlers, ch)
|
||||
}
|
||||
|
||||
// SetBusObject sets the handler for the BusObject of conn
|
||||
func (conn *DBusFakeConnection) SetBusObject(handler DBusFakeHandler) {
|
||||
conn.busObject = &fakeObject{handler}
|
||||
}
|
||||
|
||||
// AddObject adds a handler for the Object at name and path
|
||||
func (conn *DBusFakeConnection) AddObject(name, path string, handler DBusFakeHandler) {
|
||||
conn.objects[name+path] = &fakeObject{handler}
|
||||
}
|
||||
|
||||
// EmitSignal emits a signal on conn
|
||||
func (conn *DBusFakeConnection) EmitSignal(name, path, iface, signal string, args ...interface{}) {
|
||||
sig := &godbus.Signal{
|
||||
Sender: name,
|
||||
Path: godbus.ObjectPath(path),
|
||||
Name: iface + "." + signal,
|
||||
Body: args,
|
||||
}
|
||||
for _, ch := range conn.signalHandlers {
|
||||
ch <- sig
|
||||
}
|
||||
}
|
||||
|
||||
// Call is part of the Object interface
|
||||
func (obj *fakeObject) Call(method string, flags godbus.Flags, args ...interface{}) Call {
|
||||
ret, err := obj.handler(method, args...)
|
||||
return &fakeCall{ret, err}
|
||||
}
|
||||
|
||||
// Store is part of the Call interface
|
||||
func (call *fakeCall) Store(retvalues ...interface{}) error {
|
||||
if call.err != nil {
|
||||
return call.err
|
||||
}
|
||||
return godbus.Store(call.ret, retvalues...)
|
||||
}
|
18
vendor/k8s.io/kubernetes/pkg/util/iptables/doc.go
generated
vendored
Normal file
18
vendor/k8s.io/kubernetes/pkg/util/iptables/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2014 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 iptables provides an interface and implementations for running iptables commands.
|
||||
package iptables // import "k8s.io/kubernetes/pkg/util/iptables"
|
581
vendor/k8s.io/kubernetes/pkg/util/iptables/iptables.go
generated
vendored
Normal file
581
vendor/k8s.io/kubernetes/pkg/util/iptables/iptables.go
generated
vendored
Normal file
|
@ -0,0 +1,581 @@
|
|||
/*
|
||||
Copyright 2014 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 iptables
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
godbus "github.com/godbus/dbus"
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
utildbus "k8s.io/kubernetes/pkg/util/dbus"
|
||||
utilexec "k8s.io/kubernetes/pkg/util/exec"
|
||||
utilversion "k8s.io/kubernetes/pkg/util/version"
|
||||
)
|
||||
|
||||
type RulePosition string
|
||||
|
||||
const (
|
||||
Prepend RulePosition = "-I"
|
||||
Append RulePosition = "-A"
|
||||
)
|
||||
|
||||
// An injectable interface for running iptables commands. Implementations must be goroutine-safe.
|
||||
type Interface interface {
|
||||
// GetVersion returns the "X.Y.Z" version string for iptables.
|
||||
GetVersion() (string, error)
|
||||
// EnsureChain checks if the specified chain exists and, if not, creates it. If the chain existed, return true.
|
||||
EnsureChain(table Table, chain Chain) (bool, error)
|
||||
// FlushChain clears the specified chain. If the chain did not exist, return error.
|
||||
FlushChain(table Table, chain Chain) error
|
||||
// DeleteChain deletes the specified chain. If the chain did not exist, return error.
|
||||
DeleteChain(table Table, chain Chain) error
|
||||
// EnsureRule checks if the specified rule is present and, if not, creates it. If the rule existed, return true.
|
||||
EnsureRule(position RulePosition, table Table, chain Chain, args ...string) (bool, error)
|
||||
// DeleteRule checks if the specified rule is present and, if so, deletes it.
|
||||
DeleteRule(table Table, chain Chain, args ...string) error
|
||||
// IsIpv6 returns true if this is managing ipv6 tables
|
||||
IsIpv6() bool
|
||||
// Save calls `iptables-save` for table.
|
||||
Save(table Table) ([]byte, error)
|
||||
// SaveAll calls `iptables-save`.
|
||||
SaveAll() ([]byte, error)
|
||||
// Restore runs `iptables-restore` passing data through []byte.
|
||||
// table is the Table to restore
|
||||
// data should be formatted like the output of Save()
|
||||
// flush sets the presence of the "--noflush" flag. see: FlushFlag
|
||||
// counters sets the "--counters" flag. see: RestoreCountersFlag
|
||||
Restore(table Table, data []byte, flush FlushFlag, counters RestoreCountersFlag) error
|
||||
// RestoreAll is the same as Restore except that no table is specified.
|
||||
RestoreAll(data []byte, flush FlushFlag, counters RestoreCountersFlag) error
|
||||
// AddReloadFunc adds a function to call on iptables reload
|
||||
AddReloadFunc(reloadFunc func())
|
||||
// Destroy cleans up resources used by the Interface
|
||||
Destroy()
|
||||
}
|
||||
|
||||
type Protocol byte
|
||||
|
||||
const (
|
||||
ProtocolIpv4 Protocol = iota + 1
|
||||
ProtocolIpv6
|
||||
)
|
||||
|
||||
type Table string
|
||||
|
||||
const (
|
||||
TableNAT Table = "nat"
|
||||
TableFilter Table = "filter"
|
||||
)
|
||||
|
||||
type Chain string
|
||||
|
||||
const (
|
||||
ChainPostrouting Chain = "POSTROUTING"
|
||||
ChainPrerouting Chain = "PREROUTING"
|
||||
ChainOutput Chain = "OUTPUT"
|
||||
ChainInput Chain = "INPUT"
|
||||
)
|
||||
|
||||
const (
|
||||
cmdIPTablesSave string = "iptables-save"
|
||||
cmdIPTablesRestore string = "iptables-restore"
|
||||
cmdIPTables string = "iptables"
|
||||
cmdIp6tables string = "ip6tables"
|
||||
)
|
||||
|
||||
// Option flag for Restore
|
||||
type RestoreCountersFlag bool
|
||||
|
||||
const RestoreCounters RestoreCountersFlag = true
|
||||
const NoRestoreCounters RestoreCountersFlag = false
|
||||
|
||||
// Option flag for Flush
|
||||
type FlushFlag bool
|
||||
|
||||
const FlushTables FlushFlag = true
|
||||
const NoFlushTables FlushFlag = false
|
||||
|
||||
// Versions of iptables less than this do not support the -C / --check flag
|
||||
// (test whether a rule exists).
|
||||
const MinCheckVersion = "1.4.11"
|
||||
|
||||
// Minimum iptables versions supporting the -w and -w2 flags
|
||||
const MinWaitVersion = "1.4.20"
|
||||
const MinWait2Version = "1.4.22"
|
||||
|
||||
// runner implements Interface in terms of exec("iptables").
|
||||
type runner struct {
|
||||
mu sync.Mutex
|
||||
exec utilexec.Interface
|
||||
dbus utildbus.Interface
|
||||
protocol Protocol
|
||||
hasCheck bool
|
||||
waitFlag []string
|
||||
|
||||
reloadFuncs []func()
|
||||
signal chan *godbus.Signal
|
||||
}
|
||||
|
||||
// New returns a new Interface which will exec iptables.
|
||||
func New(exec utilexec.Interface, dbus utildbus.Interface, protocol Protocol) Interface {
|
||||
vstring, err := getIPTablesVersionString(exec)
|
||||
if err != nil {
|
||||
glog.Warningf("Error checking iptables version, assuming version at least %s: %v", MinCheckVersion, err)
|
||||
vstring = MinCheckVersion
|
||||
}
|
||||
runner := &runner{
|
||||
exec: exec,
|
||||
dbus: dbus,
|
||||
protocol: protocol,
|
||||
hasCheck: getIPTablesHasCheckCommand(vstring),
|
||||
waitFlag: getIPTablesWaitFlag(vstring),
|
||||
}
|
||||
runner.connectToFirewallD()
|
||||
return runner
|
||||
}
|
||||
|
||||
// Destroy is part of Interface.
|
||||
func (runner *runner) Destroy() {
|
||||
if runner.signal != nil {
|
||||
runner.signal <- nil
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
firewalldName = "org.fedoraproject.FirewallD1"
|
||||
firewalldPath = "/org/fedoraproject/FirewallD1"
|
||||
firewalldInterface = "org.fedoraproject.FirewallD1"
|
||||
)
|
||||
|
||||
// Connects to D-Bus and listens for FirewallD start/restart. (On non-FirewallD-using
|
||||
// systems, this is effectively a no-op; we listen for the signals, but they will never be
|
||||
// emitted, so reload() will never be called.)
|
||||
func (runner *runner) connectToFirewallD() {
|
||||
bus, err := runner.dbus.SystemBus()
|
||||
if err != nil {
|
||||
glog.V(1).Infof("Could not connect to D-Bus system bus: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
rule := fmt.Sprintf("type='signal',sender='%s',path='%s',interface='%s',member='Reloaded'", firewalldName, firewalldPath, firewalldInterface)
|
||||
bus.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, rule)
|
||||
|
||||
rule = fmt.Sprintf("type='signal',interface='org.freedesktop.DBus',member='NameOwnerChanged',path='/org/freedesktop/DBus',sender='org.freedesktop.DBus',arg0='%s'", firewalldName)
|
||||
bus.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, rule)
|
||||
|
||||
runner.signal = make(chan *godbus.Signal, 10)
|
||||
bus.Signal(runner.signal)
|
||||
|
||||
go runner.dbusSignalHandler(bus)
|
||||
}
|
||||
|
||||
// GetVersion returns the version string.
|
||||
func (runner *runner) GetVersion() (string, error) {
|
||||
return getIPTablesVersionString(runner.exec)
|
||||
}
|
||||
|
||||
// EnsureChain is part of Interface.
|
||||
func (runner *runner) EnsureChain(table Table, chain Chain) (bool, error) {
|
||||
fullArgs := makeFullArgs(table, chain)
|
||||
|
||||
runner.mu.Lock()
|
||||
defer runner.mu.Unlock()
|
||||
|
||||
out, err := runner.run(opCreateChain, fullArgs)
|
||||
if err != nil {
|
||||
if ee, ok := err.(utilexec.ExitError); ok {
|
||||
if ee.Exited() && ee.ExitStatus() == 1 {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, fmt.Errorf("error creating chain %q: %v: %s", chain, err, out)
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// FlushChain is part of Interface.
|
||||
func (runner *runner) FlushChain(table Table, chain Chain) error {
|
||||
fullArgs := makeFullArgs(table, chain)
|
||||
|
||||
runner.mu.Lock()
|
||||
defer runner.mu.Unlock()
|
||||
|
||||
out, err := runner.run(opFlushChain, fullArgs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error flushing chain %q: %v: %s", chain, err, out)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteChain is part of Interface.
|
||||
func (runner *runner) DeleteChain(table Table, chain Chain) error {
|
||||
fullArgs := makeFullArgs(table, chain)
|
||||
|
||||
runner.mu.Lock()
|
||||
defer runner.mu.Unlock()
|
||||
|
||||
// TODO: we could call iptables -S first, ignore the output and check for non-zero return (more like DeleteRule)
|
||||
out, err := runner.run(opDeleteChain, fullArgs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error deleting chain %q: %v: %s", chain, err, out)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// EnsureRule is part of Interface.
|
||||
func (runner *runner) EnsureRule(position RulePosition, table Table, chain Chain, args ...string) (bool, error) {
|
||||
fullArgs := makeFullArgs(table, chain, args...)
|
||||
|
||||
runner.mu.Lock()
|
||||
defer runner.mu.Unlock()
|
||||
|
||||
exists, err := runner.checkRule(table, chain, args...)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if exists {
|
||||
return true, nil
|
||||
}
|
||||
out, err := runner.run(operation(position), fullArgs)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("error appending rule: %v: %s", err, out)
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// DeleteRule is part of Interface.
|
||||
func (runner *runner) DeleteRule(table Table, chain Chain, args ...string) error {
|
||||
fullArgs := makeFullArgs(table, chain, args...)
|
||||
|
||||
runner.mu.Lock()
|
||||
defer runner.mu.Unlock()
|
||||
|
||||
exists, err := runner.checkRule(table, chain, args...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !exists {
|
||||
return nil
|
||||
}
|
||||
out, err := runner.run(opDeleteRule, fullArgs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error deleting rule: %v: %s", err, out)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (runner *runner) IsIpv6() bool {
|
||||
return runner.protocol == ProtocolIpv6
|
||||
}
|
||||
|
||||
// Save is part of Interface.
|
||||
func (runner *runner) Save(table Table) ([]byte, error) {
|
||||
runner.mu.Lock()
|
||||
defer runner.mu.Unlock()
|
||||
|
||||
// run and return
|
||||
args := []string{"-t", string(table)}
|
||||
glog.V(4).Infof("running iptables-save %v", args)
|
||||
return runner.exec.Command(cmdIPTablesSave, args...).CombinedOutput()
|
||||
}
|
||||
|
||||
// SaveAll is part of Interface.
|
||||
func (runner *runner) SaveAll() ([]byte, error) {
|
||||
runner.mu.Lock()
|
||||
defer runner.mu.Unlock()
|
||||
|
||||
// run and return
|
||||
glog.V(4).Infof("running iptables-save")
|
||||
return runner.exec.Command(cmdIPTablesSave, []string{}...).CombinedOutput()
|
||||
}
|
||||
|
||||
// Restore is part of Interface.
|
||||
func (runner *runner) Restore(table Table, data []byte, flush FlushFlag, counters RestoreCountersFlag) error {
|
||||
// setup args
|
||||
args := []string{"-T", string(table)}
|
||||
return runner.restoreInternal(args, data, flush, counters)
|
||||
}
|
||||
|
||||
// RestoreAll is part of Interface.
|
||||
func (runner *runner) RestoreAll(data []byte, flush FlushFlag, counters RestoreCountersFlag) error {
|
||||
// setup args
|
||||
args := make([]string, 0)
|
||||
return runner.restoreInternal(args, data, flush, counters)
|
||||
}
|
||||
|
||||
// restoreInternal is the shared part of Restore/RestoreAll
|
||||
func (runner *runner) restoreInternal(args []string, data []byte, flush FlushFlag, counters RestoreCountersFlag) error {
|
||||
runner.mu.Lock()
|
||||
defer runner.mu.Unlock()
|
||||
|
||||
if !flush {
|
||||
args = append(args, "--noflush")
|
||||
}
|
||||
if counters {
|
||||
args = append(args, "--counters")
|
||||
}
|
||||
|
||||
// run the command and return the output or an error including the output and error
|
||||
glog.V(4).Infof("running iptables-restore %v", args)
|
||||
cmd := runner.exec.Command(cmdIPTablesRestore, args...)
|
||||
cmd.SetStdin(bytes.NewBuffer(data))
|
||||
b, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("%v (%s)", err, b)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (runner *runner) iptablesCommand() string {
|
||||
if runner.IsIpv6() {
|
||||
return cmdIp6tables
|
||||
} else {
|
||||
return cmdIPTables
|
||||
}
|
||||
}
|
||||
|
||||
func (runner *runner) run(op operation, args []string) ([]byte, error) {
|
||||
iptablesCmd := runner.iptablesCommand()
|
||||
|
||||
fullArgs := append(runner.waitFlag, string(op))
|
||||
fullArgs = append(fullArgs, args...)
|
||||
glog.V(4).Infof("running iptables %s %v", string(op), args)
|
||||
return runner.exec.Command(iptablesCmd, fullArgs...).CombinedOutput()
|
||||
// Don't log err here - callers might not think it is an error.
|
||||
}
|
||||
|
||||
// Returns (bool, nil) if it was able to check the existence of the rule, or
|
||||
// (<undefined>, error) if the process of checking failed.
|
||||
func (runner *runner) checkRule(table Table, chain Chain, args ...string) (bool, error) {
|
||||
if runner.hasCheck {
|
||||
return runner.checkRuleUsingCheck(makeFullArgs(table, chain, args...))
|
||||
} else {
|
||||
return runner.checkRuleWithoutCheck(table, chain, args...)
|
||||
}
|
||||
}
|
||||
|
||||
var hexnumRE = regexp.MustCompile("0x0+([0-9])")
|
||||
|
||||
func trimhex(s string) string {
|
||||
return hexnumRE.ReplaceAllString(s, "0x$1")
|
||||
}
|
||||
|
||||
// Executes the rule check without using the "-C" flag, instead parsing iptables-save.
|
||||
// Present for compatibility with <1.4.11 versions of iptables. This is full
|
||||
// of hack and half-measures. We should nix this ASAP.
|
||||
func (runner *runner) checkRuleWithoutCheck(table Table, chain Chain, args ...string) (bool, error) {
|
||||
glog.V(1).Infof("running iptables-save -t %s", string(table))
|
||||
out, err := runner.exec.Command(cmdIPTablesSave, "-t", string(table)).CombinedOutput()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("error checking rule: %v", err)
|
||||
}
|
||||
|
||||
// Sadly, iptables has inconsistent quoting rules for comments. Just remove all quotes.
|
||||
// Also, quoted multi-word comments (which are counted as a single arg)
|
||||
// will be unpacked into multiple args,
|
||||
// in order to compare against iptables-save output (which will be split at whitespace boundary)
|
||||
// e.g. a single arg('"this must be before the NodePort rules"') will be unquoted and unpacked into 7 args.
|
||||
var argsCopy []string
|
||||
for i := range args {
|
||||
tmpField := strings.Trim(args[i], "\"")
|
||||
tmpField = trimhex(tmpField)
|
||||
argsCopy = append(argsCopy, strings.Fields(tmpField)...)
|
||||
}
|
||||
argset := sets.NewString(argsCopy...)
|
||||
|
||||
for _, line := range strings.Split(string(out), "\n") {
|
||||
var fields = strings.Fields(line)
|
||||
|
||||
// Check that this is a rule for the correct chain, and that it has
|
||||
// the correct number of argument (+2 for "-A <chain name>")
|
||||
if !strings.HasPrefix(line, fmt.Sprintf("-A %s", string(chain))) || len(fields) != len(argsCopy)+2 {
|
||||
continue
|
||||
}
|
||||
|
||||
// Sadly, iptables has inconsistent quoting rules for comments.
|
||||
// Just remove all quotes.
|
||||
for i := range fields {
|
||||
fields[i] = strings.Trim(fields[i], "\"")
|
||||
fields[i] = trimhex(fields[i])
|
||||
}
|
||||
|
||||
// TODO: This misses reorderings e.g. "-x foo ! -y bar" will match "! -x foo -y bar"
|
||||
if sets.NewString(fields...).IsSuperset(argset) {
|
||||
return true, nil
|
||||
}
|
||||
glog.V(5).Infof("DBG: fields is not a superset of args: fields=%v args=%v", fields, args)
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// Executes the rule check using the "-C" flag
|
||||
func (runner *runner) checkRuleUsingCheck(args []string) (bool, error) {
|
||||
out, err := runner.run(opCheckRule, args)
|
||||
if err == nil {
|
||||
return true, nil
|
||||
}
|
||||
if ee, ok := err.(utilexec.ExitError); ok {
|
||||
// iptables uses exit(1) to indicate a failure of the operation,
|
||||
// as compared to a malformed commandline, for example.
|
||||
if ee.Exited() && ee.ExitStatus() == 1 {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return false, fmt.Errorf("error checking rule: %v: %s", err, out)
|
||||
}
|
||||
|
||||
type operation string
|
||||
|
||||
const (
|
||||
opCreateChain operation = "-N"
|
||||
opFlushChain operation = "-F"
|
||||
opDeleteChain operation = "-X"
|
||||
opAppendRule operation = "-A"
|
||||
opCheckRule operation = "-C"
|
||||
opDeleteRule operation = "-D"
|
||||
)
|
||||
|
||||
func makeFullArgs(table Table, chain Chain, args ...string) []string {
|
||||
return append([]string{string(chain), "-t", string(table)}, args...)
|
||||
}
|
||||
|
||||
// Checks if iptables has the "-C" flag
|
||||
func getIPTablesHasCheckCommand(vstring string) bool {
|
||||
minVersion, err := utilversion.ParseGeneric(MinCheckVersion)
|
||||
if err != nil {
|
||||
glog.Errorf("MinCheckVersion (%s) is not a valid version string: %v", MinCheckVersion, err)
|
||||
return true
|
||||
}
|
||||
version, err := utilversion.ParseGeneric(vstring)
|
||||
if err != nil {
|
||||
glog.Errorf("vstring (%s) is not a valid version string: %v", vstring, err)
|
||||
return true
|
||||
}
|
||||
return version.AtLeast(minVersion)
|
||||
}
|
||||
|
||||
// Checks if iptables version has a "wait" flag
|
||||
func getIPTablesWaitFlag(vstring string) []string {
|
||||
version, err := utilversion.ParseGeneric(vstring)
|
||||
if err != nil {
|
||||
glog.Errorf("vstring (%s) is not a valid version string: %v", vstring, err)
|
||||
return nil
|
||||
}
|
||||
|
||||
minVersion, err := utilversion.ParseGeneric(MinWaitVersion)
|
||||
if err != nil {
|
||||
glog.Errorf("MinWaitVersion (%s) is not a valid version string: %v", MinWaitVersion, err)
|
||||
return nil
|
||||
}
|
||||
if version.LessThan(minVersion) {
|
||||
return nil
|
||||
}
|
||||
|
||||
minVersion, err = utilversion.ParseGeneric(MinWait2Version)
|
||||
if err != nil {
|
||||
glog.Errorf("MinWait2Version (%s) is not a valid version string: %v", MinWait2Version, err)
|
||||
return nil
|
||||
}
|
||||
if version.LessThan(minVersion) {
|
||||
return []string{"-w"}
|
||||
} else {
|
||||
return []string{"-w2"}
|
||||
}
|
||||
}
|
||||
|
||||
// getIPTablesVersionString runs "iptables --version" to get the version string
|
||||
// in the form "X.X.X"
|
||||
func getIPTablesVersionString(exec utilexec.Interface) (string, error) {
|
||||
// this doesn't access mutable state so we don't need to use the interface / runner
|
||||
bytes, err := exec.Command(cmdIPTables, "--version").CombinedOutput()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
versionMatcher := regexp.MustCompile("v([0-9]+(\\.[0-9]+)+)")
|
||||
match := versionMatcher.FindStringSubmatch(string(bytes))
|
||||
if match == nil {
|
||||
return "", fmt.Errorf("no iptables version found in string: %s", bytes)
|
||||
}
|
||||
return match[1], nil
|
||||
}
|
||||
|
||||
// goroutine to listen for D-Bus signals
|
||||
func (runner *runner) dbusSignalHandler(bus utildbus.Connection) {
|
||||
firewalld := bus.Object(firewalldName, firewalldPath)
|
||||
|
||||
for s := range runner.signal {
|
||||
if s == nil {
|
||||
// Unregister
|
||||
bus.Signal(runner.signal)
|
||||
return
|
||||
}
|
||||
|
||||
switch s.Name {
|
||||
case "org.freedesktop.DBus.NameOwnerChanged":
|
||||
name := s.Body[0].(string)
|
||||
new_owner := s.Body[2].(string)
|
||||
|
||||
if name != firewalldName || len(new_owner) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// FirewallD startup (specifically the part where it deletes
|
||||
// all existing iptables rules) may not yet be complete when
|
||||
// we get this signal, so make a dummy request to it to
|
||||
// synchronize.
|
||||
firewalld.Call(firewalldInterface+".getDefaultZone", 0)
|
||||
|
||||
runner.reload()
|
||||
case firewalldInterface + ".Reloaded":
|
||||
runner.reload()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AddReloadFunc is part of Interface
|
||||
func (runner *runner) AddReloadFunc(reloadFunc func()) {
|
||||
runner.reloadFuncs = append(runner.reloadFuncs, reloadFunc)
|
||||
}
|
||||
|
||||
// runs all reload funcs to re-sync iptables rules
|
||||
func (runner *runner) reload() {
|
||||
glog.V(1).Infof("reloading iptables rules")
|
||||
|
||||
for _, f := range runner.reloadFuncs {
|
||||
f()
|
||||
}
|
||||
}
|
||||
|
||||
// IsNotFoundError returns true if the error indicates "not found". It parses
|
||||
// the error string looking for known values, which is imperfect but works in
|
||||
// practice.
|
||||
func IsNotFoundError(err error) bool {
|
||||
es := err.Error()
|
||||
if strings.Contains(es, "No such file or directory") {
|
||||
return true
|
||||
}
|
||||
if strings.Contains(es, "No chain/target/match by that name") {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
108
vendor/k8s.io/kubernetes/pkg/util/iptables/save_restore.go
generated
vendored
Normal file
108
vendor/k8s.io/kubernetes/pkg/util/iptables/save_restore.go
generated
vendored
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
Copyright 2014 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 iptables
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// MakeChainLine return an iptables-save/restore formatted chain line given a Chain
|
||||
func MakeChainLine(chain Chain) string {
|
||||
return fmt.Sprintf(":%s - [0:0]", chain)
|
||||
}
|
||||
|
||||
// GetChainLines parses a table's iptables-save data to find chains in the table.
|
||||
// It returns a map of iptables.Chain to string where the string is the chain line from the save (with counters etc).
|
||||
func GetChainLines(table Table, save []byte) map[Chain]string {
|
||||
chainsMap := make(map[Chain]string)
|
||||
tablePrefix := "*" + string(table)
|
||||
readIndex := 0
|
||||
// find beginning of table
|
||||
for readIndex < len(save) {
|
||||
line, n := ReadLine(readIndex, save)
|
||||
readIndex = n
|
||||
if strings.HasPrefix(line, tablePrefix) {
|
||||
break
|
||||
}
|
||||
}
|
||||
// parse table lines
|
||||
for readIndex < len(save) {
|
||||
line, n := ReadLine(readIndex, save)
|
||||
readIndex = n
|
||||
if len(line) == 0 {
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(line, "COMMIT") || strings.HasPrefix(line, "*") {
|
||||
break
|
||||
} else if strings.HasPrefix(line, "#") {
|
||||
continue
|
||||
} else if strings.HasPrefix(line, ":") && len(line) > 1 {
|
||||
chain := Chain(strings.SplitN(line[1:], " ", 2)[0])
|
||||
chainsMap[chain] = line
|
||||
}
|
||||
}
|
||||
return chainsMap
|
||||
}
|
||||
|
||||
func ReadLine(readIndex int, byteArray []byte) (string, int) {
|
||||
currentReadIndex := readIndex
|
||||
|
||||
// consume left spaces
|
||||
for currentReadIndex < len(byteArray) {
|
||||
if byteArray[currentReadIndex] == ' ' {
|
||||
currentReadIndex++
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// leftTrimIndex stores the left index of the line after the line is left-trimmed
|
||||
leftTrimIndex := currentReadIndex
|
||||
|
||||
// rightTrimIndex stores the right index of the line after the line is right-trimmed
|
||||
// it is set to -1 since the correct value has not yet been determined.
|
||||
rightTrimIndex := -1
|
||||
|
||||
for ; currentReadIndex < len(byteArray); currentReadIndex++ {
|
||||
if byteArray[currentReadIndex] == ' ' {
|
||||
// set rightTrimIndex
|
||||
if rightTrimIndex == -1 {
|
||||
rightTrimIndex = currentReadIndex
|
||||
}
|
||||
} else if (byteArray[currentReadIndex] == '\n') || (currentReadIndex == (len(byteArray) - 1)) {
|
||||
// end of line or byte buffer is reached
|
||||
if currentReadIndex <= leftTrimIndex {
|
||||
return "", currentReadIndex + 1
|
||||
}
|
||||
// set the rightTrimIndex
|
||||
if rightTrimIndex == -1 {
|
||||
rightTrimIndex = currentReadIndex
|
||||
if currentReadIndex == (len(byteArray)-1) && (byteArray[currentReadIndex] != '\n') {
|
||||
// ensure that the last character is part of the returned string,
|
||||
// unless the last character is '\n'
|
||||
rightTrimIndex = currentReadIndex + 1
|
||||
}
|
||||
}
|
||||
return string(byteArray[leftTrimIndex:rightTrimIndex]), currentReadIndex + 1
|
||||
} else {
|
||||
// unset rightTrimIndex
|
||||
rightTrimIndex = -1
|
||||
}
|
||||
}
|
||||
return "", currentReadIndex
|
||||
}
|
28
vendor/k8s.io/kubernetes/pkg/util/net/sets/doc.go
generated
vendored
Normal file
28
vendor/k8s.io/kubernetes/pkg/util/net/sets/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// This package contains hand-coded set implementations that should be similar
|
||||
// to the autogenerated ones in pkg/util/sets.
|
||||
// We can't simply use net.IPNet as a map-key in Go (because it contains a
|
||||
// []byte).
|
||||
// We could use the same workaround we use here (a string representation as the
|
||||
// key) to autogenerate sets. If we do that, or decide on an alternate
|
||||
// approach, we should replace the implementations in this package with the
|
||||
// autogenerated versions.
|
||||
// It is expected that callers will alias this import as "netsets" i.e. import
|
||||
// netsets "k8s.io/kubernetes/pkg/util/net/sets"
|
||||
|
||||
package sets
|
119
vendor/k8s.io/kubernetes/pkg/util/net/sets/ipnet.go
generated
vendored
Normal file
119
vendor/k8s.io/kubernetes/pkg/util/net/sets/ipnet.go
generated
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
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 sets
|
||||
|
||||
import (
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type IPNet map[string]*net.IPNet
|
||||
|
||||
func ParseIPNets(specs ...string) (IPNet, error) {
|
||||
ipnetset := make(IPNet)
|
||||
for _, spec := range specs {
|
||||
spec = strings.TrimSpace(spec)
|
||||
_, ipnet, err := net.ParseCIDR(spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
k := ipnet.String() // In case of normalization
|
||||
ipnetset[k] = ipnet
|
||||
}
|
||||
return ipnetset, nil
|
||||
}
|
||||
|
||||
// Insert adds items to the set.
|
||||
func (s IPNet) Insert(items ...*net.IPNet) {
|
||||
for _, item := range items {
|
||||
s[item.String()] = item
|
||||
}
|
||||
}
|
||||
|
||||
// Delete removes all items from the set.
|
||||
func (s IPNet) Delete(items ...*net.IPNet) {
|
||||
for _, item := range items {
|
||||
delete(s, item.String())
|
||||
}
|
||||
}
|
||||
|
||||
// Has returns true if and only if item is contained in the set.
|
||||
func (s IPNet) Has(item *net.IPNet) bool {
|
||||
_, contained := s[item.String()]
|
||||
return contained
|
||||
}
|
||||
|
||||
// HasAll returns true if and only if all items are contained in the set.
|
||||
func (s IPNet) HasAll(items ...*net.IPNet) bool {
|
||||
for _, item := range items {
|
||||
if !s.Has(item) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Difference returns a set of objects that are not in s2
|
||||
// For example:
|
||||
// s1 = {a1, a2, a3}
|
||||
// s2 = {a1, a2, a4, a5}
|
||||
// s1.Difference(s2) = {a3}
|
||||
// s2.Difference(s1) = {a4, a5}
|
||||
func (s IPNet) Difference(s2 IPNet) IPNet {
|
||||
result := make(IPNet)
|
||||
for k, i := range s {
|
||||
_, found := s2[k]
|
||||
if found {
|
||||
continue
|
||||
}
|
||||
result[k] = i
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// StringSlice returns a []string with the String representation of each element in the set.
|
||||
// Order is undefined.
|
||||
func (s IPNet) StringSlice() []string {
|
||||
a := make([]string, 0, len(s))
|
||||
for k := range s {
|
||||
a = append(a, k)
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
// IsSuperset returns true if and only if s1 is a superset of s2.
|
||||
func (s1 IPNet) IsSuperset(s2 IPNet) bool {
|
||||
for k := range s2 {
|
||||
_, found := s1[k]
|
||||
if !found {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Equal returns true if and only if s1 is equal (as a set) to s2.
|
||||
// Two sets are equal if their membership is identical.
|
||||
// (In practice, this means same elements, order doesn't matter)
|
||||
func (s1 IPNet) Equal(s2 IPNet) bool {
|
||||
return len(s1) == len(s2) && s1.IsSuperset(s2)
|
||||
}
|
||||
|
||||
// Len returns the size of the set.
|
||||
func (s IPNet) Len() int {
|
||||
return len(s)
|
||||
}
|
73
vendor/k8s.io/kubernetes/pkg/util/sysctl/sysctl.go
generated
vendored
Normal file
73
vendor/k8s.io/kubernetes/pkg/util/sysctl/sysctl.go
generated
vendored
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
Copyright 2015 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 sysctl
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
sysctlBase = "/proc/sys"
|
||||
VmOvercommitMemory = "vm/overcommit_memory"
|
||||
VmPanicOnOOM = "vm/panic_on_oom"
|
||||
KernelPanic = "kernel/panic"
|
||||
KernelPanicOnOops = "kernel/panic_on_oops"
|
||||
|
||||
VmOvercommitMemoryAlways = 1 // kernel performs no memory over-commit handling
|
||||
VmPanicOnOOMInvokeOOMKiller = 0 // kernel calls the oom_killer function when OOM occurs
|
||||
|
||||
KernelPanicOnOopsAlways = 1 // kernel panics on kernel oops
|
||||
KernelPanicRebootTimeout = 10 // seconds after a panic for the kernel to reboot
|
||||
)
|
||||
|
||||
// An injectable interface for running sysctl commands.
|
||||
type Interface interface {
|
||||
// GetSysctl returns the value for the specified sysctl setting
|
||||
GetSysctl(sysctl string) (int, error)
|
||||
// SetSysctl modifies the specified sysctl flag to the new value
|
||||
SetSysctl(sysctl string, newVal int) error
|
||||
}
|
||||
|
||||
// New returns a new Interface for accessing sysctl
|
||||
func New() Interface {
|
||||
return &procSysctl{}
|
||||
}
|
||||
|
||||
// procSysctl implements Interface by reading and writing files under /proc/sys
|
||||
type procSysctl struct {
|
||||
}
|
||||
|
||||
// GetSysctl returns the value for the specified sysctl setting
|
||||
func (_ *procSysctl) GetSysctl(sysctl string) (int, error) {
|
||||
data, err := ioutil.ReadFile(path.Join(sysctlBase, sysctl))
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
val, err := strconv.Atoi(strings.Trim(string(data), " \n"))
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
return val, nil
|
||||
}
|
||||
|
||||
// SetSysctl modifies the specified sysctl flag to the new value
|
||||
func (_ *procSysctl) SetSysctl(sysctl string, newVal int) error {
|
||||
return ioutil.WriteFile(path.Join(sysctlBase, sysctl), []byte(strconv.Itoa(newVal)), 0640)
|
||||
}
|
18
vendor/k8s.io/kubernetes/pkg/util/version/doc.go
generated
vendored
Normal file
18
vendor/k8s.io/kubernetes/pkg/util/version/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
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 version provides utilities for version number comparisons
|
||||
package version // import "k8s.io/kubernetes/pkg/util/version"
|
236
vendor/k8s.io/kubernetes/pkg/util/version/version.go
generated
vendored
Normal file
236
vendor/k8s.io/kubernetes/pkg/util/version/version.go
generated
vendored
Normal file
|
@ -0,0 +1,236 @@
|
|||
/*
|
||||
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 version
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Version is an opqaue representation of a version number
|
||||
type Version struct {
|
||||
components []uint
|
||||
semver bool
|
||||
preRelease string
|
||||
buildMetadata string
|
||||
}
|
||||
|
||||
var (
|
||||
// versionMatchRE splits a version string into numeric and "extra" parts
|
||||
versionMatchRE = regexp.MustCompile(`^\s*v?([0-9]+(?:\.[0-9]+)*)(.*)*$`)
|
||||
// extraMatchRE splits the "extra" part of versionMatchRE into semver pre-release and build metadata; it does not validate the "no leading zeroes" constraint for pre-release
|
||||
extraMatchRE = regexp.MustCompile(`^(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?\s*$`)
|
||||
)
|
||||
|
||||
func parse(str string, semver bool) (*Version, error) {
|
||||
parts := versionMatchRE.FindStringSubmatch(str)
|
||||
if parts == nil {
|
||||
return nil, fmt.Errorf("could not parse %q as version", str)
|
||||
}
|
||||
numbers, extra := parts[1], parts[2]
|
||||
|
||||
components := strings.Split(numbers, ".")
|
||||
if (semver && len(components) != 3) || (!semver && len(components) < 2) {
|
||||
return nil, fmt.Errorf("illegal version string %q", str)
|
||||
}
|
||||
|
||||
v := &Version{
|
||||
components: make([]uint, len(components)),
|
||||
semver: semver,
|
||||
}
|
||||
for i, comp := range components {
|
||||
if (i == 0 || semver) && strings.HasPrefix(comp, "0") && comp != "0" {
|
||||
return nil, fmt.Errorf("illegal zero-prefixed version component %q in %q", comp, str)
|
||||
}
|
||||
num, err := strconv.ParseUint(comp, 10, 0)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("illegal non-numeric version component %q in %q: %v", comp, str, err)
|
||||
}
|
||||
v.components[i] = uint(num)
|
||||
}
|
||||
|
||||
if semver && extra != "" {
|
||||
extraParts := extraMatchRE.FindStringSubmatch(extra)
|
||||
if extraParts == nil {
|
||||
return nil, fmt.Errorf("could not parse pre-release/metadata (%s) in version %q", extra, str)
|
||||
}
|
||||
v.preRelease, v.buildMetadata = extraParts[1], extraParts[2]
|
||||
|
||||
for _, comp := range strings.Split(v.preRelease, ".") {
|
||||
if _, err := strconv.ParseUint(comp, 10, 0); err == nil {
|
||||
if strings.HasPrefix(comp, "0") && comp != "0" {
|
||||
return nil, fmt.Errorf("illegal zero-prefixed version component %q in %q", comp, str)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// ParseGeneric parses a "generic" version string. The version string must consist of two
|
||||
// or more dot-separated numeric fields (the first of which can't have leading zeroes),
|
||||
// followed by arbitrary uninterpreted data (which need not be separated from the final
|
||||
// numeric field by punctuation). For convenience, leading and trailing whitespace is
|
||||
// ignored, and the version can be preceded by the letter "v". See also ParseSemantic.
|
||||
func ParseGeneric(str string) (*Version, error) {
|
||||
return parse(str, false)
|
||||
}
|
||||
|
||||
// MustParseGeneric is like ParseGeneric except that it panics on error
|
||||
func MustParseGeneric(str string) *Version {
|
||||
v, err := ParseGeneric(str)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// ParseSemantic parses a version string that exactly obeys the syntax and semantics of
|
||||
// the "Semantic Versioning" specification (http://semver.org/) (although it ignores
|
||||
// leading and trailing whitespace, and allows the version to be preceded by "v"). For
|
||||
// version strings that are not guaranteed to obey the Semantic Versioning syntax, use
|
||||
// ParseGeneric.
|
||||
func ParseSemantic(str string) (*Version, error) {
|
||||
return parse(str, true)
|
||||
}
|
||||
|
||||
// MustParseSemantic is like ParseSemantic except that it panics on error
|
||||
func MustParseSemantic(str string) *Version {
|
||||
v, err := ParseSemantic(str)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// BuildMetadata returns the build metadata, if v is a Semantic Version, or ""
|
||||
func (v *Version) BuildMetadata() string {
|
||||
return v.buildMetadata
|
||||
}
|
||||
|
||||
// String converts a Version back to a string; note that for versions parsed with
|
||||
// ParseGeneric, this will not include the trailing uninterpreted portion of the version
|
||||
// number.
|
||||
func (v *Version) String() string {
|
||||
var buffer bytes.Buffer
|
||||
|
||||
for i, comp := range v.components {
|
||||
if i > 0 {
|
||||
buffer.WriteString(".")
|
||||
}
|
||||
buffer.WriteString(fmt.Sprintf("%d", comp))
|
||||
}
|
||||
if v.preRelease != "" {
|
||||
buffer.WriteString("-")
|
||||
buffer.WriteString(v.preRelease)
|
||||
}
|
||||
if v.buildMetadata != "" {
|
||||
buffer.WriteString("+")
|
||||
buffer.WriteString(v.buildMetadata)
|
||||
}
|
||||
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
// compareInternal returns -1 if v is less than other, 1 if it is greater than other, or 0
|
||||
// if they are equal
|
||||
func (v *Version) compareInternal(other *Version) int {
|
||||
for i := range v.components {
|
||||
switch {
|
||||
case i >= len(other.components):
|
||||
if v.components[i] != 0 {
|
||||
return 1
|
||||
}
|
||||
case other.components[i] < v.components[i]:
|
||||
return 1
|
||||
case other.components[i] > v.components[i]:
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
if !v.semver || !other.semver {
|
||||
return 0
|
||||
}
|
||||
|
||||
switch {
|
||||
case v.preRelease == "" && other.preRelease != "":
|
||||
return 1
|
||||
case v.preRelease != "" && other.preRelease == "":
|
||||
return -1
|
||||
case v.preRelease == other.preRelease: // includes case where both are ""
|
||||
return 0
|
||||
}
|
||||
|
||||
vPR := strings.Split(v.preRelease, ".")
|
||||
oPR := strings.Split(other.preRelease, ".")
|
||||
for i := range vPR {
|
||||
if i >= len(oPR) {
|
||||
return 1
|
||||
}
|
||||
vNum, err := strconv.ParseUint(vPR[i], 10, 0)
|
||||
if err == nil {
|
||||
oNum, err := strconv.ParseUint(oPR[i], 10, 0)
|
||||
if err == nil {
|
||||
switch {
|
||||
case oNum < vNum:
|
||||
return 1
|
||||
case oNum > vNum:
|
||||
return -1
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
if oPR[i] < vPR[i] {
|
||||
return 1
|
||||
} else if oPR[i] > vPR[i] {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
// AtLeast tests if a version is at least equal to a given minimum version. If both
|
||||
// Versions are Semantic Versions, this will use the Semantic Version comparison
|
||||
// algorithm. Otherwise, it will compare only the numeric components, with non-present
|
||||
// components being considered "0" (ie, "1.4" is equal to "1.4.0").
|
||||
func (v *Version) AtLeast(min *Version) bool {
|
||||
return v.compareInternal(min) != -1
|
||||
}
|
||||
|
||||
// LessThan tests if a version is less than a given version. (It is exactly the opposite
|
||||
// of AtLeast, for situations where asking "is v too old?" makes more sense than asking
|
||||
// "is v new enough?".)
|
||||
func (v *Version) LessThan(other *Version) bool {
|
||||
return v.compareInternal(other) == -1
|
||||
}
|
||||
|
||||
// Compare compares v against a version string (which will be parsed as either Semantic
|
||||
// or non-Semantic depending on v). On success it returns -1 if v is less than other, 1 if
|
||||
// it is greater than other, or 0 if they are equal.
|
||||
func (v *Version) Compare(other string) (int, error) {
|
||||
ov, err := parse(other, v.semver)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return v.compareInternal(ov), nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue