Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 4 additions & 8 deletions cni/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,11 @@ import (
)

type PodNetworkInterfaceInfo struct {
PodName string
PodNamespace string
PodName string
PodNamespace string
PodEndpointId string
ContainerID string
IPAddresses []net.IPNet
}

type CNIState interface {
PrintResult() error
ContainerID string
IPAddresses []net.IPNet
}

type AzureCNIState struct {
Expand Down
25 changes: 14 additions & 11 deletions cni/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,25 @@ import (
)

const (
azureVnetBinName = "./azure-vnet"
azureVnetBinDirectory = "/opt/cni/bin"
azureVnetExecutable = "/opt/cni/bin/azure-vnet"
)

type CNIClient interface {
GetEndpointState() (api.CNIState, error)
type Client interface {
GetEndpointState() (*api.AzureCNIState, error)
}

type AzureCNIClient struct {
var _ (Client) = (*client)(nil)

type client struct {
exec utilexec.Interface
}

func (c *AzureCNIClient) GetEndpointState() (*api.AzureCNIState, error) {
cmd := c.exec.Command(azureVnetBinName)
cmd.SetDir(azureVnetBinDirectory)
func New(exec utilexec.Interface) *client {
return &client{exec: exec}
}

func (c *client) GetEndpointState() (*api.AzureCNIState, error) {
cmd := c.exec.Command(azureVnetExecutable)

envs := os.Environ()
cmdenv := fmt.Sprintf("%s=%s", cni.Cmd, cni.CmdGetEndpointsState)
Expand All @@ -49,9 +53,8 @@ func (c *AzureCNIClient) GetEndpointState() (*api.AzureCNIState, error) {
return state, nil
}

func (c *AzureCNIClient) GetVersion() (*semver.Version, error) {
cmd := c.exec.Command(azureVnetBinName, "-v")
cmd.SetDir(azureVnetBinDirectory)
func (c *client) GetVersion() (*semver.Version, error) {
cmd := c.exec.Command(azureVnetExecutable, "-v")

output, err := cmd.CombinedOutput()
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions cni/client/client_unit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func TestGetState(t *testing.T) {

fakeexec, _ := testutils.GetFakeExecWithScripts(calls)

c := &AzureCNIClient{exec: fakeexec}
c := New(fakeexec)
state, err := c.GetEndpointState()
require.NoError(t, err)

Expand All @@ -39,7 +39,7 @@ func TestGetVersion(t *testing.T) {

fakeexec, _ := testutils.GetFakeExecWithScripts(calls)

c := &AzureCNIClient{exec: fakeexec}
c := New(fakeexec)
version, err := c.GetVersion()
require.NoError(t, err)

Expand Down
18 changes: 10 additions & 8 deletions cni/network/invoker_cns.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,19 @@ func NewCNSInvoker(podName, namespace string) (*CNSIPAMInvoker, error) {

//Add uses the requestipconfig API in cns, and returns ipv4 and a nil ipv6 as CNS doesn't support IPv6 yet
func (invoker *CNSIPAMInvoker) Add(nwCfg *cni.NetworkConfig, args *cniSkel.CmdArgs, hostSubnetPrefix *net.IPNet, options map[string]interface{}) (*cniTypesCurr.Result, *cniTypesCurr.Result, error) {

// Parse Pod arguments.
podInfo := cns.KubernetesPodInfo{PodName: invoker.podName, PodNamespace: invoker.podNamespace}
podInfo := cns.KubernetesPodInfo{
PodName: invoker.podName,
PodNamespace: invoker.podNamespace,
}
orchestratorContext, err := json.Marshal(podInfo)
if err != nil {
return nil, nil, err
}

endpointId := GetEndpointID(args)
ipconfig := cns.IPConfigRequest{
OrchestratorContext: orchestratorContext,
PodInterfaceID: endpointId,
PodInterfaceID: GetEndpointID(args),
InfraContainerID: args.ContainerID,
}

Expand Down Expand Up @@ -177,19 +178,20 @@ func setHostOptions(nwCfg *cni.NetworkConfig, hostSubnetPrefix *net.IPNet, ncSub

// Delete calls into the releaseipconfiguration API in CNS
func (invoker *CNSIPAMInvoker) Delete(address *net.IPNet, nwCfg *cni.NetworkConfig, args *cniSkel.CmdArgs, options map[string]interface{}) error {

// Parse Pod arguments.
podInfo := cns.KubernetesPodInfo{PodName: invoker.podName, PodNamespace: invoker.podNamespace}
podInfo := cns.KubernetesPodInfo{
PodName: invoker.podName,
PodNamespace: invoker.podNamespace,
}

orchestratorContext, err := json.Marshal(podInfo)
if err != nil {
return err
}

endpointId := GetEndpointID(args)
req := cns.IPConfigRequest{
OrchestratorContext: orchestratorContext,
PodInterfaceID: endpointId,
PodInterfaceID: GetEndpointID(args),
InfraContainerID: args.ContainerID,
}

Expand Down
11 changes: 5 additions & 6 deletions cni/network/multitenancy.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,18 +64,17 @@ func getContainerNetworkConfiguration(
return getContainerNetworkConfigurationInternal(nwCfg.CNSUrl, podNamespace, podNameWithoutSuffix, ifName)
}

func getContainerNetworkConfigurationInternal(
address string,
namespace string,
podName string,
ifName string) (*cniTypesCurr.Result, *cns.GetNetworkContainerResponse, net.IPNet, error) {
func getContainerNetworkConfigurationInternal(address string, namespace string, podName string, ifName string) (*cniTypesCurr.Result, *cns.GetNetworkContainerResponse, net.IPNet, error) {
cnsClient, err := cnsclient.GetCnsClient()
if err != nil {
log.Printf("Failed to get CNS client. Error: %v", err)
return nil, nil, net.IPNet{}, err
}

podInfo := cns.KubernetesPodInfo{PodName: podName, PodNamespace: namespace}
podInfo := cns.KubernetesPodInfo{
PodName: podName,
PodNamespace: namespace,
}
orchestratorContext, err := json.Marshal(podInfo)
if err != nil {
log.Printf("Marshalling KubernetesPodInfo failed with %v", err)
Expand Down
15 changes: 9 additions & 6 deletions cni/network/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ func (plugin *netPlugin) Start(config *common.PluginConfig) error {
return nil
}

func (plugin *netPlugin) GetAllEndpointState(networkid string) (api.CNIState, error) {
func (plugin *netPlugin) GetAllEndpointState(networkid string) (*api.AzureCNIState, error) {
st := api.AzureCNIState{
ContainerInterfaces: make(map[string]api.PodNetworkInterfaceInfo),
}
Expand All @@ -168,11 +168,11 @@ func (plugin *netPlugin) GetAllEndpointState(networkid string) (api.CNIState, er
for _, ep := range eps {
id := ep.Id
info := api.PodNetworkInterfaceInfo{
PodName: ep.PODName,
PodNamespace: ep.PODNameSpace,
PodName: ep.PODName,
PodNamespace: ep.PODNameSpace,
PodEndpointId: ep.Id,
ContainerID: ep.ContainerID,
IPAddresses: ep.IPAddresses,
ContainerID: ep.ContainerID,
IPAddresses: ep.IPAddresses,
}

st.ContainerInterfaces[id] = info
Expand Down Expand Up @@ -1097,7 +1097,10 @@ func (plugin *netPlugin) Update(args *cniSkel.CmdArgs) error {
}

// create struct with info for target POD
podInfo := cns.KubernetesPodInfo{PodName: k8sPodName, PodNamespace: k8sNamespace}
podInfo := cns.KubernetesPodInfo{
PodName: k8sPodName,
PodNamespace: k8sNamespace,
}
if orchestratorContext, err = json.Marshal(podInfo); err != nil {
log.Printf("Marshalling KubernetesPodInfo failed with %v", err)
return plugin.Errorf(err.Error())
Expand Down
16 changes: 8 additions & 8 deletions cni/network/network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,17 +113,17 @@ func TestGetAllEndpointState(t *testing.T) {
ContainerInterfaces: map[string]api.PodNetworkInterfaceInfo{
ep1.Id: {
PodEndpointId: ep1.Id,
PodName: ep1.PODName,
PodNamespace: ep1.PODNameSpace,
ContainerID: ep1.ContainerID,
IPAddresses: ep1.IPAddresses,
PodName: ep1.PODName,
PodNamespace: ep1.PODNameSpace,
ContainerID: ep1.ContainerID,
IPAddresses: ep1.IPAddresses,
},
ep2.Id: {
PodEndpointId: ep2.Id,
PodName: ep2.PODName,
PodNamespace: ep2.PODNameSpace,
ContainerID: ep2.ContainerID,
IPAddresses: ep2.IPAddresses,
PodName: ep2.PODName,
PodNamespace: ep2.PODNameSpace,
ContainerID: ep2.ContainerID,
IPAddresses: ep2.IPAddresses,
},
},
}
Expand Down
135 changes: 130 additions & 5 deletions cns/NetworkContainerContract.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,16 +107,141 @@ type ConfigureContainerNetworkingRequest struct {
NetworkContainerid string
}

// KubernetesPodInfo is an OrchestratorContext that holds PodName and PodNamespace.
// PodInfoByIPProvider to be implemented by initializers which provide a map
// of PodInfos by IP.
type PodInfoByIPProvider interface {
PodInfoByIP() map[string]PodInfo
}

var _ PodInfoByIPProvider = (PodInfoByIPProviderFunc)(nil)

// PodInfoByIPProviderFunc functional type which implements PodInfoByIPProvider.
// Allows one-off functional implementations of the PodInfoByIPProvider
// interface when a custom type definition is not necessary.
type PodInfoByIPProviderFunc func() map[string]PodInfo

// PodInfoByIP implements PodInfoByIPProvider on PodInfByIPProviderFunc.
func (f PodInfoByIPProviderFunc) PodInfoByIP() map[string]PodInfo {
return f()
}

var GlobalPodInfoScheme podInfoScheme

// podInfoScheme indicates which schema should be used when generating
// the map key in the Key() function on a podInfo object.
type podInfoScheme int

const (
KubernetesPodInfoScheme podInfoScheme = iota
InterfaceIDPodInfoScheme
)

// PodInfo represents the object that we are providing network for.
type PodInfo interface {
// InfraContainerID the CRI infra container for the pod namespace.
InfraContainerID() string
// InterfaceID a short hash of the infra container and the primary network
// interface of the pod net ns.
InterfaceID() string
// Key is a unique string representation of the PodInfo.
Key() string
// Name is the orchestrator pod name.
Name() string
// Namespace is the orchestrator pod namespace.
Namespace() string
// OrchestratorContext is a JSON KubernetesPodInfo
OrchestratorContext() (json.RawMessage, error)
}

type KubernetesPodInfo struct {
PodName string
PodNamespace string
}

// GetOrchestratorContext will return the orchestratorcontext as a string
// TODO - should use a hashed name or can this be PODUid?
func (podinfo *KubernetesPodInfo) GetOrchestratorContextKey() string {
return podinfo.PodName + ":" + podinfo.PodNamespace
var _ PodInfo = (*podInfo)(nil)

// podInfo implements PodInfo for multiple schemas of Key
type podInfo struct {
KubernetesPodInfo
PodInfraContainerID string
PodInterfaceID string
Version podInfoScheme
}

func (p *podInfo) InfraContainerID() string {
return p.PodInfraContainerID
}

func (p *podInfo) InterfaceID() string {
return p.PodInterfaceID
}

// Key is a unique string representation of the PodInfo.
// If the PodInfo.Version == kubernetes, the Key is composed of the
// orchestrator pod name and namespace. if the Version is interfaceID, key is
// composed of the CNI interfaceID, which is generated from the CRI infra
// container ID and the pod net ns primary interface name.
func (p *podInfo) Key() string {
if p.Version == InterfaceIDPodInfoScheme {
return p.PodInterfaceID
}
return p.PodName + ":" + p.PodNamespace
}

func (p *podInfo) Name() string {
return p.PodName
}

func (p *podInfo) Namespace() string {
return p.PodNamespace
}

func (p *podInfo) OrchestratorContext() (json.RawMessage, error) {
jsonContext, err := json.Marshal(p.KubernetesPodInfo)
if err != nil {
return nil, fmt.Errorf("failed to marshal PodInfo, error: %w", err)
}
return jsonContext, nil
}

// NewPodInfo returns an implementation of PodInfo that returns the passed
// configuration for their namesake functions.
func NewPodInfo(infraContainerID, interfaceID, name, namespace string) PodInfo {
return &podInfo{
KubernetesPodInfo: KubernetesPodInfo{
PodName: name,
PodNamespace: namespace,
},
PodInfraContainerID: infraContainerID,
PodInterfaceID: interfaceID,
Version: GlobalPodInfoScheme,
}
}

// UnmarshalPodInfo wraps json.Unmarshal to return an implementation of
// PodInfo.
func UnmarshalPodInfo(b []byte) (PodInfo, error) {
p := &podInfo{}
if err := json.Unmarshal(b, p); err != nil {
return nil, err
}
p.Version = GlobalPodInfoScheme
return p, nil
}

// NewPodInfoFromIPConfigRequest builds and returns an implementation of
// PodInfo from the provided IPConfigRequest.
func NewPodInfoFromIPConfigRequest(req IPConfigRequest) (PodInfo, error) {
p, err := UnmarshalPodInfo(req.OrchestratorContext)
if err != nil {
return nil, err
}
if GlobalPodInfoScheme == InterfaceIDPodInfoScheme && req.PodInterfaceID == "" {
return nil, fmt.Errorf("need interfaceID for pod info but request was empty")
}
p.(*podInfo).PodInfraContainerID = req.InfraContainerID
p.(*podInfo).PodInterfaceID = req.PodInterfaceID
return p, nil
}

// MultiTenancyInfo contains encap type and id.
Expand Down
Loading