gomod: change projectcalico/calico to kubesphere/calico (#5557)
* chore(calico): update calico to 3.25.0 * chore(calico): replace projectcalico/calico to kubesphere/calico Signed-off-by: root <renyunkang@kubesphere.io> --------- Signed-off-by: root <renyunkang@kubesphere.io>
This commit is contained in:
58
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/bgp_node.go
generated
vendored
Normal file
58
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/bgp_node.go
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright (c) 2017 Tigera, Inc. All rights reserved.
|
||||
|
||||
// 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 model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
typeBGPNode = reflect.TypeOf(BGPNode{})
|
||||
)
|
||||
|
||||
type BGPNodeKey struct {
|
||||
Host string
|
||||
}
|
||||
|
||||
func (key BGPNodeKey) defaultPath() (string, error) {
|
||||
if key.Host == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "host"}
|
||||
}
|
||||
|
||||
k := "/calico/bgp/v1/host/" + key.Host
|
||||
return k, nil
|
||||
}
|
||||
|
||||
func (key BGPNodeKey) defaultDeletePath() (string, error) {
|
||||
return key.defaultPath()
|
||||
}
|
||||
|
||||
func (key BGPNodeKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (key BGPNodeKey) valueType() (reflect.Type, error) {
|
||||
return typeBGPNode, nil
|
||||
}
|
||||
|
||||
func (key BGPNodeKey) String() string {
|
||||
return fmt.Sprintf("BGPNodeKey(host=%s)", key.Host)
|
||||
}
|
||||
|
||||
type BGPNode struct {
|
||||
}
|
||||
162
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/bgpconfig.go
generated
vendored
Normal file
162
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/bgpconfig.go
generated
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
// Copyright (c) 2016 Tigera, Inc. All rights reserved.
|
||||
//
|
||||
// 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 model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
matchGlobalBGPConfig = regexp.MustCompile("^/?calico/bgp/v1/global/(.+)$")
|
||||
matchNodeBGPConfig = regexp.MustCompile("^/?calico/bgp/v1/host/([^/]+)/(.+)$")
|
||||
typeGlobalBGPConfig = rawStringType
|
||||
typeNodeBGPConfig = rawStringType
|
||||
)
|
||||
|
||||
type GlobalBGPConfigKey struct {
|
||||
// The name of the global BGP config key.
|
||||
Name string `json:"-" validate:"required,name"`
|
||||
}
|
||||
|
||||
func (key GlobalBGPConfigKey) defaultPath() (string, error) {
|
||||
return key.defaultDeletePath()
|
||||
}
|
||||
|
||||
func (key GlobalBGPConfigKey) defaultDeletePath() (string, error) {
|
||||
if key.Name == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "name"}
|
||||
}
|
||||
e := fmt.Sprintf("/calico/bgp/v1/global/%s", key.Name)
|
||||
return e, nil
|
||||
}
|
||||
|
||||
func (key GlobalBGPConfigKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (key GlobalBGPConfigKey) valueType() (reflect.Type, error) {
|
||||
return typeGlobalBGPConfig, nil
|
||||
}
|
||||
|
||||
func (key GlobalBGPConfigKey) String() string {
|
||||
return fmt.Sprintf("GlobalBGPConfig(name=%s)", key.Name)
|
||||
}
|
||||
|
||||
type GlobalBGPConfigListOptions struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
func (options GlobalBGPConfigListOptions) defaultPathRoot() string {
|
||||
k := "/calico/bgp/v1/global"
|
||||
if options.Name == "" {
|
||||
return k
|
||||
}
|
||||
k = k + fmt.Sprintf("/%s", options.Name)
|
||||
return k
|
||||
}
|
||||
|
||||
func (options GlobalBGPConfigListOptions) KeyFromDefaultPath(path string) Key {
|
||||
log.Debugf("Get GlobalFelixConfig key from %s", path)
|
||||
r := matchGlobalBGPConfig.FindAllStringSubmatch(path, -1)
|
||||
if len(r) != 1 {
|
||||
log.Debugf("Didn't match regex")
|
||||
return nil
|
||||
}
|
||||
name := r[0][1]
|
||||
if options.Name != "" && name != options.Name {
|
||||
log.Debugf("Didn't match name %s != %s", options.Name, name)
|
||||
return nil
|
||||
}
|
||||
return GlobalBGPConfigKey{Name: name}
|
||||
}
|
||||
|
||||
type NodeBGPConfigKey struct {
|
||||
// The hostname for the host specific BGP config
|
||||
Nodename string `json:"-" validate:"required,name"`
|
||||
|
||||
// The name of the host specific BGP config key.
|
||||
Name string `json:"-" validate:"required,name"`
|
||||
}
|
||||
|
||||
func (key NodeBGPConfigKey) defaultPath() (string, error) {
|
||||
return key.defaultDeletePath()
|
||||
}
|
||||
|
||||
func (key NodeBGPConfigKey) defaultDeletePath() (string, error) {
|
||||
if key.Nodename == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "node"}
|
||||
}
|
||||
if key.Name == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "name"}
|
||||
}
|
||||
e := fmt.Sprintf("/calico/bgp/v1/host/%s/%s", key.Nodename, key.Name)
|
||||
return e, nil
|
||||
}
|
||||
|
||||
func (key NodeBGPConfigKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (key NodeBGPConfigKey) valueType() (reflect.Type, error) {
|
||||
return typeNodeBGPConfig, nil
|
||||
}
|
||||
|
||||
func (key NodeBGPConfigKey) String() string {
|
||||
return fmt.Sprintf("HostBGPConfig(node=%s; name=%s)", key.Nodename, key.Name)
|
||||
}
|
||||
|
||||
type NodeBGPConfigListOptions struct {
|
||||
Nodename string
|
||||
Name string
|
||||
}
|
||||
|
||||
func (options NodeBGPConfigListOptions) defaultPathRoot() string {
|
||||
k := "/calico/bgp/v1/host/%s"
|
||||
if options.Nodename == "" {
|
||||
return k
|
||||
}
|
||||
k = k + fmt.Sprintf("/%s", options.Nodename)
|
||||
if options.Name == "" {
|
||||
return k
|
||||
}
|
||||
k = k + fmt.Sprintf("/%s", options.Name)
|
||||
return k
|
||||
}
|
||||
|
||||
func (options NodeBGPConfigListOptions) KeyFromDefaultPath(path string) Key {
|
||||
log.Debugf("Get HostConfig key from %s", path)
|
||||
r := matchNodeBGPConfig.FindAllStringSubmatch(path, -1)
|
||||
if len(r) != 1 {
|
||||
log.Debugf("Didn't match regex")
|
||||
return nil
|
||||
}
|
||||
nodename := r[0][1]
|
||||
name := r[0][2]
|
||||
if options.Nodename != "" && nodename != options.Nodename {
|
||||
log.Debugf("Didn't match nodename %s != %s", options.Nodename, nodename)
|
||||
return nil
|
||||
}
|
||||
if options.Name != "" && name != options.Name {
|
||||
log.Debugf("Didn't match name %s != %s", options.Name, name)
|
||||
return nil
|
||||
}
|
||||
return NodeBGPConfigKey{Nodename: nodename, Name: name}
|
||||
}
|
||||
230
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/bgppeer.go
generated
vendored
Normal file
230
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/bgppeer.go
generated
vendored
Normal file
@@ -0,0 +1,230 @@
|
||||
// Copyright (c) 2020 Tigera, Inc. All rights reserved.
|
||||
|
||||
// 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 model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/projectcalico/api/pkg/lib/numorstring"
|
||||
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/errors"
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/net"
|
||||
)
|
||||
|
||||
var (
|
||||
matchGlobalBGPPeer = regexp.MustCompile("^/?calico/bgp/v1/global/peer_v./([^/]+)$")
|
||||
matchHostBGPPeer = regexp.MustCompile("^/?calico/bgp/v1/host/([^/]+)/peer_v./([^/]+)$")
|
||||
typeBGPPeer = reflect.TypeOf(BGPPeer{})
|
||||
ipPortSeparator = "-"
|
||||
defaultPort uint16 = 179
|
||||
)
|
||||
|
||||
type NodeBGPPeerKey struct {
|
||||
Nodename string `json:"-" validate:"omitempty"`
|
||||
PeerIP net.IP `json:"-" validate:"required"`
|
||||
Port uint16 `json:"-" validate:"omitempty"`
|
||||
}
|
||||
|
||||
func (key NodeBGPPeerKey) defaultPath() (string, error) {
|
||||
if key.PeerIP.IP == nil {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "peerIP"}
|
||||
}
|
||||
if key.Nodename == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "node"}
|
||||
}
|
||||
e := fmt.Sprintf("/calico/bgp/v1/host/%s/peer_v%d/%s",
|
||||
key.Nodename, key.PeerIP.Version(), combineIPAndPort(key.PeerIP, key.Port))
|
||||
return e, nil
|
||||
}
|
||||
|
||||
func (key NodeBGPPeerKey) defaultDeletePath() (string, error) {
|
||||
return key.defaultPath()
|
||||
}
|
||||
|
||||
func (key NodeBGPPeerKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (key NodeBGPPeerKey) valueType() (reflect.Type, error) {
|
||||
return typeBGPPeer, nil
|
||||
}
|
||||
|
||||
func (key NodeBGPPeerKey) String() string {
|
||||
return fmt.Sprintf("BGPPeer(node=%s, ip=%s, port=%d)", key.Nodename, key.PeerIP, key.Port)
|
||||
}
|
||||
|
||||
type NodeBGPPeerListOptions struct {
|
||||
Nodename string
|
||||
PeerIP net.IP
|
||||
Port uint16
|
||||
}
|
||||
|
||||
func (options NodeBGPPeerListOptions) defaultPathRoot() string {
|
||||
if options.Nodename == "" {
|
||||
return "/calico/bgp/v1/host"
|
||||
} else if options.PeerIP.IP == nil {
|
||||
return fmt.Sprintf("/calico/bgp/v1/host/%s",
|
||||
options.Nodename)
|
||||
} else {
|
||||
return fmt.Sprintf("/calico/bgp/v1/host/%s/peer_v%d/%s",
|
||||
options.Nodename, options.PeerIP.Version(), combineIPAndPort(options.PeerIP, options.Port))
|
||||
}
|
||||
}
|
||||
|
||||
func (options NodeBGPPeerListOptions) KeyFromDefaultPath(path string) Key {
|
||||
log.Debugf("Get BGPPeer key from %s", path)
|
||||
nodename := ""
|
||||
var port uint16
|
||||
peerIP := net.IP{}
|
||||
ekeyb := []byte(path)
|
||||
if r := matchHostBGPPeer.FindAllSubmatch(ekeyb, -1); len(r) == 1 {
|
||||
var ipBytes []byte
|
||||
ipBytes, port = extractIPAndPort(string(r[0][2]))
|
||||
nodename = string(r[0][1])
|
||||
if err := peerIP.UnmarshalText(ipBytes); err != nil {
|
||||
log.WithError(err).WithField("PeerIP", r[0][2]).Error("Error unmarshalling GlobalBGPPeer IP address")
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
log.Debugf("%s didn't match regex", path)
|
||||
return nil
|
||||
}
|
||||
|
||||
if options.PeerIP.IP != nil && !options.PeerIP.Equal(peerIP.IP) {
|
||||
log.Debugf("Didn't match peerIP %s != %s", options.PeerIP.String(), peerIP.String())
|
||||
return nil
|
||||
}
|
||||
if options.Nodename != "" && nodename != options.Nodename {
|
||||
log.Debugf("Didn't match hostname %s != %s", options.Nodename, nodename)
|
||||
return nil
|
||||
}
|
||||
|
||||
if port == 0 {
|
||||
return NodeBGPPeerKey{PeerIP: peerIP, Nodename: nodename}
|
||||
}
|
||||
return NodeBGPPeerKey{PeerIP: peerIP, Nodename: nodename, Port: port}
|
||||
}
|
||||
|
||||
type GlobalBGPPeerKey struct {
|
||||
PeerIP net.IP `json:"-" validate:"required"`
|
||||
Port uint16 `json:"-" validate:"omitempty"`
|
||||
}
|
||||
|
||||
func (key GlobalBGPPeerKey) defaultPath() (string, error) {
|
||||
if key.PeerIP.IP == nil {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "peerIP"}
|
||||
}
|
||||
e := fmt.Sprintf("/calico/bgp/v1/global/peer_v%d/%s",
|
||||
key.PeerIP.Version(), combineIPAndPort(key.PeerIP, key.Port))
|
||||
return e, nil
|
||||
}
|
||||
|
||||
func (key GlobalBGPPeerKey) defaultDeletePath() (string, error) {
|
||||
return key.defaultPath()
|
||||
}
|
||||
|
||||
func (key GlobalBGPPeerKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (key GlobalBGPPeerKey) valueType() (reflect.Type, error) {
|
||||
return typeBGPPeer, nil
|
||||
}
|
||||
|
||||
func (key GlobalBGPPeerKey) String() string {
|
||||
return fmt.Sprintf("BGPPeer(global, ip=%s, port=%d)", key.PeerIP, key.Port)
|
||||
}
|
||||
|
||||
type GlobalBGPPeerListOptions struct {
|
||||
PeerIP net.IP
|
||||
Port uint16
|
||||
}
|
||||
|
||||
func (options GlobalBGPPeerListOptions) defaultPathRoot() string {
|
||||
if options.PeerIP.IP == nil {
|
||||
return "/calico/bgp/v1/global"
|
||||
} else {
|
||||
return fmt.Sprintf("/calico/bgp/v1/global/peer_v%d/%s",
|
||||
options.PeerIP.Version(), combineIPAndPort(options.PeerIP, options.Port))
|
||||
}
|
||||
}
|
||||
|
||||
func (options GlobalBGPPeerListOptions) KeyFromDefaultPath(path string) Key {
|
||||
log.Debugf("Get BGPPeer key from %s", path)
|
||||
peerIP := net.IP{}
|
||||
ekeyb := []byte(path)
|
||||
var port uint16
|
||||
|
||||
if r := matchGlobalBGPPeer.FindAllSubmatch(ekeyb, -1); len(r) == 1 {
|
||||
var ipBytes []byte
|
||||
ipBytes, port = extractIPAndPort(string(r[0][1]))
|
||||
if err := peerIP.UnmarshalText(ipBytes); err != nil {
|
||||
log.WithError(err).WithField("PeerIP", r[0][1]).Error("Error unmarshalling GlobalBGPPeer IP address")
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
log.Debugf("%s didn't match regex", path)
|
||||
return nil
|
||||
}
|
||||
|
||||
if options.PeerIP.IP != nil && !options.PeerIP.Equal(peerIP.IP) {
|
||||
log.Debugf("Didn't match peerIP %s != %s", options.PeerIP.String(), peerIP.String())
|
||||
return nil
|
||||
}
|
||||
|
||||
if port == 0 {
|
||||
return GlobalBGPPeerKey{PeerIP: peerIP, Port: port}
|
||||
}
|
||||
return GlobalBGPPeerKey{PeerIP: peerIP, Port: port}
|
||||
}
|
||||
|
||||
type BGPPeer struct {
|
||||
// PeerIP is the IP address of the BGP peer.
|
||||
PeerIP net.IP `json:"ip"`
|
||||
|
||||
// ASNum is the AS number of the peer. Note that we write out the
|
||||
// value as a string in to the backend, because confd templating
|
||||
// converts large uints to float e notation which breaks the BIRD
|
||||
// configuration.
|
||||
ASNum numorstring.ASNumber `json:"as_num,string"`
|
||||
}
|
||||
|
||||
func extractIPAndPort(ipPort string) ([]byte, uint16) {
|
||||
arr := strings.Split(ipPort, ipPortSeparator)
|
||||
if len(arr) == 2 {
|
||||
port, err := strconv.ParseUint(arr[1], 0, 16)
|
||||
if err != nil {
|
||||
log.Warningf("Error extracting port. %#v", err)
|
||||
return []byte(ipPort), defaultPort
|
||||
}
|
||||
return []byte(arr[0]), uint16(port)
|
||||
}
|
||||
return []byte(ipPort), defaultPort
|
||||
}
|
||||
|
||||
func combineIPAndPort(ip net.IP, port uint16) string {
|
||||
if port == 0 || port == defaultPort {
|
||||
return ip.String()
|
||||
} else {
|
||||
strPort := strconv.Itoa(int(port))
|
||||
return ip.String() + ipPortSeparator + strPort
|
||||
}
|
||||
}
|
||||
235
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/block.go
generated
vendored
Normal file
235
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/block.go
generated
vendored
Normal file
@@ -0,0 +1,235 @@
|
||||
// Copyright (c) 2016-2021 Tigera, Inc. All rights reserved.
|
||||
|
||||
// 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 model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/errors"
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/net"
|
||||
)
|
||||
|
||||
const (
|
||||
// Common attributes which may be set on allocations by clients.
|
||||
IPAMBlockAttributePod = "pod"
|
||||
IPAMBlockAttributeNamespace = "namespace"
|
||||
IPAMBlockAttributeNode = "node"
|
||||
IPAMBlockAttributeType = "type"
|
||||
IPAMBlockAttributeTypeIPIP = "ipipTunnelAddress"
|
||||
IPAMBlockAttributeTypeVXLAN = "vxlanTunnelAddress"
|
||||
IPAMBlockAttributeTypeVXLANV6 = "vxlanV6TunnelAddress"
|
||||
IPAMBlockAttributeTypeWireguard = "wireguardTunnelAddress"
|
||||
IPAMBlockAttributeTypeWireguardV6 = "wireguardV6TunnelAddress"
|
||||
IPAMBlockAttributeTimestamp = "timestamp"
|
||||
)
|
||||
|
||||
var (
|
||||
matchBlock = regexp.MustCompile("^/?calico/ipam/v2/assignment/ipv./block/([^/]+)$")
|
||||
typeBlock = reflect.TypeOf(AllocationBlock{})
|
||||
)
|
||||
|
||||
type BlockKey struct {
|
||||
CIDR net.IPNet `json:"-" validate:"required,name"`
|
||||
}
|
||||
|
||||
func (key BlockKey) defaultPath() (string, error) {
|
||||
if key.CIDR.IP == nil {
|
||||
return "", errors.ErrorInsufficientIdentifiers{}
|
||||
}
|
||||
c := strings.Replace(key.CIDR.String(), "/", "-", 1)
|
||||
e := fmt.Sprintf("/calico/ipam/v2/assignment/ipv%d/block/%s", key.CIDR.Version(), c)
|
||||
return e, nil
|
||||
}
|
||||
|
||||
func (key BlockKey) defaultDeletePath() (string, error) {
|
||||
return key.defaultPath()
|
||||
}
|
||||
|
||||
func (key BlockKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (key BlockKey) valueType() (reflect.Type, error) {
|
||||
return typeBlock, nil
|
||||
}
|
||||
|
||||
func (key BlockKey) String() string {
|
||||
return fmt.Sprintf("BlockKey(cidr=%s)", key.CIDR.String())
|
||||
}
|
||||
|
||||
type BlockListOptions struct {
|
||||
IPVersion int `json:"-"`
|
||||
}
|
||||
|
||||
func (options BlockListOptions) defaultPathRoot() string {
|
||||
k := "/calico/ipam/v2/assignment/"
|
||||
if options.IPVersion != 0 {
|
||||
k = k + fmt.Sprintf("ipv%d/", options.IPVersion)
|
||||
}
|
||||
return k
|
||||
}
|
||||
|
||||
func (options BlockListOptions) KeyFromDefaultPath(path string) Key {
|
||||
log.Debugf("Get Block key from %s", path)
|
||||
r := matchBlock.FindAllStringSubmatch(path, -1)
|
||||
if len(r) != 1 {
|
||||
log.Debugf("%s didn't match regex", path)
|
||||
return nil
|
||||
}
|
||||
cidrStr := strings.Replace(r[0][1], "-", "/", 1)
|
||||
_, cidr, err := net.ParseCIDR(cidrStr)
|
||||
if err != nil {
|
||||
log.Debugf("find an invalid cidr %s for path=%v , info=%v ", r[0][1], path, err)
|
||||
return nil
|
||||
}
|
||||
return BlockKey{CIDR: *cidr}
|
||||
}
|
||||
|
||||
type AllocationBlock struct {
|
||||
// The block's CIDR.
|
||||
CIDR net.IPNet `json:"cidr"`
|
||||
|
||||
// Affinity of the block, if this block has one. If set, it will be of the form
|
||||
// "host:<hostname>". If not set, this block is not affine to a host.
|
||||
Affinity *string `json:"affinity"`
|
||||
|
||||
// Array of allocations in-use within this block. nil entries mean the allocation is free.
|
||||
// For non-nil entries at index i, the index is the ordinal of the allocation within this block
|
||||
// and the value is the index of the associated attributes in the Attributes array.
|
||||
Allocations []*int `json:"allocations"`
|
||||
|
||||
// Unallocated is an ordered list of allocations which are free in the block.
|
||||
Unallocated []int `json:"unallocated"`
|
||||
|
||||
// Attributes is an array of arbitrary metadata associated with allocations in the block. To find
|
||||
// attributes for a given allocation, use the value of the allocation's entry in the Allocations array
|
||||
// as the index of the element in this array.
|
||||
Attributes []AllocationAttribute `json:"attributes"`
|
||||
|
||||
// We store a sequence number that is updated each time the block is written.
|
||||
// Each allocation will also store the sequence number of the block at the time of its creation.
|
||||
// When releasing an IP, passing the sequence number associated with the allocation allows us
|
||||
// to protect against a race condition and ensure the IP hasn't been released and re-allocated
|
||||
// since the release request.
|
||||
SequenceNumber uint64 `json:"sequenceNumber"`
|
||||
|
||||
// Map of allocated ordinal within the block to sequence number of the block at
|
||||
// the time of allocation. Kubernetes does not allow numerical keys for maps, so
|
||||
// the key is cast to a string.
|
||||
SequenceNumberForAllocation map[string]uint64 `json:"sequenceNumberForAllocation"`
|
||||
|
||||
// Deleted is an internal boolean used to workaround a limitation in the Kubernetes API whereby
|
||||
// deletion will not return a conflict error if the block has been updated.
|
||||
Deleted bool `json:"deleted"`
|
||||
|
||||
// HostAffinity is deprecated in favor of Affinity.
|
||||
// This is only to keep compatibility with existing deployments.
|
||||
// The data format should be `Affinity: host:hostname` (not `hostAffinity: hostname`).
|
||||
HostAffinity *string `json:"hostAffinity,omitempty"`
|
||||
}
|
||||
|
||||
func (b *AllocationBlock) SetSequenceNumberForOrdinal(ordinal int) {
|
||||
if b.SequenceNumberForAllocation == nil {
|
||||
b.SequenceNumberForAllocation = map[string]uint64{}
|
||||
}
|
||||
b.SequenceNumberForAllocation[fmt.Sprintf("%d", ordinal)] = b.SequenceNumber
|
||||
}
|
||||
|
||||
func (b *AllocationBlock) GetSequenceNumberForOrdinal(ordinal int) uint64 {
|
||||
return b.SequenceNumberForAllocation[fmt.Sprintf("%d", ordinal)]
|
||||
}
|
||||
|
||||
func (b *AllocationBlock) ClearSequenceNumberForOrdinal(ordinal int) {
|
||||
delete(b.SequenceNumberForAllocation, fmt.Sprintf("%d", ordinal))
|
||||
}
|
||||
|
||||
func (b *AllocationBlock) MarkDeleted() {
|
||||
b.Deleted = true
|
||||
}
|
||||
|
||||
func (b *AllocationBlock) IsDeleted() bool {
|
||||
return b.Deleted
|
||||
}
|
||||
|
||||
func (b *AllocationBlock) Host() string {
|
||||
if b.Affinity != nil && strings.HasPrefix(*b.Affinity, "host:") {
|
||||
return strings.TrimPrefix(*b.Affinity, "host:")
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type Allocation struct {
|
||||
Addr net.IP
|
||||
Host string
|
||||
}
|
||||
|
||||
func (b *AllocationBlock) NonAffineAllocations() []Allocation {
|
||||
var allocs []Allocation
|
||||
myHost := b.Host()
|
||||
for ordinal, attrIdx := range b.Allocations {
|
||||
if attrIdx == nil {
|
||||
continue // Skip unallocated IPs.
|
||||
}
|
||||
if *attrIdx >= len(b.Attributes) {
|
||||
log.WithField("block", b).Warnf("Missing attributes for IP with ordinal %d", ordinal)
|
||||
continue
|
||||
}
|
||||
attrs := b.Attributes[*attrIdx]
|
||||
host := attrs.AttrSecondary[IPAMBlockAttributeNode]
|
||||
if myHost != "" && host == myHost {
|
||||
continue // Skip allocations that are affine to this block.
|
||||
}
|
||||
a := Allocation{
|
||||
Addr: b.OrdinalToIP(ordinal),
|
||||
Host: host,
|
||||
}
|
||||
allocs = append(allocs, a)
|
||||
}
|
||||
return allocs
|
||||
}
|
||||
|
||||
// Get number of addresses covered by the block
|
||||
func (b *AllocationBlock) NumAddresses() int {
|
||||
ones, size := b.CIDR.Mask.Size()
|
||||
numAddresses := 1 << uint(size-ones)
|
||||
return numAddresses
|
||||
}
|
||||
|
||||
// Find the ordinal (i.e. how far into the block) a given IP lies. Returns an error if the IP is outside the block.
|
||||
func (b *AllocationBlock) IPToOrdinal(ip net.IP) (int, error) {
|
||||
ipAsInt := net.IPToBigInt(ip)
|
||||
baseInt := net.IPToBigInt(net.IP{b.CIDR.IP})
|
||||
ord := big.NewInt(0).Sub(ipAsInt, baseInt).Int64()
|
||||
if ord < 0 || ord >= int64(b.NumAddresses()) {
|
||||
return 0, fmt.Errorf("IP %s not in block %s", ip, b.CIDR)
|
||||
}
|
||||
return int(ord), nil
|
||||
}
|
||||
|
||||
// Calculates the IP at the given position within the block. ord=0 gives the first IP in the block.
|
||||
func (b *AllocationBlock) OrdinalToIP(ord int) net.IP {
|
||||
return b.CIDR.NthIP(ord)
|
||||
}
|
||||
|
||||
type AllocationAttribute struct {
|
||||
AttrPrimary *string `json:"handle_id"`
|
||||
AttrSecondary map[string]string `json:"secondary"`
|
||||
}
|
||||
118
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/block_affinity.go
generated
vendored
Normal file
118
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/block_affinity.go
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
// Copyright (c) 2016-2019 Tigera, Inc. All rights reserved.
|
||||
|
||||
// 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 model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/errors"
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/net"
|
||||
)
|
||||
|
||||
var (
|
||||
matchBlockAffinity = regexp.MustCompile("^/?calico/ipam/v2/host/([^/]+)/ipv./block/([^/]+)$")
|
||||
typeBlockAff = reflect.TypeOf(BlockAffinity{})
|
||||
)
|
||||
|
||||
type BlockAffinityState string
|
||||
|
||||
const (
|
||||
StateConfirmed BlockAffinityState = "confirmed"
|
||||
StatePending BlockAffinityState = "pending"
|
||||
StatePendingDeletion BlockAffinityState = "pendingDeletion"
|
||||
)
|
||||
|
||||
type BlockAffinityKey struct {
|
||||
CIDR net.IPNet `json:"-" validate:"required,name"`
|
||||
Host string `json:"-"`
|
||||
}
|
||||
|
||||
type BlockAffinity struct {
|
||||
State BlockAffinityState `json:"state"`
|
||||
Deleted bool `json:"deleted"`
|
||||
}
|
||||
|
||||
func (key BlockAffinityKey) defaultPath() (string, error) {
|
||||
if key.CIDR.IP == nil || key.Host == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{}
|
||||
}
|
||||
c := strings.Replace(key.CIDR.String(), "/", "-", 1)
|
||||
e := fmt.Sprintf("/calico/ipam/v2/host/%s/ipv%d/block/%s", key.Host, key.CIDR.Version(), c)
|
||||
return e, nil
|
||||
}
|
||||
|
||||
func (key BlockAffinityKey) defaultDeletePath() (string, error) {
|
||||
return key.defaultPath()
|
||||
}
|
||||
|
||||
func (key BlockAffinityKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (key BlockAffinityKey) valueType() (reflect.Type, error) {
|
||||
return typeBlockAff, nil
|
||||
}
|
||||
|
||||
func (key BlockAffinityKey) String() string {
|
||||
return fmt.Sprintf("BlockAffinityKey(cidr=%s, host=%s)", key.CIDR, key.Host)
|
||||
}
|
||||
|
||||
type BlockAffinityListOptions struct {
|
||||
Host string
|
||||
IPVersion int
|
||||
}
|
||||
|
||||
func (options BlockAffinityListOptions) defaultPathRoot() string {
|
||||
k := "/calico/ipam/v2/host/"
|
||||
if options.Host != "" {
|
||||
k = k + options.Host
|
||||
|
||||
if options.IPVersion != 0 {
|
||||
k = k + fmt.Sprintf("/ipv%d/block", options.IPVersion)
|
||||
}
|
||||
}
|
||||
return k
|
||||
}
|
||||
|
||||
func (options BlockAffinityListOptions) KeyFromDefaultPath(path string) Key {
|
||||
log.Debugf("Get Block affinity key from %s", path)
|
||||
r := matchBlockAffinity.FindAllStringSubmatch(path, -1)
|
||||
if len(r) != 1 {
|
||||
log.Debugf("%s didn't match regex", path)
|
||||
return nil
|
||||
}
|
||||
cidrStr := strings.Replace(r[0][2], "-", "/", 1)
|
||||
_, cidr, _ := net.ParseCIDR(cidrStr)
|
||||
if cidr == nil {
|
||||
log.Debugf("Failed to parse CIDR in block affinity path: %q", path)
|
||||
return nil
|
||||
}
|
||||
host := r[0][1]
|
||||
|
||||
if options.Host != "" && options.Host != host {
|
||||
log.Debugf("Didn't match hostname: %s != %s", options.Host, host)
|
||||
return nil
|
||||
}
|
||||
if options.IPVersion != 0 && options.IPVersion != cidr.Version() {
|
||||
log.Debugf("Didn't match IP version. %d != %d", options.IPVersion, cidr.Version())
|
||||
return nil
|
||||
}
|
||||
return BlockAffinityKey{CIDR: *cidr, Host: host}
|
||||
}
|
||||
20
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/deletion.go
generated
vendored
Normal file
20
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/deletion.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright (c) 2019 Tigera, Inc. All rights reserved.
|
||||
|
||||
// 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 model
|
||||
|
||||
type DeletionMarker interface {
|
||||
MarkDeleted()
|
||||
IsDeleted() bool
|
||||
}
|
||||
183
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/felixconfig.go
generated
vendored
Normal file
183
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/felixconfig.go
generated
vendored
Normal file
@@ -0,0 +1,183 @@
|
||||
// Copyright (c) 2016-2018 Tigera, Inc. All rights reserved.
|
||||
//
|
||||
// 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 model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
matchGlobalConfig = regexp.MustCompile("^/?calico/v1/config/(.+)$")
|
||||
matchHostConfig = regexp.MustCompile("^/?calico/v1/host/([^/]+)/config/(.+)$")
|
||||
matchReadyFlag = regexp.MustCompile("^/calico/v1/Ready$")
|
||||
typeGlobalConfig = rawStringType
|
||||
typeHostConfig = rawStringType
|
||||
typeReadyFlag = rawBoolType
|
||||
)
|
||||
|
||||
type ReadyFlagKey struct {
|
||||
}
|
||||
|
||||
func (key ReadyFlagKey) defaultPath() (string, error) {
|
||||
return "/calico/v1/Ready", nil
|
||||
}
|
||||
|
||||
func (key ReadyFlagKey) defaultDeletePath() (string, error) {
|
||||
return key.defaultPath()
|
||||
}
|
||||
|
||||
func (key ReadyFlagKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (key ReadyFlagKey) valueType() (reflect.Type, error) {
|
||||
return typeReadyFlag, nil
|
||||
}
|
||||
|
||||
func (key ReadyFlagKey) String() string {
|
||||
return "ReadyFlagKey()"
|
||||
}
|
||||
|
||||
type GlobalConfigKey struct {
|
||||
Name string `json:"-" validate:"required,name"`
|
||||
}
|
||||
|
||||
func (key GlobalConfigKey) defaultPath() (string, error) {
|
||||
if key.Name == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "name"}
|
||||
}
|
||||
e := fmt.Sprintf("/calico/v1/config/%s", key.Name)
|
||||
return e, nil
|
||||
}
|
||||
|
||||
func (key GlobalConfigKey) defaultDeletePath() (string, error) {
|
||||
return key.defaultPath()
|
||||
}
|
||||
|
||||
func (key GlobalConfigKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (key GlobalConfigKey) valueType() (reflect.Type, error) {
|
||||
return typeGlobalConfig, nil
|
||||
}
|
||||
|
||||
func (key GlobalConfigKey) String() string {
|
||||
return fmt.Sprintf("GlobalFelixConfig(name=%s)", key.Name)
|
||||
}
|
||||
|
||||
type GlobalConfigListOptions struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
func (options GlobalConfigListOptions) defaultPathRoot() string {
|
||||
k := "/calico/v1/config"
|
||||
if options.Name == "" {
|
||||
return k
|
||||
}
|
||||
k = k + fmt.Sprintf("/%s", options.Name)
|
||||
return k
|
||||
}
|
||||
|
||||
func (options GlobalConfigListOptions) KeyFromDefaultPath(path string) Key {
|
||||
log.Debugf("Get GlobalConfig key from %s", path)
|
||||
r := matchGlobalConfig.FindAllStringSubmatch(path, -1)
|
||||
if len(r) != 1 {
|
||||
log.Debugf("Didn't match regex")
|
||||
return nil
|
||||
}
|
||||
name := r[0][1]
|
||||
if options.Name != "" && name != options.Name {
|
||||
log.Debugf("Didn't match name %s != %s", options.Name, name)
|
||||
return nil
|
||||
}
|
||||
return GlobalConfigKey{Name: name}
|
||||
}
|
||||
|
||||
type HostConfigKey struct {
|
||||
Hostname string `json:"-" validate:"required,name"`
|
||||
Name string `json:"-" validate:"required,name"`
|
||||
}
|
||||
|
||||
func (key HostConfigKey) defaultPath() (string, error) {
|
||||
if key.Name == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "name"}
|
||||
}
|
||||
if key.Hostname == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "node"}
|
||||
}
|
||||
e := fmt.Sprintf("/calico/v1/host/%s/config/%s", key.Hostname, key.Name)
|
||||
return e, nil
|
||||
}
|
||||
|
||||
func (key HostConfigKey) defaultDeletePath() (string, error) {
|
||||
return key.defaultPath()
|
||||
}
|
||||
|
||||
func (key HostConfigKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (key HostConfigKey) valueType() (reflect.Type, error) {
|
||||
return typeHostConfig, nil
|
||||
}
|
||||
|
||||
func (key HostConfigKey) String() string {
|
||||
return fmt.Sprintf("HostConfig(node=%s,name=%s)", key.Hostname, key.Name)
|
||||
}
|
||||
|
||||
type HostConfigListOptions struct {
|
||||
Hostname string
|
||||
Name string
|
||||
}
|
||||
|
||||
func (options HostConfigListOptions) defaultPathRoot() string {
|
||||
k := "/calico/v1/host"
|
||||
if options.Hostname == "" {
|
||||
return k
|
||||
}
|
||||
k = k + fmt.Sprintf("/%s/config", options.Hostname)
|
||||
if options.Name == "" {
|
||||
return k
|
||||
}
|
||||
k = k + fmt.Sprintf("/%s", options.Name)
|
||||
return k
|
||||
}
|
||||
|
||||
func (options HostConfigListOptions) KeyFromDefaultPath(path string) Key {
|
||||
log.Debugf("Get HostConfig key from %s", path)
|
||||
r := matchHostConfig.FindAllStringSubmatch(path, -1)
|
||||
if len(r) != 1 {
|
||||
log.Debugf("Didn't match regex")
|
||||
return nil
|
||||
}
|
||||
hostname := r[0][1]
|
||||
name := r[0][2]
|
||||
if options.Hostname != "" && hostname != options.Hostname {
|
||||
log.Debugf("Didn't match hostname %s != %s", options.Hostname, hostname)
|
||||
return nil
|
||||
}
|
||||
if options.Name != "" && name != options.Name {
|
||||
log.Debugf("Didn't match name %s != %s", options.Name, name)
|
||||
return nil
|
||||
}
|
||||
return HostConfigKey{Hostname: hostname, Name: name}
|
||||
}
|
||||
113
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/hostendpoint.go
generated
vendored
Normal file
113
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/hostendpoint.go
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
// Copyright (c) 2016-2017 Tigera, Inc. All rights reserved.
|
||||
|
||||
// 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 model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"regexp"
|
||||
|
||||
"reflect"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/errors"
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/net"
|
||||
)
|
||||
|
||||
var (
|
||||
matchHostEndpoint = regexp.MustCompile("^/?calico/v1/host/([^/]+)/endpoint/([^/]+)$")
|
||||
typeHostEndpoint = reflect.TypeOf(HostEndpoint{})
|
||||
)
|
||||
|
||||
type HostEndpointKey struct {
|
||||
Hostname string `json:"-" validate:"required,hostname"`
|
||||
EndpointID string `json:"-" validate:"required,namespacedName"`
|
||||
}
|
||||
|
||||
func (key HostEndpointKey) defaultPath() (string, error) {
|
||||
if key.Hostname == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "node"}
|
||||
}
|
||||
if key.EndpointID == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "name"}
|
||||
}
|
||||
e := fmt.Sprintf("/calico/v1/host/%s/endpoint/%s",
|
||||
key.Hostname, escapeName(key.EndpointID))
|
||||
return e, nil
|
||||
}
|
||||
|
||||
func (key HostEndpointKey) defaultDeletePath() (string, error) {
|
||||
return key.defaultPath()
|
||||
}
|
||||
|
||||
func (key HostEndpointKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (key HostEndpointKey) valueType() (reflect.Type, error) {
|
||||
return typeHostEndpoint, nil
|
||||
}
|
||||
|
||||
func (key HostEndpointKey) String() string {
|
||||
return fmt.Sprintf("HostEndpoint(node=%s, name=%s)", key.Hostname, key.EndpointID)
|
||||
}
|
||||
|
||||
type HostEndpointListOptions struct {
|
||||
Hostname string
|
||||
EndpointID string
|
||||
}
|
||||
|
||||
func (options HostEndpointListOptions) defaultPathRoot() string {
|
||||
k := "/calico/v1/host"
|
||||
if options.Hostname == "" {
|
||||
return k
|
||||
}
|
||||
k = k + fmt.Sprintf("/%s/endpoint", options.Hostname)
|
||||
if options.EndpointID == "" {
|
||||
return k
|
||||
}
|
||||
k = k + fmt.Sprintf("/%s", escapeName(options.EndpointID))
|
||||
return k
|
||||
}
|
||||
|
||||
func (options HostEndpointListOptions) KeyFromDefaultPath(path string) Key {
|
||||
log.Debugf("Get HostEndpoint key from %s", path)
|
||||
r := matchHostEndpoint.FindAllStringSubmatch(path, -1)
|
||||
if len(r) != 1 {
|
||||
log.Debugf("Didn't match regex")
|
||||
return nil
|
||||
}
|
||||
hostname := r[0][1]
|
||||
endpointID := unescapeName(r[0][2])
|
||||
if options.Hostname != "" && hostname != options.Hostname {
|
||||
log.Debugf("Didn't match hostname %s != %s", options.Hostname, hostname)
|
||||
return nil
|
||||
}
|
||||
if options.EndpointID != "" && endpointID != options.EndpointID {
|
||||
log.Debugf("Didn't match endpointID %s != %s", options.EndpointID, endpointID)
|
||||
return nil
|
||||
}
|
||||
return HostEndpointKey{Hostname: hostname, EndpointID: endpointID}
|
||||
}
|
||||
|
||||
type HostEndpoint struct {
|
||||
Name string `json:"name,omitempty" validate:"omitempty,interface"`
|
||||
ExpectedIPv4Addrs []net.IP `json:"expected_ipv4_addrs,omitempty" validate:"omitempty,dive,ipv4"`
|
||||
ExpectedIPv6Addrs []net.IP `json:"expected_ipv6_addrs,omitempty" validate:"omitempty,dive,ipv6"`
|
||||
Labels map[string]string `json:"labels,omitempty" validate:"omitempty,labels"`
|
||||
ProfileIDs []string `json:"profile_ids,omitempty" validate:"omitempty,dive,name"`
|
||||
Ports []EndpointPort `json:"ports,omitempty" validate:"dive"`
|
||||
}
|
||||
107
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/hostendpointstatus.go
generated
vendored
Normal file
107
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/hostendpointstatus.go
generated
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
// Copyright (c) 2016 Tigera, Inc. All rights reserved.
|
||||
|
||||
// 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 model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"regexp"
|
||||
|
||||
"reflect"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
matchHostEndpointStatus = regexp.MustCompile("^/?calico/felix/v1/host/([^/]+)/endpoint/([^/]+)$")
|
||||
typeHostEndpointStatus = reflect.TypeOf(HostEndpointStatus{})
|
||||
)
|
||||
|
||||
type HostEndpointStatusKey struct {
|
||||
Hostname string `json:"-" validate:"required,hostname"`
|
||||
EndpointID string `json:"-" validate:"required,namespacedName"`
|
||||
}
|
||||
|
||||
func (key HostEndpointStatusKey) defaultPath() (string, error) {
|
||||
if key.Hostname == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "node"}
|
||||
}
|
||||
if key.EndpointID == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "name"}
|
||||
}
|
||||
e := fmt.Sprintf("/calico/felix/v1/host/%s/endpoint/%s",
|
||||
key.Hostname, escapeName(key.EndpointID))
|
||||
return e, nil
|
||||
}
|
||||
|
||||
func (key HostEndpointStatusKey) defaultDeletePath() (string, error) {
|
||||
return key.defaultPath()
|
||||
}
|
||||
|
||||
func (key HostEndpointStatusKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (key HostEndpointStatusKey) valueType() (reflect.Type, error) {
|
||||
return typeHostEndpointStatus, nil
|
||||
}
|
||||
|
||||
func (key HostEndpointStatusKey) String() string {
|
||||
return fmt.Sprintf("HostEndpointStatus(hostname=%s, name=%s)", key.Hostname, key.EndpointID)
|
||||
}
|
||||
|
||||
type HostEndpointStatusListOptions struct {
|
||||
Hostname string
|
||||
EndpointID string
|
||||
}
|
||||
|
||||
func (options HostEndpointStatusListOptions) defaultPathRoot() string {
|
||||
k := "/calico/felix/v1/host"
|
||||
if options.Hostname == "" {
|
||||
return k
|
||||
}
|
||||
k = k + fmt.Sprintf("/%s/endpoint", options.Hostname)
|
||||
if options.EndpointID == "" {
|
||||
return k
|
||||
}
|
||||
k = k + fmt.Sprintf("/%s", escapeName(options.EndpointID))
|
||||
return k
|
||||
}
|
||||
|
||||
func (options HostEndpointStatusListOptions) KeyFromDefaultPath(ekey string) Key {
|
||||
log.Debugf("Get HostEndpointStatus key from %s", ekey)
|
||||
r := matchHostEndpointStatus.FindAllStringSubmatch(ekey, -1)
|
||||
if len(r) != 1 {
|
||||
log.Debugf("Didn't match regex")
|
||||
return nil
|
||||
}
|
||||
hostname := r[0][1]
|
||||
endpointID := unescapeName(r[0][2])
|
||||
if options.Hostname != "" && hostname != options.Hostname {
|
||||
log.Debugf("Didn't match hostname %s != %s", options.Hostname, hostname)
|
||||
return nil
|
||||
}
|
||||
if options.EndpointID != "" && endpointID != options.EndpointID {
|
||||
log.Debugf("Didn't match endpointID %s != %s", options.EndpointID, endpointID)
|
||||
return nil
|
||||
}
|
||||
return HostEndpointStatusKey{Hostname: hostname, EndpointID: endpointID}
|
||||
}
|
||||
|
||||
type HostEndpointStatus struct {
|
||||
Status string `json:"status"`
|
||||
}
|
||||
53
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/ipam_config.go
generated
vendored
Normal file
53
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/ipam_config.go
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
// Copyright (c) 2016 Tigera, Inc. All rights reserved.
|
||||
|
||||
// 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 model
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
const (
|
||||
IPAMConfigGlobalName = "default"
|
||||
)
|
||||
|
||||
var typeIPAMConfig = reflect.TypeOf(IPAMConfig{})
|
||||
|
||||
type IPAMConfigKey struct{}
|
||||
|
||||
func (key IPAMConfigKey) defaultPath() (string, error) {
|
||||
return "/calico/ipam/v2/config", nil
|
||||
}
|
||||
|
||||
func (key IPAMConfigKey) defaultDeletePath() (string, error) {
|
||||
return key.defaultPath()
|
||||
}
|
||||
|
||||
func (key IPAMConfigKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (key IPAMConfigKey) valueType() (reflect.Type, error) {
|
||||
return typeIPAMConfig, nil
|
||||
}
|
||||
|
||||
func (key IPAMConfigKey) String() string {
|
||||
return "IPAMConfigKey()"
|
||||
}
|
||||
|
||||
type IPAMConfig struct {
|
||||
StrictAffinity bool `json:"strict_affinity,omitempty"`
|
||||
AutoAllocateBlocks bool `json:"auto_allocate_blocks,omitempty"`
|
||||
MaxBlocksPerHost int `json:"maxBlocksPerHost,omitempty"`
|
||||
}
|
||||
84
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/ipam_handle.go
generated
vendored
Normal file
84
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/ipam_handle.go
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
// Copyright (c) 2016,2020 Tigera, Inc. All rights reserved.
|
||||
|
||||
// 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 model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
matchHandle = regexp.MustCompile("^/?calico/ipam/v2/handle/([^/]+)$")
|
||||
typeHandle = reflect.TypeOf(IPAMHandle{})
|
||||
)
|
||||
|
||||
type IPAMHandleKey struct {
|
||||
HandleID string `json:"id"`
|
||||
}
|
||||
|
||||
func (key IPAMHandleKey) defaultPath() (string, error) {
|
||||
if key.HandleID == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{}
|
||||
}
|
||||
e := fmt.Sprintf("/calico/ipam/v2/handle/%s", key.HandleID)
|
||||
return e, nil
|
||||
}
|
||||
|
||||
func (key IPAMHandleKey) defaultDeletePath() (string, error) {
|
||||
return key.defaultPath()
|
||||
}
|
||||
|
||||
func (key IPAMHandleKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (key IPAMHandleKey) valueType() (reflect.Type, error) {
|
||||
return typeHandle, nil
|
||||
}
|
||||
|
||||
func (key IPAMHandleKey) String() string {
|
||||
return fmt.Sprintf("IPAMHandleKey(id=%s)", key.HandleID)
|
||||
}
|
||||
|
||||
type IPAMHandleListOptions struct {
|
||||
// TODO: Have some options here?
|
||||
}
|
||||
|
||||
func (options IPAMHandleListOptions) defaultPathRoot() string {
|
||||
k := "/calico/ipam/v2/handle/"
|
||||
// TODO: Allow filtering on individual host?
|
||||
return k
|
||||
}
|
||||
|
||||
func (options IPAMHandleListOptions) KeyFromDefaultPath(path string) Key {
|
||||
log.Debugf("Get IPAM handle key from %s", path)
|
||||
r := matchHandle.FindAllStringSubmatch(path, -1)
|
||||
if len(r) != 1 {
|
||||
log.Debugf("%s didn't match regex", path)
|
||||
return nil
|
||||
}
|
||||
return IPAMHandleKey{HandleID: r[0][1]}
|
||||
}
|
||||
|
||||
type IPAMHandle struct {
|
||||
HandleID string `json:"-"`
|
||||
Block map[string]int `json:"block"`
|
||||
Deleted bool `json:"deleted"`
|
||||
}
|
||||
58
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/ipam_host.go
generated
vendored
Normal file
58
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/ipam_host.go
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright (c) 2016 Tigera, Inc. All rights reserved.
|
||||
|
||||
// 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 model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
typeIPAMHost = reflect.TypeOf(IPAMHost{})
|
||||
)
|
||||
|
||||
type IPAMHostKey struct {
|
||||
Host string
|
||||
}
|
||||
|
||||
func (key IPAMHostKey) defaultPath() (string, error) {
|
||||
if key.Host == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "host"}
|
||||
}
|
||||
|
||||
k := "/calico/ipam/v2/host/" + key.Host
|
||||
return k, nil
|
||||
}
|
||||
|
||||
func (key IPAMHostKey) defaultDeletePath() (string, error) {
|
||||
return key.defaultPath()
|
||||
}
|
||||
|
||||
func (key IPAMHostKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (key IPAMHostKey) valueType() (reflect.Type, error) {
|
||||
return typeIPAMHost, nil
|
||||
}
|
||||
|
||||
func (key IPAMHostKey) String() string {
|
||||
return fmt.Sprintf("IPAMHostKey(host=%s)", key.Host)
|
||||
}
|
||||
|
||||
type IPAMHost struct {
|
||||
}
|
||||
107
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/ippool.go
generated
vendored
Normal file
107
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/ippool.go
generated
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
// Copyright (c) 2016,2021 Tigera, Inc. All rights reserved.
|
||||
|
||||
// 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 model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/backend/encap"
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/errors"
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/net"
|
||||
)
|
||||
|
||||
var (
|
||||
matchIPPool = regexp.MustCompile("^/?calico/v1/ipam/v./pool/([^/]+)$")
|
||||
typeIPPool = reflect.TypeOf(IPPool{})
|
||||
)
|
||||
|
||||
type IPPoolKey struct {
|
||||
CIDR net.IPNet `json:"-" validate:"required,name"`
|
||||
}
|
||||
|
||||
func (key IPPoolKey) defaultPath() (string, error) {
|
||||
if key.CIDR.IP == nil {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "cidr"}
|
||||
}
|
||||
c := strings.Replace(key.CIDR.String(), "/", "-", 1)
|
||||
e := fmt.Sprintf("/calico/v1/ipam/v%d/pool/%s", key.CIDR.Version(), c)
|
||||
return e, nil
|
||||
}
|
||||
|
||||
func (key IPPoolKey) defaultDeletePath() (string, error) {
|
||||
return key.defaultPath()
|
||||
}
|
||||
|
||||
func (key IPPoolKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (key IPPoolKey) valueType() (reflect.Type, error) {
|
||||
return typeIPPool, nil
|
||||
}
|
||||
|
||||
func (key IPPoolKey) String() string {
|
||||
return fmt.Sprintf("IPPool(cidr=%s)", key.CIDR)
|
||||
}
|
||||
|
||||
type IPPoolListOptions struct {
|
||||
CIDR net.IPNet
|
||||
}
|
||||
|
||||
func (options IPPoolListOptions) defaultPathRoot() string {
|
||||
k := "/calico/v1/ipam/"
|
||||
if options.CIDR.IP == nil {
|
||||
return k
|
||||
}
|
||||
c := strings.Replace(options.CIDR.String(), "/", "-", 1)
|
||||
k = k + fmt.Sprintf("v%d/pool/", options.CIDR.Version()) + fmt.Sprintf("%s", c)
|
||||
return k
|
||||
}
|
||||
|
||||
func (options IPPoolListOptions) KeyFromDefaultPath(path string) Key {
|
||||
log.Debugf("Get Pool key from %s", path)
|
||||
r := matchIPPool.FindAllStringSubmatch(path, -1)
|
||||
if len(r) != 1 {
|
||||
log.Debugf("%s didn't match regex", path)
|
||||
return nil
|
||||
}
|
||||
cidrStr := strings.Replace(r[0][1], "-", "/", 1)
|
||||
_, cidr, err := net.ParseCIDR(cidrStr)
|
||||
if err != nil {
|
||||
log.WithError(err).Warningf("Failed to parse CIDR %s", cidrStr)
|
||||
return nil
|
||||
}
|
||||
if options.CIDR.IP != nil && !reflect.DeepEqual(*cidr, options.CIDR) {
|
||||
log.Debugf("Didn't match cidr %s != %s", options.CIDR.String(), cidr.String())
|
||||
return nil
|
||||
}
|
||||
return IPPoolKey{CIDR: *cidr}
|
||||
}
|
||||
|
||||
type IPPool struct {
|
||||
CIDR net.IPNet `json:"cidr"`
|
||||
IPIPInterface string `json:"ipip"`
|
||||
IPIPMode encap.Mode `json:"ipip_mode"`
|
||||
VXLANMode encap.Mode `json:"vxlan_mode"`
|
||||
Masquerade bool `json:"masquerade"`
|
||||
IPAM bool `json:"ipam"`
|
||||
Disabled bool `json:"disabled"`
|
||||
DisableBGPExport bool `json:"disableBGPExport"`
|
||||
}
|
||||
627
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/keys.go
generated
vendored
Normal file
627
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/keys.go
generated
vendored
Normal file
@@ -0,0 +1,627 @@
|
||||
// Copyright (c) 2016-2020 Tigera, Inc. All rights reserved.
|
||||
//
|
||||
// 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 model
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
net2 "net"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/json"
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/namespace"
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/net"
|
||||
)
|
||||
|
||||
// RawString is used a value type to indicate that the value is a bare non-JSON string
|
||||
type rawString string
|
||||
type rawBool bool
|
||||
type rawIP net.IP
|
||||
|
||||
var rawStringType = reflect.TypeOf(rawString(""))
|
||||
var rawBoolType = reflect.TypeOf(rawBool(true))
|
||||
var rawIPType = reflect.TypeOf(rawIP{})
|
||||
|
||||
// Key represents a parsed datastore key.
|
||||
type Key interface {
|
||||
// defaultPath() returns a common path representation of the object used by
|
||||
// etcdv3 and other datastores.
|
||||
defaultPath() (string, error)
|
||||
|
||||
// defaultDeletePath() returns a common path representation used by etcdv3
|
||||
// and other datastores to delete the object.
|
||||
defaultDeletePath() (string, error)
|
||||
|
||||
// defaultDeleteParentPaths() returns an ordered slice of paths that should
|
||||
// be removed after deleting the primary path (given by defaultDeletePath),
|
||||
// provided there are no child entries associated with those paths. This is
|
||||
// only used by directory based KV stores (such as etcdv3). With a directory
|
||||
// based KV store, creation of a resource may also create parent directory entries
|
||||
// that could be shared by multiple resources, and therefore the parent directories
|
||||
// can only be removed when there are no more resources under them. The list of
|
||||
// parent paths is ordered, and directories should be removed in the order supplied
|
||||
// in the slice and only if the directory is empty.
|
||||
defaultDeleteParentPaths() ([]string, error)
|
||||
|
||||
// valueType returns the object type associated with this key.
|
||||
valueType() (reflect.Type, error)
|
||||
|
||||
// String returns a unique string representation of this key. The string
|
||||
// returned by this method must uniquely identify this Key.
|
||||
String() string
|
||||
}
|
||||
|
||||
// Interface used to perform datastore lookups.
|
||||
type ListInterface interface {
|
||||
// defaultPathRoot() returns a default stringified root path, i.e. path
|
||||
// to the directory containing all the keys to be listed.
|
||||
defaultPathRoot() string
|
||||
|
||||
// BUG(smc) I think we should remove this and use the package KeyFromDefaultPath function.
|
||||
// KeyFromDefaultPath parses the default path representation of the
|
||||
// Key type for this list. It returns nil if passed a different kind
|
||||
// of path.
|
||||
KeyFromDefaultPath(key string) Key
|
||||
}
|
||||
|
||||
// KVPair holds a typed key and value object as well as datastore specific
|
||||
// revision information.
|
||||
//
|
||||
// The Value is dependent on the Key, but in general will be on of the following
|
||||
// types:
|
||||
// - A pointer to a struct
|
||||
// - A slice or map
|
||||
// - A bare string, boolean value or IP address (i.e. without quotes, so not
|
||||
// JSON format).
|
||||
type KVPair struct {
|
||||
Key Key
|
||||
Value interface{}
|
||||
Revision string
|
||||
UID *types.UID
|
||||
TTL time.Duration // For writes, if non-zero, key has a TTL.
|
||||
}
|
||||
|
||||
// KVPairList hosts a slice of KVPair structs and a Revision, returned from a Ls
|
||||
type KVPairList struct {
|
||||
KVPairs []*KVPair
|
||||
Revision string
|
||||
}
|
||||
|
||||
// KeyToDefaultPath converts one of the Keys from this package into a unique
|
||||
// '/'-delimited path, which is suitable for use as the key when storing the
|
||||
// value in a hierarchical (i.e. one with directories and leaves) key/value
|
||||
// datastore such as etcd v3.
|
||||
//
|
||||
// Each unique key returns a unique path.
|
||||
//
|
||||
// Keys with a hierarchical relationship share a common prefix. However, in
|
||||
// order to support datastores that do not support storing data at non-leaf
|
||||
// nodes in the hierarchy (such as etcd v3), the path returned for a "parent"
|
||||
// key, is not a direct ancestor of its children.
|
||||
func KeyToDefaultPath(key Key) (string, error) {
|
||||
return key.defaultPath()
|
||||
}
|
||||
|
||||
// KeyToDefaultDeletePath converts one of the Keys from this package into a
|
||||
// unique '/'-delimited path, which is suitable for use as the key when
|
||||
// (recursively) deleting the value from a hierarchical (i.e. one with
|
||||
// directories and leaves) key/value datastore such as etcd v3.
|
||||
//
|
||||
// KeyToDefaultDeletePath returns a different path to KeyToDefaultPath when
|
||||
// it is a passed a Key that represents a non-leaf which, for example, has its
|
||||
// own metadata but also contains other resource types as children.
|
||||
//
|
||||
// KeyToDefaultDeletePath returns the common prefix of the non-leaf key and
|
||||
// its children so that a recursive delete of that key would delete the
|
||||
// object itself and any children it has.
|
||||
func KeyToDefaultDeletePath(key Key) (string, error) {
|
||||
return key.defaultDeletePath()
|
||||
}
|
||||
|
||||
// KeyToDefaultDeleteParentPaths returns a slice of '/'-delimited
|
||||
// paths which are used to delete parent entries that may be auto-created
|
||||
// by directory-based KV stores (e.g. etcd v3). These paths should also be
|
||||
// removed provided they have no more child entries.
|
||||
//
|
||||
// The list of parent paths is ordered, and directories should be removed
|
||||
// in the order supplied in the slice and only if the directory is empty.
|
||||
//
|
||||
// For example,
|
||||
//
|
||||
// KeyToDefaultDeletePaths(WorkloadEndpointKey{
|
||||
// Nodename: "h",
|
||||
// OrchestratorID: "o",
|
||||
// WorkloadID: "w",
|
||||
// EndpointID: "e",
|
||||
// })
|
||||
//
|
||||
// returns
|
||||
//
|
||||
// ["/calico/v1/host/h/workload/o/w/endpoint",
|
||||
//
|
||||
// "/calico/v1/host/h/workload/o/w"]
|
||||
//
|
||||
// indicating that these paths should also be deleted when they are empty.
|
||||
// In this example it is equivalent to deleting the workload when there are
|
||||
// no more endpoints in the workload.
|
||||
func KeyToDefaultDeleteParentPaths(key Key) ([]string, error) {
|
||||
return key.defaultDeleteParentPaths()
|
||||
}
|
||||
|
||||
// ListOptionsToDefaultPathRoot converts list options struct into a
|
||||
// common-prefix path suitable for querying a datastore that uses the paths
|
||||
// returned by KeyToDefaultPath.
|
||||
func ListOptionsToDefaultPathRoot(listOptions ListInterface) string {
|
||||
return listOptions.defaultPathRoot()
|
||||
}
|
||||
|
||||
// ListOptionsIsFullyQualified returns true if the options actually specify a fully
|
||||
// qualified resource rather than a partial match.
|
||||
func ListOptionsIsFullyQualified(listOptions ListInterface) bool {
|
||||
// Construct the path prefix and then check to see if that actually corresponds to
|
||||
// the path of a resource instance.
|
||||
return listOptions.KeyFromDefaultPath(listOptions.defaultPathRoot()) != nil
|
||||
}
|
||||
|
||||
// IsListOptionsLastSegmentPrefix returns true if the final segment of the default path
|
||||
// root is a name prefix rather than the full name.
|
||||
func IsListOptionsLastSegmentPrefix(listOptions ListInterface) bool {
|
||||
// Only supported for ResourceListOptions.
|
||||
rl, ok := listOptions.(ResourceListOptions)
|
||||
return ok && rl.IsLastSegmentIsPrefix()
|
||||
}
|
||||
|
||||
// KeyFromDefaultPath parses the default path representation of a key into one
|
||||
// of our <Type>Key structs. Returns nil if the string doesn't match one of
|
||||
// our key types.
|
||||
func KeyFromDefaultPath(path string) Key {
|
||||
// "v3" resource keys strictly require a leading slash but older "v1" keys were permissive.
|
||||
// For ease of parsing, strip the slash off now but pass it down to keyFromDefaultPathInner so
|
||||
// it can check for it later.
|
||||
normalizedPath := path
|
||||
if strings.HasPrefix(normalizedPath, "/") {
|
||||
normalizedPath = normalizedPath[1:]
|
||||
}
|
||||
|
||||
parts := strings.Split(normalizedPath, "/")
|
||||
if len(parts) < 3 {
|
||||
// After removing the optional `/` prefix, should have at least 3 segments.
|
||||
return nil
|
||||
}
|
||||
|
||||
return keyFromDefaultPathInner(path, parts)
|
||||
}
|
||||
|
||||
func keyFromDefaultPathInner(path string, parts []string) Key {
|
||||
if parts[0] != "calico" {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch parts[1] {
|
||||
case "v1":
|
||||
switch parts[2] {
|
||||
case "ipam":
|
||||
return IPPoolListOptions{}.KeyFromDefaultPath(path)
|
||||
case "config":
|
||||
return GlobalConfigKey{Name: strings.Join(parts[3:], "/")}
|
||||
case "host":
|
||||
if len(parts) < 5 {
|
||||
return nil
|
||||
}
|
||||
hostname := parts[3]
|
||||
switch parts[4] {
|
||||
case "workload":
|
||||
if len(parts) != 9 || parts[7] != "endpoint" {
|
||||
return nil
|
||||
}
|
||||
return WorkloadEndpointKey{
|
||||
Hostname: unescapeName(hostname),
|
||||
OrchestratorID: unescapeName(parts[5]),
|
||||
WorkloadID: unescapeName(parts[6]),
|
||||
EndpointID: unescapeName(parts[8]),
|
||||
}
|
||||
case "endpoint":
|
||||
if len(parts) != 6 {
|
||||
return nil
|
||||
}
|
||||
return HostEndpointKey{
|
||||
Hostname: unescapeName(hostname),
|
||||
EndpointID: unescapeName(parts[5]),
|
||||
}
|
||||
case "config":
|
||||
return HostConfigKey{
|
||||
Hostname: hostname,
|
||||
Name: strings.Join(parts[5:], "/"),
|
||||
}
|
||||
case "metadata":
|
||||
if len(parts) != 5 {
|
||||
return nil
|
||||
}
|
||||
return HostMetadataKey{
|
||||
Hostname: hostname,
|
||||
}
|
||||
case "bird_ip":
|
||||
if len(parts) != 5 {
|
||||
return nil
|
||||
}
|
||||
return HostIPKey{
|
||||
Hostname: hostname,
|
||||
}
|
||||
case "wireguard":
|
||||
if len(parts) != 5 {
|
||||
return nil
|
||||
}
|
||||
return WireguardKey{
|
||||
NodeName: hostname,
|
||||
}
|
||||
}
|
||||
case "netset":
|
||||
if len(parts) != 4 {
|
||||
return nil
|
||||
}
|
||||
return NetworkSetKey{
|
||||
Name: unescapeName(parts[3]),
|
||||
}
|
||||
case "Ready":
|
||||
if len(parts) > 3 || path[0] != '/' {
|
||||
return nil
|
||||
}
|
||||
return ReadyFlagKey{}
|
||||
case "policy":
|
||||
if len(parts) < 6 {
|
||||
return nil
|
||||
}
|
||||
switch parts[3] {
|
||||
case "tier":
|
||||
if len(parts) < 6 {
|
||||
return nil
|
||||
}
|
||||
switch parts[5] {
|
||||
case "policy":
|
||||
if len(parts) != 7 {
|
||||
return nil
|
||||
}
|
||||
return PolicyKey{
|
||||
Name: unescapeName(parts[6]),
|
||||
}
|
||||
}
|
||||
case "profile":
|
||||
pk := unescapeName(parts[4])
|
||||
switch parts[5] {
|
||||
case "rules":
|
||||
return ProfileRulesKey{ProfileKey: ProfileKey{pk}}
|
||||
case "labels":
|
||||
return ProfileLabelsKey{ProfileKey: ProfileKey{pk}}
|
||||
}
|
||||
}
|
||||
}
|
||||
case "bgp":
|
||||
switch parts[2] {
|
||||
case "v1":
|
||||
if len(parts) < 5 {
|
||||
return nil
|
||||
}
|
||||
switch parts[3] {
|
||||
case "global":
|
||||
return GlobalBGPConfigListOptions{}.KeyFromDefaultPath(path)
|
||||
case "host":
|
||||
if len(parts) < 6 {
|
||||
return nil
|
||||
}
|
||||
return NodeBGPConfigListOptions{}.KeyFromDefaultPath(path)
|
||||
}
|
||||
}
|
||||
case "ipam":
|
||||
if len(parts) < 5 {
|
||||
return nil
|
||||
}
|
||||
switch parts[2] {
|
||||
case "v2":
|
||||
switch parts[3] {
|
||||
case "assignment":
|
||||
return BlockListOptions{}.KeyFromDefaultPath(path)
|
||||
case "handle":
|
||||
if len(parts) > 5 {
|
||||
return nil
|
||||
}
|
||||
return IPAMHandleKey{
|
||||
HandleID: parts[4],
|
||||
}
|
||||
case "host":
|
||||
return BlockAffinityListOptions{}.KeyFromDefaultPath(path)
|
||||
}
|
||||
}
|
||||
case "resources":
|
||||
switch parts[2] {
|
||||
case "v3":
|
||||
// v3 resource keys strictly require the leading slash.
|
||||
if len(parts) < 6 || parts[3] != "projectcalico.org" || path[0] != '/' {
|
||||
return nil
|
||||
}
|
||||
switch len(parts) {
|
||||
case 6:
|
||||
ri, ok := resourceInfoByPlural[unescapeName(parts[4])]
|
||||
if !ok {
|
||||
log.Warnf("(BUG) unknown resource type: %v", path)
|
||||
return nil
|
||||
}
|
||||
if namespace.IsNamespaced(ri.kind) {
|
||||
log.Warnf("(BUG) Path is a global resource, but resource is namespaced: %v", path)
|
||||
return nil
|
||||
}
|
||||
log.Debugf("Path is a global resource: %v", path)
|
||||
return ResourceKey{
|
||||
Kind: ri.kind,
|
||||
Name: unescapeName(parts[5]),
|
||||
}
|
||||
case 7:
|
||||
ri, ok := resourceInfoByPlural[unescapeName(parts[4])]
|
||||
if !ok {
|
||||
log.Warnf("(BUG) unknown resource type: %v", path)
|
||||
return nil
|
||||
}
|
||||
if !namespace.IsNamespaced(ri.kind) {
|
||||
log.Warnf("(BUG) Path is a namespaced resource, but resource is global: %v", path)
|
||||
return nil
|
||||
}
|
||||
log.Debugf("Path is a namespaced resource: %v", path)
|
||||
return ResourceKey{
|
||||
Kind: ri.kind,
|
||||
Namespace: unescapeName(parts[5]),
|
||||
Name: unescapeName(parts[6]),
|
||||
}
|
||||
}
|
||||
}
|
||||
case "felix":
|
||||
if len(parts) < 4 {
|
||||
return nil
|
||||
}
|
||||
switch parts[2] {
|
||||
case "v1":
|
||||
switch parts[3] {
|
||||
case "host":
|
||||
if len(parts) != 7 || parts[5] != "endpoint" {
|
||||
return nil
|
||||
}
|
||||
return HostEndpointStatusKey{
|
||||
Hostname: parts[4],
|
||||
EndpointID: unescapeName(parts[6]),
|
||||
}
|
||||
}
|
||||
case "v2":
|
||||
if len(parts) < 7 {
|
||||
return nil
|
||||
}
|
||||
if parts[4] != "host" {
|
||||
return nil
|
||||
}
|
||||
switch parts[6] {
|
||||
case "status":
|
||||
return ActiveStatusReportListOptions{}.KeyFromDefaultPath(path)
|
||||
case "last_reported_status":
|
||||
return LastStatusReportListOptions{}.KeyFromDefaultPath(path)
|
||||
case "workload":
|
||||
return WorkloadEndpointStatusListOptions{}.KeyFromDefaultPath(path)
|
||||
}
|
||||
}
|
||||
}
|
||||
log.Debugf("Path is unknown: %v", path)
|
||||
return nil
|
||||
}
|
||||
|
||||
// OldKeyFromDefaultPath is the old, (slower) implementation of KeyFromDefaultPath. It is kept to allow
|
||||
// fuzzing the new version against it. Parses the default path representation of a key into one
|
||||
// of our <Type>Key structs. Returns nil if the string doesn't match one of
|
||||
// our key types.
|
||||
func OldKeyFromDefaultPath(path string) Key {
|
||||
if m := matchWorkloadEndpoint.FindStringSubmatch(path); m != nil {
|
||||
log.Debugf("Path is a workload endpoint: %v", path)
|
||||
return WorkloadEndpointKey{
|
||||
Hostname: unescapeName(m[1]),
|
||||
OrchestratorID: unescapeName(m[2]),
|
||||
WorkloadID: unescapeName(m[3]),
|
||||
EndpointID: unescapeName(m[4]),
|
||||
}
|
||||
} else if m := matchHostEndpoint.FindStringSubmatch(path); m != nil {
|
||||
log.Debugf("Path is a host endpoint: %v", path)
|
||||
return HostEndpointKey{
|
||||
Hostname: unescapeName(m[1]),
|
||||
EndpointID: unescapeName(m[2]),
|
||||
}
|
||||
} else if m := matchNetworkSet.FindStringSubmatch(path); m != nil {
|
||||
log.Debugf("Path is a network set: %v", path)
|
||||
return NetworkSetKey{
|
||||
Name: unescapeName(m[1]),
|
||||
}
|
||||
} else if m := matchGlobalResource.FindStringSubmatch(path); m != nil {
|
||||
ri, ok := resourceInfoByPlural[unescapeName(m[1])]
|
||||
if !ok {
|
||||
log.Warnf("(BUG) unknown resource type: %v", path)
|
||||
return nil
|
||||
}
|
||||
if namespace.IsNamespaced(ri.kind) {
|
||||
log.Warnf("(BUG) Path is a global resource, but resource is namespaced: %v", path)
|
||||
return nil
|
||||
}
|
||||
log.Debugf("Path is a global resource: %v", path)
|
||||
return ResourceKey{
|
||||
Kind: ri.kind,
|
||||
Name: unescapeName(m[2]),
|
||||
}
|
||||
} else if m := matchNamespacedResource.FindStringSubmatch(path); m != nil {
|
||||
ri, ok := resourceInfoByPlural[unescapeName(m[1])]
|
||||
if !ok {
|
||||
log.Warnf("(BUG) unknown resource type: %v", path)
|
||||
return nil
|
||||
}
|
||||
if !namespace.IsNamespaced(ri.kind) {
|
||||
log.Warnf("(BUG) Path is a namespaced resource, but resource is global: %v", path)
|
||||
return nil
|
||||
}
|
||||
log.Debugf("Path is a namespaced resource: %v", path)
|
||||
return ResourceKey{
|
||||
Kind: resourceInfoByPlural[unescapeName(m[1])].kind,
|
||||
Namespace: unescapeName(m[2]),
|
||||
Name: unescapeName(m[3]),
|
||||
}
|
||||
} else if m := matchPolicy.FindStringSubmatch(path); m != nil {
|
||||
log.Debugf("Path is a policy: %v", path)
|
||||
return PolicyKey{
|
||||
Name: unescapeName(m[2]),
|
||||
}
|
||||
} else if m := matchProfile.FindStringSubmatch(path); m != nil {
|
||||
log.Debugf("Path is a profile: %v (%v)", path, m[2])
|
||||
pk := ProfileKey{unescapeName(m[1])}
|
||||
switch m[2] {
|
||||
case "rules":
|
||||
log.Debugf("Profile rules")
|
||||
return ProfileRulesKey{ProfileKey: pk}
|
||||
case "labels":
|
||||
log.Debugf("Profile labels")
|
||||
return ProfileLabelsKey{ProfileKey: pk}
|
||||
}
|
||||
return nil
|
||||
} else if m := matchHostIp.FindStringSubmatch(path); m != nil {
|
||||
log.Debugf("Path is a host ID: %v", path)
|
||||
return HostIPKey{Hostname: m[1]}
|
||||
} else if m := matchWireguard.FindStringSubmatch(path); m != nil {
|
||||
log.Debugf("Path is a node name: %v", path)
|
||||
return WireguardKey{NodeName: m[1]}
|
||||
} else if m := matchIPPool.FindStringSubmatch(path); m != nil {
|
||||
log.Debugf("Path is a pool: %v", path)
|
||||
mungedCIDR := m[1]
|
||||
cidr := strings.Replace(mungedCIDR, "-", "/", 1)
|
||||
_, c, err := net.ParseCIDR(cidr)
|
||||
if err != nil {
|
||||
log.WithError(err).Warningf("Failed to parse CIDR %s", cidr)
|
||||
} else {
|
||||
return IPPoolKey{CIDR: *c}
|
||||
}
|
||||
} else if m := matchGlobalConfig.FindStringSubmatch(path); m != nil {
|
||||
log.Debugf("Path is a global felix config: %v", path)
|
||||
return GlobalConfigKey{Name: m[1]}
|
||||
} else if m := matchHostConfig.FindStringSubmatch(path); m != nil {
|
||||
log.Debugf("Path is a host config: %v", path)
|
||||
return HostConfigKey{Hostname: m[1], Name: m[2]}
|
||||
} else if matchReadyFlag.MatchString(path) {
|
||||
log.Debugf("Path is a ready flag: %v", path)
|
||||
return ReadyFlagKey{}
|
||||
} else if k := (NodeBGPConfigListOptions{}).KeyFromDefaultPath(path); k != nil {
|
||||
return k
|
||||
} else if k := (GlobalBGPConfigListOptions{}).KeyFromDefaultPath(path); k != nil {
|
||||
return k
|
||||
} else if k := (BlockAffinityListOptions{}).KeyFromDefaultPath(path); k != nil {
|
||||
return k
|
||||
} else if k := (BlockListOptions{}).KeyFromDefaultPath(path); k != nil {
|
||||
return k
|
||||
} else if k := (HostEndpointStatusListOptions{}).KeyFromDefaultPath(path); k != nil {
|
||||
return k
|
||||
} else if k := (WorkloadEndpointStatusListOptions{}).KeyFromDefaultPath(path); k != nil {
|
||||
return k
|
||||
} else if k := (ActiveStatusReportListOptions{}).KeyFromDefaultPath(path); k != nil {
|
||||
return k
|
||||
} else if k := (LastStatusReportListOptions{}).KeyFromDefaultPath(path); k != nil {
|
||||
return k
|
||||
} else {
|
||||
log.Debugf("Path is unknown: %v", path)
|
||||
}
|
||||
// Not a key we know about.
|
||||
return nil
|
||||
}
|
||||
|
||||
// ParseValue parses the default JSON representation of our data into one of
|
||||
// our value structs, according to the type of key. I.e. if passed a
|
||||
// PolicyKey as the first parameter, it will try to parse rawData into a
|
||||
// Policy struct.
|
||||
func ParseValue(key Key, rawData []byte) (interface{}, error) {
|
||||
valueType, err := key.valueType()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if valueType == rawStringType {
|
||||
return string(rawData), nil
|
||||
}
|
||||
if valueType == rawBoolType {
|
||||
return string(rawData) == "true", nil
|
||||
}
|
||||
if valueType == rawIPType {
|
||||
ip := net2.ParseIP(string(rawData))
|
||||
if ip == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return &net.IP{IP: ip}, nil
|
||||
}
|
||||
value := reflect.New(valueType)
|
||||
elem := value.Elem()
|
||||
if elem.Kind() == reflect.Struct && elem.NumField() > 0 {
|
||||
if elem.Field(0).Type() == reflect.ValueOf(key).Type() {
|
||||
elem.Field(0).Set(reflect.ValueOf(key))
|
||||
}
|
||||
}
|
||||
iface := value.Interface()
|
||||
err = json.Unmarshal(rawData, iface)
|
||||
if err != nil {
|
||||
// This is a special case to address backwards compatibility from the time when we had no state information as block affinity value.
|
||||
// example:
|
||||
// Key: "/calico/ipam/v2/host/myhost.io/ipv4/block/172.29.82.0-26"
|
||||
// Value: ""
|
||||
// In 3.0.7 we added block affinity state as the value, so old "" value is no longer a valid JSON, so for that
|
||||
// particular case we replace the "" with a "{}" so it can be parsed and we don't leak blocks after upgrade to Calico 3.0.7
|
||||
// See: https://github.com/projectcalico/calico/issues/1956
|
||||
if bytes.Equal(rawData, []byte(``)) && valueType == typeBlockAff {
|
||||
rawData = []byte(`{}`)
|
||||
if err = json.Unmarshal(rawData, iface); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
log.Warningf("Failed to unmarshal %#v into value %#v",
|
||||
string(rawData), value)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if elem.Kind() != reflect.Struct {
|
||||
// Pointer to a map or slice, unwrap.
|
||||
iface = elem.Interface()
|
||||
}
|
||||
return iface, nil
|
||||
}
|
||||
|
||||
// SerializeValue serializes a value in the model to a []byte to be stored in the datastore. This
|
||||
// performs the opposite processing to ParseValue()
|
||||
func SerializeValue(d *KVPair) ([]byte, error) {
|
||||
valueType, err := d.Key.valueType()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if d.Value == nil {
|
||||
return json.Marshal(nil)
|
||||
}
|
||||
if valueType == rawStringType {
|
||||
return []byte(d.Value.(string)), nil
|
||||
}
|
||||
if valueType == rawBoolType {
|
||||
return []byte(fmt.Sprint(d.Value)), nil
|
||||
}
|
||||
if valueType == rawIPType {
|
||||
return []byte(fmt.Sprint(d.Value)), nil
|
||||
}
|
||||
return json.Marshal(d.Value)
|
||||
}
|
||||
19
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/kubeendpointslice.go
generated
vendored
Normal file
19
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/kubeendpointslice.go
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) 2021 Tigera, Inc. All rights reserved.
|
||||
|
||||
// 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 model
|
||||
|
||||
const (
|
||||
KindKubernetesEndpointSlice = "KubernetesEndpointSlice"
|
||||
)
|
||||
19
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/kubenetworkpolicy.go
generated
vendored
Normal file
19
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/kubenetworkpolicy.go
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) 2021 Tigera, Inc. All rights reserved.
|
||||
|
||||
// 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 model
|
||||
|
||||
const (
|
||||
KindKubernetesNetworkPolicy = "KubernetesNetworkPolicy"
|
||||
)
|
||||
19
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/kubeservice.go
generated
vendored
Normal file
19
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/kubeservice.go
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) 2021 Tigera, Inc. All rights reserved.
|
||||
|
||||
// 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 model
|
||||
|
||||
const (
|
||||
KindKubernetesService = "KubernetesService"
|
||||
)
|
||||
30
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/name.go
generated
vendored
Normal file
30
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/name.go
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
// Copyright (c) 2016 Tigera, Inc. All rights reserved.
|
||||
|
||||
// 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 model
|
||||
|
||||
import "strings"
|
||||
|
||||
// escapeName removes any "/" from the name and URL encodes it to %2f,
|
||||
// and necessarily removes % and encodes to %25.
|
||||
func escapeName(name string) string {
|
||||
name = strings.Replace(name, "%", "%25", -1)
|
||||
return strings.Replace(name, "/", "%2f", -1)
|
||||
}
|
||||
|
||||
// unescapeName replaces %2f and %25 in the name back to be a / and %.
|
||||
func unescapeName(name string) string {
|
||||
name = strings.Replace(name, "%2f", "/", -1)
|
||||
return strings.Replace(name, "%25", "%", -1)
|
||||
}
|
||||
95
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/networkset.go
generated
vendored
Normal file
95
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/networkset.go
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
// Copyright (c) 2017-2018 Tigera, Inc. All rights reserved.
|
||||
|
||||
// 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 model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"regexp"
|
||||
|
||||
"reflect"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/errors"
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/net"
|
||||
)
|
||||
|
||||
var (
|
||||
matchNetworkSet = regexp.MustCompile("^/?calico/v1/netset/([^/]+)$")
|
||||
typeNetworkSet = reflect.TypeOf(NetworkSet{})
|
||||
)
|
||||
|
||||
type NetworkSetKey struct {
|
||||
Name string `json:"-" validate:"required,namespacedName"`
|
||||
}
|
||||
|
||||
func (key NetworkSetKey) defaultPath() (string, error) {
|
||||
if key.Name == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "name"}
|
||||
}
|
||||
e := fmt.Sprintf("/calico/v1/netset/%s", escapeName(key.Name))
|
||||
return e, nil
|
||||
}
|
||||
|
||||
func (key NetworkSetKey) defaultDeletePath() (string, error) {
|
||||
return key.defaultPath()
|
||||
}
|
||||
|
||||
func (key NetworkSetKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (key NetworkSetKey) valueType() (reflect.Type, error) {
|
||||
return typeNetworkSet, nil
|
||||
}
|
||||
|
||||
func (key NetworkSetKey) String() string {
|
||||
return fmt.Sprintf("NetworkSet(name=%s)", key.Name)
|
||||
}
|
||||
|
||||
type NetworkSetListOptions struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
func (options NetworkSetListOptions) defaultPathRoot() string {
|
||||
k := "/calico/v1/netset"
|
||||
if options.Name == "" {
|
||||
return k
|
||||
}
|
||||
k = k + fmt.Sprintf("/%s", escapeName(options.Name))
|
||||
return k
|
||||
}
|
||||
|
||||
func (options NetworkSetListOptions) KeyFromDefaultPath(path string) Key {
|
||||
log.Debugf("Get NetworkSet key from %s", path)
|
||||
r := matchNetworkSet.FindAllStringSubmatch(path, -1)
|
||||
if len(r) != 1 {
|
||||
log.Debugf("Didn't match regex")
|
||||
return nil
|
||||
}
|
||||
name := unescapeName(r[0][1])
|
||||
if options.Name != "" && name != options.Name {
|
||||
log.Debugf("Didn't match name %s != %s", options.Name, name)
|
||||
return nil
|
||||
}
|
||||
return NetworkSetKey{Name: name}
|
||||
}
|
||||
|
||||
type NetworkSet struct {
|
||||
Nets []net.IPNet `json:"nets,omitempty" validate:"omitempty,dive,cidr"`
|
||||
Labels map[string]string `json:"labels,omitempty" validate:"omitempty,labels"`
|
||||
ProfileIDs []string `json:"profile_ids,omitempty" validate:"omitempty,dive,name"`
|
||||
}
|
||||
282
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/node.go
generated
vendored
Normal file
282
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/node.go
generated
vendored
Normal file
@@ -0,0 +1,282 @@
|
||||
// Copyright (c) 2016,2020 Tigera, Inc. All rights reserved.
|
||||
|
||||
// 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 model
|
||||
|
||||
import (
|
||||
goerrors "errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"reflect"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/projectcalico/api/pkg/lib/numorstring"
|
||||
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/errors"
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/net"
|
||||
)
|
||||
|
||||
var (
|
||||
typeNode = reflect.TypeOf(Node{})
|
||||
typeHostMetadata = reflect.TypeOf(HostMetadata{})
|
||||
typeOrchRefs = reflect.TypeOf([]OrchRef{})
|
||||
typeHostIp = rawIPType
|
||||
typeWireguard = reflect.TypeOf(Wireguard{})
|
||||
matchHostMetadata = regexp.MustCompile(`^/?calico/v1/host/([^/]+)/metadata$`)
|
||||
matchHostIp = regexp.MustCompile(`^/?calico/v1/host/([^/]+)/bird_ip$`)
|
||||
matchWireguard = regexp.MustCompile(`^/?calico/v1/host/([^/]+)/wireguard$`)
|
||||
)
|
||||
|
||||
type Node struct {
|
||||
// Felix specific configuration
|
||||
FelixIPv4 *net.IP
|
||||
|
||||
// Node specific labels
|
||||
Labels map[string]string `json:"labels,omitempty"`
|
||||
|
||||
// BGP specific configuration
|
||||
BGPIPv4Addr *net.IP
|
||||
BGPIPv6Addr *net.IP
|
||||
BGPIPv4Net *net.IPNet
|
||||
BGPIPv6Net *net.IPNet
|
||||
BGPASNumber *numorstring.ASNumber
|
||||
OrchRefs []OrchRef `json:"orchRefs,omitempty"`
|
||||
}
|
||||
|
||||
type OrchRef struct {
|
||||
Orchestrator string `json:"orchestrator,omitempty"`
|
||||
NodeName string `json:"nodeName,omitempty"`
|
||||
}
|
||||
|
||||
type Wireguard struct {
|
||||
InterfaceIPv4Addr *net.IP `json:"interfaceIPv4Addr,omitempty"`
|
||||
PublicKey string `json:"publicKey,omitempty"`
|
||||
InterfaceIPv6Addr *net.IP `json:"interfaceIPv6Addr,omitempty"`
|
||||
PublicKeyV6 string `json:"publicKeyV6,omitempty"`
|
||||
}
|
||||
|
||||
type NodeKey struct {
|
||||
Hostname string
|
||||
}
|
||||
|
||||
func (key NodeKey) defaultPath() (string, error) {
|
||||
return "", goerrors.New("Node is a composite type, so not handled with a single path")
|
||||
}
|
||||
|
||||
func (key NodeKey) defaultDeletePath() (string, error) {
|
||||
return "", goerrors.New("Node is a composite type, so not handled with a single path")
|
||||
}
|
||||
|
||||
func (key NodeKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
return nil, goerrors.New("Node is composite type, so not handled with a single path")
|
||||
}
|
||||
|
||||
func (key NodeKey) valueType() (reflect.Type, error) {
|
||||
return typeNode, nil
|
||||
}
|
||||
|
||||
func (key NodeKey) String() string {
|
||||
return fmt.Sprintf("Node(name=%s)", key.Hostname)
|
||||
}
|
||||
|
||||
type NodeListOptions struct {
|
||||
Hostname string
|
||||
}
|
||||
|
||||
func (options NodeListOptions) defaultPathRoot() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (options NodeListOptions) KeyFromDefaultPath(path string) Key {
|
||||
return nil
|
||||
}
|
||||
|
||||
// The node is a composite of the following subcomponents:
|
||||
// - The host metadata. This is the primary subcomponent and is used to enumerate
|
||||
// hosts. However, for backwards compatibility, the etcd driver needs to handle
|
||||
// that this may not exist, and instead need to enumerate based on directory.
|
||||
// - The host IPv4 address used by Calico to lock down IPIP traffic.
|
||||
// - The BGP IPv4 and IPv6 addresses
|
||||
// - The BGP ASN.
|
||||
|
||||
type HostMetadata struct {
|
||||
}
|
||||
|
||||
type HostMetadataKey struct {
|
||||
Hostname string
|
||||
}
|
||||
|
||||
func (key HostMetadataKey) defaultPath() (string, error) {
|
||||
if key.Hostname == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "name"}
|
||||
}
|
||||
return fmt.Sprintf("/calico/v1/host/%s/metadata", key.Hostname), nil
|
||||
}
|
||||
|
||||
func (key HostMetadataKey) defaultDeletePath() (string, error) {
|
||||
if key.Hostname == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "name"}
|
||||
}
|
||||
return fmt.Sprintf("/calico/v1/host/%s", key.Hostname), nil
|
||||
}
|
||||
|
||||
func (key HostMetadataKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (key HostMetadataKey) valueType() (reflect.Type, error) {
|
||||
return typeHostMetadata, nil
|
||||
}
|
||||
|
||||
func (key HostMetadataKey) String() string {
|
||||
return fmt.Sprintf("Node(name=%s)", key.Hostname)
|
||||
}
|
||||
|
||||
type HostMetadataListOptions struct {
|
||||
Hostname string
|
||||
}
|
||||
|
||||
func (options HostMetadataListOptions) defaultPathRoot() string {
|
||||
if options.Hostname == "" {
|
||||
return "/calico/v1/host"
|
||||
} else {
|
||||
return fmt.Sprintf("/calico/v1/host/%s/metadata", options.Hostname)
|
||||
}
|
||||
}
|
||||
|
||||
func (options HostMetadataListOptions) KeyFromDefaultPath(path string) Key {
|
||||
log.Debugf("Get Node key from %s", path)
|
||||
if r := matchHostMetadata.FindAllStringSubmatch(path, -1); len(r) == 1 {
|
||||
return HostMetadataKey{Hostname: r[0][1]}
|
||||
} else {
|
||||
log.Debugf("%s didn't match regex", path)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// The Felix Host IP Key.
|
||||
type HostIPKey struct {
|
||||
Hostname string
|
||||
}
|
||||
|
||||
func (key HostIPKey) defaultPath() (string, error) {
|
||||
return fmt.Sprintf("/calico/v1/host/%s/bird_ip",
|
||||
key.Hostname), nil
|
||||
}
|
||||
|
||||
func (key HostIPKey) defaultDeletePath() (string, error) {
|
||||
return key.defaultPath()
|
||||
}
|
||||
|
||||
func (key HostIPKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (key HostIPKey) valueType() (reflect.Type, error) {
|
||||
return typeHostIp, nil
|
||||
}
|
||||
|
||||
func (key HostIPKey) String() string {
|
||||
return fmt.Sprintf("Node(name=%s)", key.Hostname)
|
||||
}
|
||||
|
||||
type OrchRefKey struct {
|
||||
Hostname string
|
||||
}
|
||||
|
||||
func (key OrchRefKey) defaultPath() (string, error) {
|
||||
return fmt.Sprintf("/calico/v1/host/%s/orchestrator_refs",
|
||||
key.Hostname), nil
|
||||
}
|
||||
|
||||
func (key OrchRefKey) defaultDeletePath() (string, error) {
|
||||
return key.defaultPath()
|
||||
}
|
||||
|
||||
func (key OrchRefKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (key OrchRefKey) valueType() (reflect.Type, error) {
|
||||
return typeOrchRefs, nil
|
||||
}
|
||||
|
||||
func (key OrchRefKey) String() string {
|
||||
return fmt.Sprintf("OrchRefs(nodename=%s)", key.Hostname)
|
||||
}
|
||||
|
||||
type OrchRefListOptions struct {
|
||||
Hostname string
|
||||
}
|
||||
|
||||
func (options OrchRefListOptions) defaultPathRoot() string {
|
||||
return fmt.Sprintf("/calico/v1/host/%s/orchestrator_refs", options.Hostname)
|
||||
}
|
||||
|
||||
func (options OrchRefListOptions) KeyFromDefaultPath(path string) Key {
|
||||
return OrchRefKey{Hostname: options.Hostname}
|
||||
}
|
||||
|
||||
// The Felix Wireguard Key.
|
||||
type WireguardKey struct {
|
||||
NodeName string
|
||||
}
|
||||
|
||||
func (key WireguardKey) defaultPath() (string, error) {
|
||||
if key.NodeName == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "name"}
|
||||
}
|
||||
return fmt.Sprintf("/calico/v1/host/%s/wireguard",
|
||||
key.NodeName), nil
|
||||
}
|
||||
|
||||
func (key WireguardKey) defaultDeletePath() (string, error) {
|
||||
return key.defaultPath()
|
||||
}
|
||||
|
||||
func (key WireguardKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (key WireguardKey) valueType() (reflect.Type, error) {
|
||||
return typeWireguard, nil
|
||||
}
|
||||
|
||||
func (key WireguardKey) String() string {
|
||||
return fmt.Sprintf("Node(nodename=%s)", key.NodeName)
|
||||
}
|
||||
|
||||
type WireguardListOptions struct {
|
||||
NodeName string
|
||||
}
|
||||
|
||||
func (options WireguardListOptions) defaultPathRoot() string {
|
||||
if options.NodeName == "" {
|
||||
return "/calico/v1/host"
|
||||
} else {
|
||||
return fmt.Sprintf("/calico/v1/host/%s/wireguard", options.NodeName)
|
||||
}
|
||||
}
|
||||
|
||||
func (options WireguardListOptions) KeyFromDefaultPath(path string) Key {
|
||||
log.Debugf("Get Node key from %s", path)
|
||||
if r := matchWireguard.FindAllStringSubmatch(path, -1); len(r) == 1 {
|
||||
return WireguardKey{NodeName: r[0][1]}
|
||||
} else {
|
||||
log.Debugf("%s didn't match regex", path)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
126
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/policy.go
generated
vendored
Normal file
126
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/policy.go
generated
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
// Copyright (c) 2016-2018 Tigera, Inc. All rights reserved.
|
||||
|
||||
// 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 model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"reflect"
|
||||
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
matchPolicy = regexp.MustCompile("^/?calico/v1/policy/tier/([^/]+)/policy/([^/]+)$")
|
||||
typePolicy = reflect.TypeOf(Policy{})
|
||||
)
|
||||
|
||||
type PolicyKey struct {
|
||||
Name string `json:"-" validate:"required,name"`
|
||||
}
|
||||
|
||||
func (key PolicyKey) defaultPath() (string, error) {
|
||||
if key.Name == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "name"}
|
||||
}
|
||||
e := fmt.Sprintf("/calico/v1/policy/tier/default/policy/%s",
|
||||
escapeName(key.Name))
|
||||
return e, nil
|
||||
}
|
||||
|
||||
func (key PolicyKey) defaultDeletePath() (string, error) {
|
||||
return key.defaultPath()
|
||||
}
|
||||
|
||||
func (key PolicyKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (key PolicyKey) valueType() (reflect.Type, error) {
|
||||
return typePolicy, nil
|
||||
}
|
||||
|
||||
func (key PolicyKey) String() string {
|
||||
return fmt.Sprintf("Policy(name=%s)", key.Name)
|
||||
}
|
||||
|
||||
type PolicyListOptions struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
func (options PolicyListOptions) defaultPathRoot() string {
|
||||
k := "/calico/v1/policy/tier/default/policy"
|
||||
if options.Name == "" {
|
||||
return k
|
||||
}
|
||||
k = k + fmt.Sprintf("/%s", escapeName(options.Name))
|
||||
return k
|
||||
}
|
||||
|
||||
func (options PolicyListOptions) KeyFromDefaultPath(path string) Key {
|
||||
log.Debugf("Get Policy key from %s", path)
|
||||
r := matchPolicy.FindAllStringSubmatch(path, -1)
|
||||
if len(r) != 1 {
|
||||
log.Debugf("Didn't match regex")
|
||||
return nil
|
||||
}
|
||||
name := unescapeName(r[0][2])
|
||||
if options.Name != "" && name != options.Name {
|
||||
log.Debugf("Didn't match name %s != %s", options.Name, name)
|
||||
return nil
|
||||
}
|
||||
return PolicyKey{Name: name}
|
||||
}
|
||||
|
||||
type Policy struct {
|
||||
Namespace string `json:"namespace,omitempty" validate:"omitempty"`
|
||||
Order *float64 `json:"order,omitempty" validate:"omitempty"`
|
||||
InboundRules []Rule `json:"inbound_rules,omitempty" validate:"omitempty,dive"`
|
||||
OutboundRules []Rule `json:"outbound_rules,omitempty" validate:"omitempty,dive"`
|
||||
Selector string `json:"selector" validate:"selector"`
|
||||
DoNotTrack bool `json:"untracked,omitempty"`
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
PreDNAT bool `json:"pre_dnat,omitempty"`
|
||||
ApplyOnForward bool `json:"apply_on_forward,omitempty"`
|
||||
Types []string `json:"types,omitempty"`
|
||||
}
|
||||
|
||||
func (p Policy) String() string {
|
||||
parts := make([]string, 0)
|
||||
if p.Order != nil {
|
||||
parts = append(parts, fmt.Sprintf("order:%v", *p.Order))
|
||||
}
|
||||
parts = append(parts, fmt.Sprintf("selector:%#v", p.Selector))
|
||||
inRules := make([]string, len(p.InboundRules))
|
||||
for ii, rule := range p.InboundRules {
|
||||
inRules[ii] = rule.String()
|
||||
}
|
||||
parts = append(parts, fmt.Sprintf("inbound:%v", strings.Join(inRules, ";")))
|
||||
outRules := make([]string, len(p.OutboundRules))
|
||||
for ii, rule := range p.OutboundRules {
|
||||
outRules[ii] = rule.String()
|
||||
}
|
||||
parts = append(parts, fmt.Sprintf("outbound:%v", strings.Join(outRules, ";")))
|
||||
parts = append(parts, fmt.Sprintf("untracked:%v", p.DoNotTrack))
|
||||
parts = append(parts, fmt.Sprintf("pre_dnat:%v", p.PreDNAT))
|
||||
parts = append(parts, fmt.Sprintf("apply_on_forward:%v", p.ApplyOnForward))
|
||||
parts = append(parts, fmt.Sprintf("types:%v", strings.Join(p.Types, ";")))
|
||||
return strings.Join(parts, ",")
|
||||
}
|
||||
208
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/profile.go
generated
vendored
Normal file
208
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/profile.go
generated
vendored
Normal file
@@ -0,0 +1,208 @@
|
||||
// Copyright (c) 2016 Tigera, Inc. All rights reserved.
|
||||
|
||||
// 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 model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"reflect"
|
||||
|
||||
"sort"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
matchProfile = regexp.MustCompile("^/?calico/v1/policy/profile/([^/]+)/(rules|labels)$")
|
||||
typeProfile = reflect.TypeOf(Profile{})
|
||||
)
|
||||
|
||||
// The profile key actually returns the common parent of the three separate entries.
|
||||
// It is useful to define this to re-use some of the common machinery, and can be used
|
||||
// for delete processing since delete needs to remove the common parent.
|
||||
type ProfileKey struct {
|
||||
Name string `json:"-" validate:"required,name"`
|
||||
}
|
||||
|
||||
func (key ProfileKey) defaultPath() (string, error) {
|
||||
if key.Name == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "name"}
|
||||
}
|
||||
e := fmt.Sprintf("/calico/v1/policy/profile/%s", escapeName(key.Name))
|
||||
return e, nil
|
||||
}
|
||||
|
||||
func (key ProfileKey) defaultDeletePath() (string, error) {
|
||||
return key.defaultPath()
|
||||
}
|
||||
|
||||
func (key ProfileKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (key ProfileKey) valueType() (reflect.Type, error) {
|
||||
return typeProfile, nil
|
||||
}
|
||||
|
||||
func (key ProfileKey) String() string {
|
||||
return fmt.Sprintf("Profile(name=%s)", key.Name)
|
||||
}
|
||||
|
||||
// ProfileRulesKey implements the KeyInterface for the profile rules
|
||||
type ProfileRulesKey struct {
|
||||
ProfileKey
|
||||
}
|
||||
|
||||
func (key ProfileRulesKey) defaultPath() (string, error) {
|
||||
e, err := key.ProfileKey.defaultPath()
|
||||
return e + "/rules", err
|
||||
}
|
||||
|
||||
func (key ProfileRulesKey) valueType() (reflect.Type, error) {
|
||||
return reflect.TypeOf(ProfileRules{}), nil
|
||||
}
|
||||
|
||||
func (key ProfileRulesKey) String() string {
|
||||
return fmt.Sprintf("ProfileRules(name=%s)", key.Name)
|
||||
}
|
||||
|
||||
// ProfileLabelsKey implements the KeyInterface for the profile labels
|
||||
type ProfileLabelsKey struct {
|
||||
ProfileKey
|
||||
}
|
||||
|
||||
func (key ProfileLabelsKey) defaultPath() (string, error) {
|
||||
e, err := key.ProfileKey.defaultPath()
|
||||
return e + "/labels", err
|
||||
}
|
||||
|
||||
func (key ProfileLabelsKey) valueType() (reflect.Type, error) {
|
||||
return reflect.TypeOf(map[string]string{}), nil
|
||||
}
|
||||
|
||||
func (key ProfileLabelsKey) String() string {
|
||||
return fmt.Sprintf("ProfileLabels(name=%s)", key.Name)
|
||||
}
|
||||
|
||||
type ProfileListOptions struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
func (options ProfileListOptions) defaultPathRoot() string {
|
||||
k := "/calico/v1/policy/profile"
|
||||
if options.Name == "" {
|
||||
return k
|
||||
}
|
||||
k = k + fmt.Sprintf("/%s", escapeName(options.Name))
|
||||
return k
|
||||
}
|
||||
|
||||
func (options ProfileListOptions) KeyFromDefaultPath(path string) Key {
|
||||
log.Debugf("Get Profile key from %s", path)
|
||||
r := matchProfile.FindAllStringSubmatch(path, -1)
|
||||
if len(r) != 1 {
|
||||
log.Debugf("Didn't match regex")
|
||||
return nil
|
||||
}
|
||||
name := unescapeName(r[0][1])
|
||||
kind := r[0][2]
|
||||
if options.Name != "" && name != options.Name {
|
||||
log.Debugf("Didn't match name %s != %s", options.Name, name)
|
||||
return nil
|
||||
}
|
||||
pk := ProfileKey{Name: name}
|
||||
switch kind {
|
||||
case "labels":
|
||||
return ProfileLabelsKey{ProfileKey: pk}
|
||||
case "rules":
|
||||
return ProfileRulesKey{ProfileKey: pk}
|
||||
}
|
||||
return pk
|
||||
}
|
||||
|
||||
// The profile structure is defined to allow the client to define a conversion interface
|
||||
// to map between the API and backend profiles. However, in the actual underlying
|
||||
// implementation the profile is written as three separate entries - rules, tags and labels.
|
||||
type Profile struct {
|
||||
Rules ProfileRules
|
||||
Tags []string
|
||||
Labels map[string]string
|
||||
}
|
||||
|
||||
type ProfileRules struct {
|
||||
InboundRules []Rule `json:"inbound_rules,omitempty" validate:"omitempty,dive"`
|
||||
OutboundRules []Rule `json:"outbound_rules,omitempty" validate:"omitempty,dive"`
|
||||
}
|
||||
|
||||
func (_ *ProfileListOptions) ListConvert(ds []*KVPair) []*KVPair {
|
||||
|
||||
profiles := make(map[string]*KVPair)
|
||||
var name string
|
||||
for _, d := range ds {
|
||||
switch t := d.Key.(type) {
|
||||
case ProfileLabelsKey:
|
||||
name = t.Name
|
||||
case ProfileRulesKey:
|
||||
name = t.Name
|
||||
default:
|
||||
panic(fmt.Errorf("Unexpected key type: %v", t))
|
||||
}
|
||||
|
||||
// Get the KVPair for the profile, initialising if just created.
|
||||
pd, ok := profiles[name]
|
||||
if !ok {
|
||||
log.Debugf("Initialise profile %v", name)
|
||||
pd = &KVPair{
|
||||
Value: &Profile{},
|
||||
Key: ProfileKey{Name: name},
|
||||
}
|
||||
profiles[name] = pd
|
||||
}
|
||||
|
||||
p := pd.Value.(*Profile)
|
||||
switch t := d.Value.(type) {
|
||||
case map[string]string: // must be labels
|
||||
log.Debugf("Store labels %v", t)
|
||||
p.Labels = t
|
||||
case *ProfileRules: // must be rules
|
||||
log.Debugf("Store rules %v", t)
|
||||
p.Rules = *t
|
||||
default:
|
||||
panic(fmt.Errorf("Unexpected type: %v", t))
|
||||
}
|
||||
pd.Value = p
|
||||
}
|
||||
|
||||
log.Debugf("Map of profiles: %v", profiles)
|
||||
|
||||
// To store the keys in slice in sorted order
|
||||
var keys []string
|
||||
for k := range profiles {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
out := make([]*KVPair, len(keys))
|
||||
for i, k := range keys {
|
||||
out[i] = profiles[k]
|
||||
}
|
||||
|
||||
log.Debugf("Sorted groups of profiles: %v", out)
|
||||
|
||||
return out
|
||||
}
|
||||
34
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/region.go
generated
vendored
Normal file
34
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/region.go
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
// Copyright (c) 2018 Tigera, Inc. All rights reserved.
|
||||
//
|
||||
// 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 model
|
||||
|
||||
import "fmt"
|
||||
|
||||
const (
|
||||
NoRegion string = "no-region"
|
||||
RegionPrefix string = "region-"
|
||||
)
|
||||
|
||||
func RegionString(region string) string {
|
||||
if region != "" {
|
||||
return RegionPrefix + region
|
||||
} else {
|
||||
return NoRegion
|
||||
}
|
||||
}
|
||||
|
||||
func ErrorSlashInRegionString(regionString string) error {
|
||||
return fmt.Errorf("RegionString %v is invalid because it includes a slash", regionString)
|
||||
}
|
||||
321
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/resource.go
generated
vendored
Normal file
321
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/resource.go
generated
vendored
Normal file
@@ -0,0 +1,321 @@
|
||||
// Copyright (c) 2016-2021 Tigera, Inc. All rights reserved.
|
||||
//
|
||||
// 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 model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
kapiv1 "k8s.io/api/core/v1"
|
||||
discovery "k8s.io/api/discovery/v1"
|
||||
|
||||
apiv3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3"
|
||||
|
||||
libapiv3 "github.com/projectcalico/calico/libcalico-go/lib/apis/v3"
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/namespace"
|
||||
)
|
||||
|
||||
// Name/type information about a single resource.
|
||||
type resourceInfo struct {
|
||||
typeOf reflect.Type
|
||||
plural string
|
||||
kindLower string
|
||||
kind string
|
||||
}
|
||||
|
||||
var (
|
||||
matchGlobalResource = regexp.MustCompile("^/calico/resources/v3/projectcalico[.]org/([^/]+)/([^/]+)$")
|
||||
matchNamespacedResource = regexp.MustCompile("^/calico/resources/v3/projectcalico[.]org/([^/]+)/([^/]+)/([^/]+)$")
|
||||
resourceInfoByKindLower = make(map[string]resourceInfo)
|
||||
resourceInfoByPlural = make(map[string]resourceInfo)
|
||||
)
|
||||
|
||||
func registerResourceInfo(kind string, plural string, typeOf reflect.Type) {
|
||||
kindLower := strings.ToLower(kind)
|
||||
plural = strings.ToLower(plural)
|
||||
ri := resourceInfo{
|
||||
typeOf: typeOf,
|
||||
kindLower: kindLower,
|
||||
kind: kind,
|
||||
plural: plural,
|
||||
}
|
||||
resourceInfoByKindLower[kindLower] = ri
|
||||
resourceInfoByPlural[plural] = ri
|
||||
}
|
||||
|
||||
func init() {
|
||||
registerResourceInfo(
|
||||
apiv3.KindBGPPeer,
|
||||
"bgppeers",
|
||||
reflect.TypeOf(apiv3.BGPPeer{}),
|
||||
)
|
||||
registerResourceInfo(
|
||||
apiv3.KindBGPConfiguration,
|
||||
"bgpconfigurations",
|
||||
reflect.TypeOf(apiv3.BGPConfiguration{}),
|
||||
)
|
||||
registerResourceInfo(
|
||||
apiv3.KindClusterInformation,
|
||||
"clusterinformations",
|
||||
reflect.TypeOf(apiv3.ClusterInformation{}),
|
||||
)
|
||||
registerResourceInfo(
|
||||
apiv3.KindFelixConfiguration,
|
||||
"felixconfigurations",
|
||||
reflect.TypeOf(apiv3.FelixConfiguration{}),
|
||||
)
|
||||
registerResourceInfo(
|
||||
apiv3.KindGlobalNetworkPolicy,
|
||||
"globalnetworkpolicies",
|
||||
reflect.TypeOf(apiv3.GlobalNetworkPolicy{}),
|
||||
)
|
||||
registerResourceInfo(
|
||||
apiv3.KindHostEndpoint,
|
||||
"hostendpoints",
|
||||
reflect.TypeOf(apiv3.HostEndpoint{}),
|
||||
)
|
||||
registerResourceInfo(
|
||||
apiv3.KindGlobalNetworkSet,
|
||||
"globalnetworksets",
|
||||
reflect.TypeOf(apiv3.GlobalNetworkSet{}),
|
||||
)
|
||||
registerResourceInfo(
|
||||
apiv3.KindIPPool,
|
||||
"ippools",
|
||||
reflect.TypeOf(apiv3.IPPool{}),
|
||||
)
|
||||
registerResourceInfo(
|
||||
apiv3.KindIPReservation,
|
||||
"ipreservations",
|
||||
reflect.TypeOf(apiv3.IPReservation{}),
|
||||
)
|
||||
registerResourceInfo(
|
||||
apiv3.KindNetworkPolicy,
|
||||
"networkpolicies",
|
||||
reflect.TypeOf(apiv3.NetworkPolicy{}),
|
||||
)
|
||||
registerResourceInfo(
|
||||
KindKubernetesNetworkPolicy,
|
||||
"kubernetesnetworkpolicies",
|
||||
reflect.TypeOf(apiv3.NetworkPolicy{}),
|
||||
)
|
||||
registerResourceInfo(
|
||||
KindKubernetesEndpointSlice,
|
||||
"kubernetesendpointslices",
|
||||
reflect.TypeOf(discovery.EndpointSlice{}),
|
||||
)
|
||||
registerResourceInfo(
|
||||
apiv3.KindNetworkSet,
|
||||
"networksets",
|
||||
reflect.TypeOf(apiv3.NetworkSet{}),
|
||||
)
|
||||
registerResourceInfo(
|
||||
libapiv3.KindNode,
|
||||
"nodes",
|
||||
reflect.TypeOf(libapiv3.Node{}),
|
||||
)
|
||||
registerResourceInfo(
|
||||
apiv3.KindCalicoNodeStatus,
|
||||
"caliconodestatuses",
|
||||
reflect.TypeOf(apiv3.CalicoNodeStatus{}),
|
||||
)
|
||||
registerResourceInfo(
|
||||
apiv3.KindProfile,
|
||||
"profiles",
|
||||
reflect.TypeOf(apiv3.Profile{}),
|
||||
)
|
||||
registerResourceInfo(
|
||||
libapiv3.KindWorkloadEndpoint,
|
||||
"workloadendpoints",
|
||||
reflect.TypeOf(libapiv3.WorkloadEndpoint{}),
|
||||
)
|
||||
registerResourceInfo(
|
||||
libapiv3.KindIPAMConfig,
|
||||
"ipamconfigs",
|
||||
reflect.TypeOf(libapiv3.IPAMConfig{}),
|
||||
)
|
||||
registerResourceInfo(
|
||||
apiv3.KindKubeControllersConfiguration,
|
||||
"kubecontrollersconfigurations",
|
||||
reflect.TypeOf(apiv3.KubeControllersConfiguration{}))
|
||||
registerResourceInfo(
|
||||
KindKubernetesService,
|
||||
"kubernetesservice",
|
||||
reflect.TypeOf(kapiv1.Service{}),
|
||||
)
|
||||
registerResourceInfo(
|
||||
libapiv3.KindBlockAffinity,
|
||||
"blockaffinities",
|
||||
reflect.TypeOf(libapiv3.BlockAffinity{}),
|
||||
)
|
||||
registerResourceInfo(
|
||||
apiv3.KindBGPFilter,
|
||||
"BGPFilters",
|
||||
reflect.TypeOf(apiv3.BGPFilter{}),
|
||||
)
|
||||
}
|
||||
|
||||
type ResourceKey struct {
|
||||
// The name of the resource.
|
||||
Name string
|
||||
// The namespace of the resource. Not required if the resource is not namespaced.
|
||||
Namespace string
|
||||
// The resource kind.
|
||||
Kind string
|
||||
}
|
||||
|
||||
func (key ResourceKey) defaultPath() (string, error) {
|
||||
return key.defaultDeletePath()
|
||||
}
|
||||
|
||||
func (key ResourceKey) defaultDeletePath() (string, error) {
|
||||
ri, ok := resourceInfoByKindLower[strings.ToLower(key.Kind)]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("couldn't convert key: %+v", key)
|
||||
}
|
||||
if namespace.IsNamespaced(key.Kind) {
|
||||
return fmt.Sprintf("/calico/resources/v3/projectcalico.org/%s/%s/%s", ri.plural, key.Namespace, key.Name), nil
|
||||
}
|
||||
return fmt.Sprintf("/calico/resources/v3/projectcalico.org/%s/%s", ri.plural, key.Name), nil
|
||||
}
|
||||
|
||||
func (key ResourceKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (key ResourceKey) valueType() (reflect.Type, error) {
|
||||
ri, ok := resourceInfoByKindLower[strings.ToLower(key.Kind)]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("Unexpected resource kind: " + key.Kind)
|
||||
}
|
||||
return ri.typeOf, nil
|
||||
}
|
||||
|
||||
func (key ResourceKey) String() string {
|
||||
if namespace.IsNamespaced(key.Kind) {
|
||||
return fmt.Sprintf("%s(%s/%s)", key.Kind, key.Namespace, key.Name)
|
||||
}
|
||||
return fmt.Sprintf("%s(%s)", key.Kind, key.Name)
|
||||
}
|
||||
|
||||
type ResourceListOptions struct {
|
||||
// The name of the resource.
|
||||
Name string
|
||||
// The namespace of the resource. Not required if the resource is not namespaced.
|
||||
Namespace string
|
||||
// The resource kind.
|
||||
Kind string
|
||||
// Whether the name is prefix rather than the full name.
|
||||
Prefix bool
|
||||
}
|
||||
|
||||
// If the Kind, Namespace and Name are specified, but the Name is a prefix then the
|
||||
// last segment of this path is a prefix.
|
||||
func (options ResourceListOptions) IsLastSegmentIsPrefix() bool {
|
||||
return len(options.Kind) != 0 &&
|
||||
(len(options.Namespace) != 0 || !namespace.IsNamespaced(options.Kind)) &&
|
||||
len(options.Name) != 0 &&
|
||||
options.Prefix
|
||||
}
|
||||
|
||||
func (options ResourceListOptions) KeyFromDefaultPath(path string) Key {
|
||||
ri, ok := resourceInfoByKindLower[strings.ToLower(options.Kind)]
|
||||
if !ok {
|
||||
log.Panic("Unexpected resource kind: " + options.Kind)
|
||||
}
|
||||
|
||||
if namespace.IsNamespaced(options.Kind) {
|
||||
log.Debugf("Get Namespaced Resource key from %s", path)
|
||||
r := matchNamespacedResource.FindAllStringSubmatch(path, -1)
|
||||
if len(r) != 1 {
|
||||
log.Debugf("Didn't match regex")
|
||||
return nil
|
||||
}
|
||||
kindPlural := r[0][1]
|
||||
namespace := r[0][2]
|
||||
name := r[0][3]
|
||||
if len(options.Kind) == 0 {
|
||||
panic("Kind must be specified in List option but is not")
|
||||
}
|
||||
if kindPlural != ri.plural {
|
||||
log.Debugf("Didn't match kind %s != %s", kindPlural, kindPlural)
|
||||
return nil
|
||||
}
|
||||
if len(options.Namespace) != 0 && namespace != options.Namespace {
|
||||
log.Debugf("Didn't match namespace %s != %s", options.Namespace, namespace)
|
||||
return nil
|
||||
}
|
||||
if len(options.Name) != 0 {
|
||||
if options.Prefix && !strings.HasPrefix(name, options.Name) {
|
||||
log.Debugf("Didn't match name prefix %s != prefix(%s)", options.Name, name)
|
||||
return nil
|
||||
} else if !options.Prefix && name != options.Name {
|
||||
log.Debugf("Didn't match name %s != %s", options.Name, name)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return ResourceKey{Kind: options.Kind, Namespace: namespace, Name: name}
|
||||
}
|
||||
|
||||
log.Debugf("Get Global Resource key from %s", path)
|
||||
r := matchGlobalResource.FindAllStringSubmatch(path, -1)
|
||||
if len(r) != 1 {
|
||||
log.Debugf("Didn't match regex")
|
||||
return nil
|
||||
}
|
||||
kindPlural := r[0][1]
|
||||
name := r[0][2]
|
||||
if kindPlural != ri.plural {
|
||||
log.Debugf("Didn't match kind %s != %s", kindPlural, ri.plural)
|
||||
return nil
|
||||
}
|
||||
if len(options.Name) != 0 {
|
||||
if options.Prefix && !strings.HasPrefix(name, options.Name) {
|
||||
log.Debugf("Didn't match name prefix %s != prefix(%s)", options.Name, name)
|
||||
return nil
|
||||
} else if !options.Prefix && name != options.Name {
|
||||
log.Debugf("Didn't match name %s != %s", options.Name, name)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return ResourceKey{Kind: options.Kind, Name: name}
|
||||
}
|
||||
|
||||
func (options ResourceListOptions) defaultPathRoot() string {
|
||||
ri, ok := resourceInfoByKindLower[strings.ToLower(options.Kind)]
|
||||
if !ok {
|
||||
log.Panic("Unexpected resource kind: " + options.Kind)
|
||||
}
|
||||
|
||||
k := "/calico/resources/v3/projectcalico.org/" + ri.plural
|
||||
if namespace.IsNamespaced(options.Kind) {
|
||||
if options.Namespace == "" {
|
||||
return k
|
||||
}
|
||||
k = k + "/" + options.Namespace
|
||||
}
|
||||
if options.Name == "" {
|
||||
return k
|
||||
}
|
||||
return k + "/" + options.Name
|
||||
}
|
||||
|
||||
func (options ResourceListOptions) String() string {
|
||||
return options.Kind
|
||||
}
|
||||
268
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/rule.go
generated
vendored
Normal file
268
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/rule.go
generated
vendored
Normal file
@@ -0,0 +1,268 @@
|
||||
// Copyright (c) 2016-2018 Tigera, Inc. All rights reserved.
|
||||
|
||||
// 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 model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
apiv3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3"
|
||||
"github.com/projectcalico/api/pkg/lib/numorstring"
|
||||
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/net"
|
||||
)
|
||||
|
||||
type Rule struct {
|
||||
Action string `json:"action,omitempty"`
|
||||
|
||||
IPVersion *int `json:"ip_version,omitempty" validate:"omitempty,ipVersion"`
|
||||
|
||||
Protocol *numorstring.Protocol `json:"protocol,omitempty" validate:"omitempty"`
|
||||
NotProtocol *numorstring.Protocol `json:"!protocol,omitempty" validate:"omitempty"`
|
||||
|
||||
// ICMP validation notes: 0 is a valid (common) ICMP type and code. Type = 255 is not assigned
|
||||
// to any protocol and the Linux kernel doesn't support matching on it so we validate against
|
||||
// it.
|
||||
ICMPType *int `json:"icmp_type,omitempty" validate:"omitempty,gte=0,lt=255"`
|
||||
ICMPCode *int `json:"icmp_code,omitempty" validate:"omitempty,gte=0,lte=255"`
|
||||
NotICMPType *int `json:"!icmp_type,omitempty" validate:"omitempty,gte=0,lt=255"`
|
||||
NotICMPCode *int `json:"!icmp_code,omitempty" validate:"omitempty,gte=0,lte=255"`
|
||||
|
||||
SrcTag string `json:"src_tag,omitempty" validate:"omitempty,tag"`
|
||||
SrcNet *net.IPNet `json:"src_net,omitempty" validate:"omitempty"`
|
||||
SrcNets []*net.IPNet `json:"src_nets,omitempty" validate:"omitempty"`
|
||||
SrcSelector string `json:"src_selector,omitempty" validate:"omitempty,selector"`
|
||||
SrcPorts []numorstring.Port `json:"src_ports,omitempty" validate:"omitempty,dive"`
|
||||
SrcService string `json:"src_service,omitempty" validate:"omitempty"`
|
||||
SrcServiceNamespace string `json:"src_service_ns,omitempty" validate:"omitempty"`
|
||||
DstTag string `json:"dst_tag,omitempty" validate:"omitempty,tag"`
|
||||
DstSelector string `json:"dst_selector,omitempty" validate:"omitempty,selector"`
|
||||
DstNet *net.IPNet `json:"dst_net,omitempty" validate:"omitempty"`
|
||||
DstNets []*net.IPNet `json:"dst_nets,omitempty" validate:"omitempty"`
|
||||
DstPorts []numorstring.Port `json:"dst_ports,omitempty" validate:"omitempty,dive"`
|
||||
DstService string `json:"dst_service,omitempty" validate:"omitempty"`
|
||||
DstServiceNamespace string `json:"dst_service_ns,omitempty" validate:"omitempty"`
|
||||
|
||||
NotSrcTag string `json:"!src_tag,omitempty" validate:"omitempty,tag"`
|
||||
NotSrcNet *net.IPNet `json:"!src_net,omitempty" validate:"omitempty"`
|
||||
NotSrcNets []*net.IPNet `json:"!src_nets,omitempty" validate:"omitempty"`
|
||||
NotSrcSelector string `json:"!src_selector,omitempty" validate:"omitempty,selector"`
|
||||
NotSrcPorts []numorstring.Port `json:"!src_ports,omitempty" validate:"omitempty,dive"`
|
||||
NotDstTag string `json:"!dst_tag,omitempty" validate:"omitempty"`
|
||||
NotDstSelector string `json:"!dst_selector,omitempty" validate:"omitempty,selector"`
|
||||
NotDstNet *net.IPNet `json:"!dst_net,omitempty" validate:"omitempty"`
|
||||
NotDstNets []*net.IPNet `json:"!dst_nets,omitempty" validate:"omitempty"`
|
||||
NotDstPorts []numorstring.Port `json:"!dst_ports,omitempty" validate:"omitempty,dive"`
|
||||
|
||||
// These fields allow us to pass through the raw match criteria from the V3 datamodel unmodified.
|
||||
// The selectors above are formed in the update processor layer by combining the original
|
||||
// selectors, namespace selectors and service account selectors into one.
|
||||
OriginalSrcSelector string `json:"orig_src_selector,omitempty" validate:"omitempty,selector"`
|
||||
OriginalSrcNamespaceSelector string `json:"orig_src_namespace_selector,omitempty" validate:"omitempty,selector"`
|
||||
OriginalDstSelector string `json:"orig_dst_selector,omitempty" validate:"omitempty,selector"`
|
||||
OriginalDstNamespaceSelector string `json:"orig_dst_namespace_selector,omitempty" validate:"omitempty,selector"`
|
||||
OriginalNotSrcSelector string `json:"!orig_src_selector,omitempty" validate:"omitempty,selector"`
|
||||
OriginalNotDstSelector string `json:"!orig_dst_selector,omitempty" validate:"omitempty,selector"`
|
||||
OriginalSrcServiceAccountNames []string `json:"orig_src_service_acct_names,omitempty" validate:"omitempty"`
|
||||
OriginalSrcServiceAccountSelector string `json:"orig_src_service_acct_selector,omitempty" validate:"omitempty,selector"`
|
||||
OriginalDstServiceAccountNames []string `json:"orig_dst_service_acct_names,omitempty" validate:"omitempty"`
|
||||
OriginalDstServiceAccountSelector string `json:"orig_dst_service_acct_selector,omitempty" validate:"omitempty,selector"`
|
||||
|
||||
// These fields allow us to pass through application layer selectors from the V3 datamodel.
|
||||
HTTPMatch *HTTPMatch `json:"http,omitempty" validate:"omitempty"`
|
||||
|
||||
LogPrefix string `json:"log_prefix,omitempty" validate:"omitempty"`
|
||||
|
||||
Metadata *RuleMetadata `json:"metadata,omitempty" validate:"omitempty"`
|
||||
}
|
||||
|
||||
type HTTPMatch struct {
|
||||
Methods []string `json:"methods,omitempty" validate:"omitempty"`
|
||||
Paths []apiv3.HTTPPath `json:"paths,omitempty" validate:"omitempty"`
|
||||
}
|
||||
|
||||
type RuleMetadata struct {
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
}
|
||||
|
||||
func combineNets(n *net.IPNet, nets []*net.IPNet) []*net.IPNet {
|
||||
if n == nil {
|
||||
return nets
|
||||
}
|
||||
if len(nets) == 0 {
|
||||
return []*net.IPNet{n}
|
||||
}
|
||||
var combination = make([]*net.IPNet, len(nets)+1)
|
||||
copy(combination, nets)
|
||||
combination[len(nets)] = n
|
||||
return combination
|
||||
}
|
||||
|
||||
func (r Rule) AllSrcNets() []*net.IPNet {
|
||||
return combineNets(r.SrcNet, r.SrcNets)
|
||||
}
|
||||
|
||||
func (r Rule) AllDstNets() []*net.IPNet {
|
||||
return combineNets(r.DstNet, r.DstNets)
|
||||
}
|
||||
|
||||
func (r Rule) AllNotSrcNets() []*net.IPNet {
|
||||
return combineNets(r.NotSrcNet, r.NotSrcNets)
|
||||
}
|
||||
|
||||
func (r Rule) AllNotDstNets() []*net.IPNet {
|
||||
return combineNets(r.NotDstNet, r.NotDstNets)
|
||||
}
|
||||
|
||||
func joinNets(nets []*net.IPNet) string {
|
||||
parts := make([]string, len(nets))
|
||||
for i, n := range nets {
|
||||
parts[i] = n.String()
|
||||
}
|
||||
return strings.Join(parts, ",")
|
||||
}
|
||||
|
||||
func (r Rule) String() string {
|
||||
parts := make([]string, 0)
|
||||
// Action.
|
||||
if r.Action != "" {
|
||||
parts = append(parts, r.Action)
|
||||
} else {
|
||||
parts = append(parts, "Allow")
|
||||
}
|
||||
|
||||
// Global packet attributes that don't depend on direction.
|
||||
if r.Protocol != nil {
|
||||
parts = append(parts, r.Protocol.String())
|
||||
}
|
||||
if r.NotProtocol != nil {
|
||||
parts = append(parts, "!"+r.NotProtocol.String())
|
||||
}
|
||||
|
||||
if r.ICMPType != nil {
|
||||
parts = append(parts, "type", strconv.Itoa(*r.ICMPType))
|
||||
}
|
||||
if r.ICMPCode != nil {
|
||||
parts = append(parts, "code", strconv.Itoa(*r.ICMPCode))
|
||||
}
|
||||
if r.NotICMPType != nil {
|
||||
parts = append(parts, "!type", strconv.Itoa(*r.NotICMPType))
|
||||
}
|
||||
if r.NotICMPCode != nil {
|
||||
parts = append(parts, "!code", strconv.Itoa(*r.NotICMPCode))
|
||||
}
|
||||
|
||||
{
|
||||
// Source attributes. New block ensures that fromParts goes out-of-scope before
|
||||
// we calculate toParts. This prevents copy/paste errors.
|
||||
fromParts := make([]string, 0)
|
||||
if len(r.SrcPorts) > 0 {
|
||||
srcPorts := make([]string, len(r.SrcPorts))
|
||||
for ii, port := range r.SrcPorts {
|
||||
srcPorts[ii] = port.String()
|
||||
}
|
||||
fromParts = append(fromParts, "ports", strings.Join(srcPorts, ","))
|
||||
}
|
||||
if r.SrcTag != "" {
|
||||
fromParts = append(fromParts, "tag", r.SrcTag)
|
||||
}
|
||||
if r.SrcSelector != "" {
|
||||
fromParts = append(fromParts, "selector", fmt.Sprintf("%#v", r.SrcSelector))
|
||||
}
|
||||
srcNets := r.AllSrcNets()
|
||||
if len(srcNets) != 0 {
|
||||
fromParts = append(fromParts, "cidr", joinNets(srcNets))
|
||||
}
|
||||
if len(r.NotSrcPorts) > 0 {
|
||||
notSrcPorts := make([]string, len(r.NotSrcPorts))
|
||||
for ii, port := range r.NotSrcPorts {
|
||||
notSrcPorts[ii] = port.String()
|
||||
}
|
||||
fromParts = append(fromParts, "!ports", strings.Join(notSrcPorts, ","))
|
||||
}
|
||||
if r.NotSrcTag != "" {
|
||||
fromParts = append(fromParts, "!tag", r.NotSrcTag)
|
||||
}
|
||||
if r.NotSrcSelector != "" {
|
||||
fromParts = append(fromParts, "!selector", fmt.Sprintf("%#v", r.NotSrcSelector))
|
||||
}
|
||||
notSrcNets := r.AllNotSrcNets()
|
||||
if len(notSrcNets) != 0 {
|
||||
fromParts = append(fromParts, "!cidr", joinNets(notSrcNets))
|
||||
}
|
||||
|
||||
if len(fromParts) > 0 {
|
||||
parts = append(parts, "from")
|
||||
parts = append(parts, fromParts...)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Destination attributes.
|
||||
toParts := make([]string, 0)
|
||||
if len(r.DstPorts) > 0 {
|
||||
DstPorts := make([]string, len(r.DstPorts))
|
||||
for ii, port := range r.DstPorts {
|
||||
DstPorts[ii] = port.String()
|
||||
}
|
||||
toParts = append(toParts, "ports", strings.Join(DstPorts, ","))
|
||||
}
|
||||
if r.DstTag != "" {
|
||||
toParts = append(toParts, "tag", r.DstTag)
|
||||
}
|
||||
if r.DstSelector != "" {
|
||||
toParts = append(toParts, "selector", fmt.Sprintf("%#v", r.DstSelector))
|
||||
}
|
||||
dstNets := r.AllDstNets()
|
||||
if len(dstNets) != 0 {
|
||||
toParts = append(toParts, "cidr", joinNets(dstNets))
|
||||
}
|
||||
if len(r.NotDstPorts) > 0 {
|
||||
notDstPorts := make([]string, len(r.NotDstPorts))
|
||||
for ii, port := range r.NotDstPorts {
|
||||
notDstPorts[ii] = port.String()
|
||||
}
|
||||
toParts = append(toParts, "!ports", strings.Join(notDstPorts, ","))
|
||||
}
|
||||
if r.NotDstTag != "" {
|
||||
toParts = append(toParts, "!tag", r.NotDstTag)
|
||||
}
|
||||
if r.NotDstSelector != "" {
|
||||
toParts = append(toParts, "!selector", fmt.Sprintf("%#v", r.NotDstSelector))
|
||||
}
|
||||
notDstNets := r.AllNotDstNets()
|
||||
if len(notDstNets) != 0 {
|
||||
toParts = append(toParts, "!cidr", joinNets(notDstNets))
|
||||
}
|
||||
|
||||
// HTTPMatch are destination rules.
|
||||
if r.HTTPMatch != nil {
|
||||
if len(r.HTTPMatch.Methods) > 0 {
|
||||
toParts = append(toParts, "httpMethods", fmt.Sprintf("%+v", r.HTTPMatch.Methods))
|
||||
}
|
||||
if len(r.HTTPMatch.Paths) > 0 {
|
||||
toParts = append(toParts, "httpPaths", fmt.Sprintf("%+v", r.HTTPMatch.Paths))
|
||||
}
|
||||
}
|
||||
|
||||
if len(toParts) > 0 {
|
||||
parts = append(parts, "to")
|
||||
parts = append(parts, toParts...)
|
||||
}
|
||||
}
|
||||
|
||||
return strings.Join(parts, " ")
|
||||
}
|
||||
184
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/statusreports.go
generated
vendored
Normal file
184
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/statusreports.go
generated
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
// Copyright (c) 2016-2018 Tigera, Inc. All rights reserved.
|
||||
//
|
||||
// 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 model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
matchActiveStatusReport = regexp.MustCompile("^/?calico/felix/v2/([^/]+)/host/([^/]+)/status$")
|
||||
matchLastStatusReport = regexp.MustCompile("^/?calico/felix/v2/([^/]+)/host/([^/]+)/last_reported_status")
|
||||
typeStatusReport = reflect.TypeOf(StatusReport{})
|
||||
)
|
||||
|
||||
type ActiveStatusReportKey struct {
|
||||
Hostname string `json:"-" validate:"required,hostname"`
|
||||
RegionString string
|
||||
}
|
||||
|
||||
func (key ActiveStatusReportKey) defaultPath() (string, error) {
|
||||
return key.defaultDeletePath()
|
||||
}
|
||||
|
||||
func (key ActiveStatusReportKey) defaultDeletePath() (string, error) {
|
||||
if key.Hostname == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "hostname"}
|
||||
}
|
||||
if key.RegionString == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "regionString"}
|
||||
}
|
||||
if strings.Contains(key.RegionString, "/") {
|
||||
return "", ErrorSlashInRegionString(key.RegionString)
|
||||
}
|
||||
e := fmt.Sprintf("/calico/felix/v2/%s/host/%s/status", key.RegionString, key.Hostname)
|
||||
return e, nil
|
||||
}
|
||||
|
||||
func (key ActiveStatusReportKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (key ActiveStatusReportKey) valueType() (reflect.Type, error) {
|
||||
return typeStatusReport, nil
|
||||
}
|
||||
|
||||
func (key ActiveStatusReportKey) String() string {
|
||||
return fmt.Sprintf("StatusReport(hostname=%s)", key.Hostname)
|
||||
}
|
||||
|
||||
type ActiveStatusReportListOptions struct {
|
||||
Hostname string
|
||||
RegionString string
|
||||
}
|
||||
|
||||
func (options ActiveStatusReportListOptions) defaultPathRoot() string {
|
||||
k := "/calico/felix/v2/"
|
||||
if options.RegionString == "" {
|
||||
return k
|
||||
}
|
||||
k = k + options.RegionString + "/host"
|
||||
if options.Hostname == "" {
|
||||
return k
|
||||
}
|
||||
k = k + fmt.Sprintf("/%s/status", options.Hostname)
|
||||
return k
|
||||
}
|
||||
|
||||
func (options ActiveStatusReportListOptions) KeyFromDefaultPath(ekey string) Key {
|
||||
log.Debugf("Get StatusReport key from %s", ekey)
|
||||
r := matchActiveStatusReport.FindAllStringSubmatch(ekey, -1)
|
||||
if len(r) != 1 {
|
||||
log.Debugf("Didn't match regex")
|
||||
return nil
|
||||
}
|
||||
regionString := r[0][1]
|
||||
name := r[0][2]
|
||||
if options.RegionString != "" && regionString != options.RegionString {
|
||||
log.Debugf("Didn't match region %s != %s", options.RegionString, regionString)
|
||||
return nil
|
||||
}
|
||||
if options.Hostname != "" && name != options.Hostname {
|
||||
log.Debugf("Didn't match name %s != %s", options.Hostname, name)
|
||||
return nil
|
||||
}
|
||||
return ActiveStatusReportKey{Hostname: name, RegionString: regionString}
|
||||
}
|
||||
|
||||
type LastStatusReportKey struct {
|
||||
Hostname string `json:"-" validate:"required,hostname"`
|
||||
RegionString string
|
||||
}
|
||||
|
||||
func (key LastStatusReportKey) defaultPath() (string, error) {
|
||||
return key.defaultDeletePath()
|
||||
}
|
||||
|
||||
func (key LastStatusReportKey) defaultDeletePath() (string, error) {
|
||||
if key.Hostname == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "hostname"}
|
||||
}
|
||||
if key.RegionString == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "regionString"}
|
||||
}
|
||||
if strings.Contains(key.RegionString, "/") {
|
||||
return "", ErrorSlashInRegionString(key.RegionString)
|
||||
}
|
||||
e := fmt.Sprintf("/calico/felix/v2/%s/host/%s/last_reported_status", key.RegionString, key.Hostname)
|
||||
return e, nil
|
||||
}
|
||||
|
||||
func (key LastStatusReportKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (key LastStatusReportKey) valueType() (reflect.Type, error) {
|
||||
return typeStatusReport, nil
|
||||
}
|
||||
|
||||
func (key LastStatusReportKey) String() string {
|
||||
return fmt.Sprintf("StatusReport(hostname=%s)", key.Hostname)
|
||||
}
|
||||
|
||||
type LastStatusReportListOptions struct {
|
||||
Hostname string
|
||||
RegionString string
|
||||
}
|
||||
|
||||
func (options LastStatusReportListOptions) defaultPathRoot() string {
|
||||
k := "/calico/felix/v2/"
|
||||
if options.RegionString == "" {
|
||||
return k
|
||||
}
|
||||
k = k + options.RegionString + "/host"
|
||||
if options.Hostname == "" {
|
||||
return k
|
||||
}
|
||||
k = k + fmt.Sprintf("/%s/last_reported_status", options.Hostname)
|
||||
return k
|
||||
}
|
||||
|
||||
func (options LastStatusReportListOptions) KeyFromDefaultPath(ekey string) Key {
|
||||
log.Debugf("Get StatusReport key from %s", ekey)
|
||||
r := matchLastStatusReport.FindAllStringSubmatch(ekey, -1)
|
||||
if len(r) != 1 {
|
||||
log.Debugf("Didn't match regex")
|
||||
return nil
|
||||
}
|
||||
regionString := r[0][1]
|
||||
name := r[0][2]
|
||||
if options.RegionString != "" && regionString != options.RegionString {
|
||||
log.Debugf("Didn't match region %s != %s", options.RegionString, regionString)
|
||||
return nil
|
||||
}
|
||||
if options.Hostname != "" && name != options.Hostname {
|
||||
log.Debugf("Didn't match name %s != %s", options.Hostname, name)
|
||||
return nil
|
||||
}
|
||||
return LastStatusReportKey{Hostname: name, RegionString: regionString}
|
||||
}
|
||||
|
||||
type StatusReport struct {
|
||||
Timestamp string `json:"time"`
|
||||
UptimeSeconds float64 `json:"uptime"`
|
||||
FirstUpdate bool `json:"first_update"`
|
||||
}
|
||||
185
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/workloadendpoint.go
generated
vendored
Normal file
185
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/workloadendpoint.go
generated
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
// Copyright (c) 2016-2017 Tigera, Inc. All rights reserved.
|
||||
|
||||
// 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 model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"regexp"
|
||||
|
||||
"reflect"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/projectcalico/api/pkg/lib/numorstring"
|
||||
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/errors"
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/net"
|
||||
)
|
||||
|
||||
var (
|
||||
matchWorkloadEndpoint = regexp.MustCompile("^/?calico/v1/host/([^/]+)/workload/([^/]+)/([^/]+)/endpoint/([^/]+)$")
|
||||
)
|
||||
|
||||
type WorkloadEndpointKey struct {
|
||||
Hostname string `json:"-"`
|
||||
OrchestratorID string `json:"-"`
|
||||
WorkloadID string `json:"-"`
|
||||
EndpointID string `json:"-"`
|
||||
}
|
||||
|
||||
func (key WorkloadEndpointKey) defaultPath() (string, error) {
|
||||
if key.Hostname == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "node"}
|
||||
}
|
||||
if key.OrchestratorID == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "orchestrator"}
|
||||
}
|
||||
if key.WorkloadID == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "workload"}
|
||||
}
|
||||
if key.EndpointID == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "name"}
|
||||
}
|
||||
return fmt.Sprintf("/calico/v1/host/%s/workload/%s/%s/endpoint/%s",
|
||||
key.Hostname, escapeName(key.OrchestratorID), escapeName(key.WorkloadID), escapeName(key.EndpointID)), nil
|
||||
}
|
||||
|
||||
func (key WorkloadEndpointKey) defaultDeletePath() (string, error) {
|
||||
return key.defaultPath()
|
||||
}
|
||||
|
||||
func (key WorkloadEndpointKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
if key.Hostname == "" {
|
||||
return nil, errors.ErrorInsufficientIdentifiers{Name: "node"}
|
||||
}
|
||||
if key.OrchestratorID == "" {
|
||||
return nil, errors.ErrorInsufficientIdentifiers{Name: "orchestrator"}
|
||||
}
|
||||
if key.WorkloadID == "" {
|
||||
return nil, errors.ErrorInsufficientIdentifiers{Name: "workload"}
|
||||
}
|
||||
workload := fmt.Sprintf("/calico/v1/host/%s/workload/%s/%s",
|
||||
key.Hostname, escapeName(key.OrchestratorID), escapeName(key.WorkloadID))
|
||||
endpoints := workload + "/endpoint"
|
||||
return []string{endpoints, workload}, nil
|
||||
}
|
||||
|
||||
func (key WorkloadEndpointKey) valueType() (reflect.Type, error) {
|
||||
return reflect.TypeOf(WorkloadEndpoint{}), nil
|
||||
}
|
||||
|
||||
func (key WorkloadEndpointKey) String() string {
|
||||
return fmt.Sprintf("WorkloadEndpoint(node=%s, orchestrator=%s, workload=%s, name=%s)",
|
||||
key.Hostname, key.OrchestratorID, key.WorkloadID, key.EndpointID)
|
||||
}
|
||||
|
||||
type WorkloadEndpointListOptions struct {
|
||||
Hostname string
|
||||
OrchestratorID string
|
||||
WorkloadID string
|
||||
EndpointID string
|
||||
}
|
||||
|
||||
func (options WorkloadEndpointListOptions) defaultPathRoot() string {
|
||||
k := "/calico/v1/host"
|
||||
if options.Hostname == "" {
|
||||
return k
|
||||
}
|
||||
k = k + fmt.Sprintf("/%s/workload", options.Hostname)
|
||||
if options.OrchestratorID == "" {
|
||||
return k
|
||||
}
|
||||
k = k + fmt.Sprintf("/%s", escapeName(options.OrchestratorID))
|
||||
if options.WorkloadID == "" {
|
||||
return k
|
||||
}
|
||||
k = k + fmt.Sprintf("/%s/endpoint", escapeName(options.WorkloadID))
|
||||
if options.EndpointID == "" {
|
||||
return k
|
||||
}
|
||||
k = k + fmt.Sprintf("/%s", escapeName(options.EndpointID))
|
||||
return k
|
||||
}
|
||||
|
||||
func (options WorkloadEndpointListOptions) KeyFromDefaultPath(path string) Key {
|
||||
log.Debugf("Get WorkloadEndpoint key from %s", path)
|
||||
r := matchWorkloadEndpoint.FindAllStringSubmatch(path, -1)
|
||||
if len(r) != 1 {
|
||||
log.Debugf("Didn't match regex")
|
||||
return nil
|
||||
}
|
||||
hostname := r[0][1]
|
||||
orch := unescapeName(r[0][2])
|
||||
workload := unescapeName(r[0][3])
|
||||
endpointID := unescapeName(r[0][4])
|
||||
if options.Hostname != "" && hostname != options.Hostname {
|
||||
log.Debugf("Didn't match hostname %s != %s", options.Hostname, hostname)
|
||||
return nil
|
||||
}
|
||||
if options.OrchestratorID != "" && orch != options.OrchestratorID {
|
||||
log.Debugf("Didn't match orchestrator %s != %s", options.OrchestratorID, orch)
|
||||
return nil
|
||||
}
|
||||
if options.WorkloadID != "" && workload != options.WorkloadID {
|
||||
log.Debugf("Didn't match workload %s != %s", options.WorkloadID, workload)
|
||||
return nil
|
||||
}
|
||||
if options.EndpointID != "" && endpointID != options.EndpointID {
|
||||
log.Debugf("Didn't match endpoint ID %s != %s", options.EndpointID, endpointID)
|
||||
return nil
|
||||
}
|
||||
return WorkloadEndpointKey{
|
||||
Hostname: hostname,
|
||||
OrchestratorID: orch,
|
||||
WorkloadID: workload,
|
||||
EndpointID: endpointID,
|
||||
}
|
||||
}
|
||||
|
||||
type WorkloadEndpoint struct {
|
||||
State string `json:"state"`
|
||||
Name string `json:"name"`
|
||||
ActiveInstanceID string `json:"active_instance_id"`
|
||||
Mac *net.MAC `json:"mac"`
|
||||
ProfileIDs []string `json:"profile_ids"`
|
||||
IPv4Nets []net.IPNet `json:"ipv4_nets"`
|
||||
IPv6Nets []net.IPNet `json:"ipv6_nets"`
|
||||
IPv4NAT []IPNAT `json:"ipv4_nat,omitempty"`
|
||||
IPv6NAT []IPNAT `json:"ipv6_nat,omitempty"`
|
||||
Labels map[string]string `json:"labels,omitempty"`
|
||||
IPv4Gateway *net.IP `json:"ipv4_gateway,omitempty" validate:"omitempty,ipv4"`
|
||||
IPv6Gateway *net.IP `json:"ipv6_gateway,omitempty" validate:"omitempty,ipv6"`
|
||||
Ports []EndpointPort `json:"ports,omitempty" validate:"dive"`
|
||||
GenerateName string `json:"generate_name,omitempty"`
|
||||
AllowSpoofedSourcePrefixes []net.IPNet `json:"allow_spoofed_source_ips,omitempty"`
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
}
|
||||
|
||||
type EndpointPort struct {
|
||||
Name string `json:"name" validate:"name"`
|
||||
Protocol numorstring.Protocol `json:"protocol"`
|
||||
Port uint16 `json:"port" validate:"gt=0"`
|
||||
}
|
||||
|
||||
// IPNat contains a single NAT mapping for a WorkloadEndpoint resource.
|
||||
type IPNAT struct {
|
||||
// The internal IP address which must be associated with the owning endpoint via the
|
||||
// configured IPNetworks for the endpoint.
|
||||
IntIP net.IP `json:"int_ip" validate:"ip"`
|
||||
|
||||
// The external IP address.
|
||||
ExtIP net.IP `json:"ext_ip" validate:"ip"`
|
||||
}
|
||||
178
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/workloadendpointstatus.go
generated
vendored
Normal file
178
vendor/github.com/projectcalico/calico/libcalico-go/lib/backend/model/workloadendpointstatus.go
generated
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
// Copyright (c) 2016-2018 Tigera, Inc. All rights reserved.
|
||||
|
||||
// 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 model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"regexp"
|
||||
|
||||
"reflect"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/projectcalico/calico/libcalico-go/lib/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
matchWorkloadEndpointStatus = regexp.MustCompile("^/?calico/felix/v2/([^/]+)/host/([^/]+)/workload/([^/]+)/([^/]+)/endpoint/([^/]+)$")
|
||||
)
|
||||
|
||||
type WorkloadEndpointStatusKey struct {
|
||||
Hostname string `json:"-"`
|
||||
OrchestratorID string `json:"-"`
|
||||
WorkloadID string `json:"-"`
|
||||
EndpointID string `json:"-"`
|
||||
RegionString string
|
||||
}
|
||||
|
||||
func (key WorkloadEndpointStatusKey) defaultPath() (string, error) {
|
||||
if key.Hostname == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "hostname"}
|
||||
}
|
||||
if key.OrchestratorID == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "orchestrator"}
|
||||
}
|
||||
if key.WorkloadID == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "workload"}
|
||||
}
|
||||
if key.EndpointID == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "endpoint"}
|
||||
}
|
||||
if key.RegionString == "" {
|
||||
return "", errors.ErrorInsufficientIdentifiers{Name: "regionString"}
|
||||
}
|
||||
if strings.Contains(key.RegionString, "/") {
|
||||
return "", ErrorSlashInRegionString(key.RegionString)
|
||||
}
|
||||
return fmt.Sprintf("/calico/felix/v2/%s/host/%s/workload/%s/%s/endpoint/%s",
|
||||
key.RegionString,
|
||||
key.Hostname, escapeName(key.OrchestratorID), escapeName(key.WorkloadID), escapeName(key.EndpointID)), nil
|
||||
}
|
||||
|
||||
func (key WorkloadEndpointStatusKey) defaultDeletePath() (string, error) {
|
||||
return key.defaultPath()
|
||||
}
|
||||
|
||||
func (key WorkloadEndpointStatusKey) defaultDeleteParentPaths() ([]string, error) {
|
||||
if key.Hostname == "" {
|
||||
return nil, errors.ErrorInsufficientIdentifiers{Name: "hostname"}
|
||||
}
|
||||
if key.OrchestratorID == "" {
|
||||
return nil, errors.ErrorInsufficientIdentifiers{Name: "orchestrator"}
|
||||
}
|
||||
if key.WorkloadID == "" {
|
||||
return nil, errors.ErrorInsufficientIdentifiers{Name: "workload"}
|
||||
}
|
||||
if key.RegionString == "" {
|
||||
return nil, errors.ErrorInsufficientIdentifiers{Name: "regionString"}
|
||||
}
|
||||
if strings.Contains(key.RegionString, "/") {
|
||||
return nil, ErrorSlashInRegionString(key.RegionString)
|
||||
}
|
||||
workload := fmt.Sprintf("/calico/felix/v2/%s/host/%s/workload/%s/%s",
|
||||
key.RegionString,
|
||||
key.Hostname, escapeName(key.OrchestratorID), escapeName(key.WorkloadID))
|
||||
endpoints := workload + "/endpoint"
|
||||
return []string{endpoints, workload}, nil
|
||||
}
|
||||
|
||||
func (key WorkloadEndpointStatusKey) valueType() (reflect.Type, error) {
|
||||
return reflect.TypeOf(WorkloadEndpointStatus{}), nil
|
||||
}
|
||||
|
||||
func (key WorkloadEndpointStatusKey) String() string {
|
||||
return fmt.Sprintf("WorkloadEndpointStatus(hostname=%s, orchestrator=%s, workload=%s, name=%s)",
|
||||
key.Hostname, key.OrchestratorID, key.WorkloadID, key.EndpointID)
|
||||
}
|
||||
|
||||
type WorkloadEndpointStatusListOptions struct {
|
||||
Hostname string
|
||||
OrchestratorID string
|
||||
WorkloadID string
|
||||
EndpointID string
|
||||
RegionString string
|
||||
}
|
||||
|
||||
func (options WorkloadEndpointStatusListOptions) defaultPathRoot() string {
|
||||
k := "/calico/felix/v2/"
|
||||
if options.RegionString == "" {
|
||||
return k
|
||||
}
|
||||
k = k + options.RegionString + "/host"
|
||||
if options.Hostname == "" {
|
||||
return k
|
||||
}
|
||||
k = k + fmt.Sprintf("/%s/workload", options.Hostname)
|
||||
if options.OrchestratorID == "" {
|
||||
return k
|
||||
}
|
||||
k = k + fmt.Sprintf("/%s", escapeName(options.OrchestratorID))
|
||||
if options.WorkloadID == "" {
|
||||
return k
|
||||
}
|
||||
k = k + fmt.Sprintf("/%s/endpoint", escapeName(options.WorkloadID))
|
||||
if options.EndpointID == "" {
|
||||
return k
|
||||
}
|
||||
k = k + fmt.Sprintf("/%s", escapeName(options.EndpointID))
|
||||
return k
|
||||
}
|
||||
|
||||
func (options WorkloadEndpointStatusListOptions) KeyFromDefaultPath(ekey string) Key {
|
||||
log.Debugf("Get WorkloadEndpoint key from %s", ekey)
|
||||
r := matchWorkloadEndpointStatus.FindAllStringSubmatch(ekey, -1)
|
||||
if len(r) != 1 {
|
||||
log.Debugf("Didn't match regex")
|
||||
return nil
|
||||
}
|
||||
regionString := r[0][1]
|
||||
hostname := r[0][2]
|
||||
orchID := unescapeName(r[0][3])
|
||||
workloadID := unescapeName(r[0][4])
|
||||
endpointID := unescapeName(r[0][5])
|
||||
if options.RegionString != "" && regionString != options.RegionString {
|
||||
log.Debugf("Didn't match region %s != %s", options.RegionString, regionString)
|
||||
return nil
|
||||
}
|
||||
if options.Hostname != "" && hostname != options.Hostname {
|
||||
log.Debugf("Didn't match hostname %s != %s", options.Hostname, hostname)
|
||||
return nil
|
||||
}
|
||||
if options.OrchestratorID != "" && orchID != options.OrchestratorID {
|
||||
log.Debugf("Didn't match orchestrator %s != %s", options.OrchestratorID, orchID)
|
||||
return nil
|
||||
}
|
||||
if options.WorkloadID != "" && workloadID != options.WorkloadID {
|
||||
log.Debugf("Didn't match workload %s != %s", options.WorkloadID, workloadID)
|
||||
return nil
|
||||
}
|
||||
if options.EndpointID != "" && endpointID != options.EndpointID {
|
||||
log.Debugf("Didn't match endpoint ID %s != %s", options.EndpointID, endpointID)
|
||||
return nil
|
||||
}
|
||||
return WorkloadEndpointStatusKey{
|
||||
Hostname: hostname,
|
||||
OrchestratorID: orchID,
|
||||
WorkloadID: workloadID,
|
||||
EndpointID: endpointID,
|
||||
RegionString: regionString,
|
||||
}
|
||||
}
|
||||
|
||||
type WorkloadEndpointStatus struct {
|
||||
Status string `json:"status"`
|
||||
}
|
||||
Reference in New Issue
Block a user