Skip to content

Commit dd7abd1

Browse files
jaer-tsunJaeryn
andauthored
CNS to DNC communication in Managed DNC (#574)
* initial changes for CNS->DNC support * Adding changes for CNS to be compatible with managed DNC (reverse communication channel) * adding NC version validation with respective NMA * return errors for respective NC based on orchestrator context from CNI * add nc version check via NMA * adding logic to SyncNodeStatus and check if NCWaitingForUpdate for CniADD and CnsAttach calls * addressing most of ashvin's comments * adding managed config * fat rebase * addressing some comments * slight optimizations... * adding channel mode instead of managed bool * set err in register node so that we keep looping * addressing ashvin's comments * fix test * removing swift prefix mods for mdnc * addressing tamanoha's comments Co-authored-by: Jaeryn <[email protected]>
1 parent 5b437b1 commit dd7abd1

File tree

16 files changed

+508
-72
lines changed

16 files changed

+508
-72
lines changed

cns/NetworkContainerContract.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@ const (
6161
PendingRelease = "PendingRelease"
6262
)
6363

64+
// ChannelMode :- CNS channel modes
65+
const (
66+
Direct = "Direct"
67+
Managed = "Managed"
68+
CRD = "CRD"
69+
)
70+
6471
// CreateNetworkContainerRequest specifies request to create a network container or network isolation boundary.
6572
type CreateNetworkContainerRequest struct {
6673
Version string
@@ -318,3 +325,9 @@ func (networkContainerRequestPolicy *NetworkContainerRequestPolicies) Validate()
318325
}
319326
return nil
320327
}
328+
329+
// NodeInfoResponse - Struct to hold the node info response.
330+
type NodeInfoResponse struct {
331+
NetworkContainers []CreateNetworkContainerRequest
332+
GetNCVersionURLFmt string
333+
}

cns/common/service.go

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ import (
1313

1414
// Service implements behavior common to all services.
1515
type Service struct {
16-
Name string
17-
Version string
18-
Options map[string]interface{}
19-
ErrChan chan error
20-
Store store.KeyValueStore
16+
Name string
17+
Version string
18+
Options map[string]interface{}
19+
ErrChan chan error
20+
Store store.KeyValueStore
21+
ChannelMode string
2122
}
2223

2324
// ServiceAPI defines base interface.
@@ -30,25 +31,27 @@ type ServiceAPI interface {
3031

3132
// ServiceConfig specifies common configuration.
3233
type ServiceConfig struct {
33-
Name string
34-
Version string
35-
Listener *acn.Listener
36-
ErrChan chan error
37-
Store store.KeyValueStore
34+
Name string
35+
Version string
36+
Listener *acn.Listener
37+
ErrChan chan error
38+
Store store.KeyValueStore
39+
ChannelMode string
3840
}
3941

4042
// NewService creates a new Service object.
41-
func NewService(name, version string, store store.KeyValueStore) (*Service, error) {
43+
func NewService(name, version, channelMode string, store store.KeyValueStore) (*Service, error) {
4244
logger.Debugf("[Azure CNS] Going to create a service object with name: %v. version: %v.", name, version)
4345

4446
svc := &Service{
45-
Name: name,
46-
Version: version,
47-
Options: make(map[string]interface{}),
48-
Store: store,
47+
Name: name,
48+
Version: version,
49+
ChannelMode: channelMode,
50+
Options: make(map[string]interface{}),
51+
Store: store,
4952
}
5053

51-
logger.Debugf("[Azure CNS] Finished creating service object with name: %v. version: %v.", name, version)
54+
logger.Debugf("[Azure CNS] Finished creating service object with name: %v. version: %v. managed: %s", name, version, channelMode)
5255
return svc, nil
5356
}
5457

@@ -65,6 +68,7 @@ func (service *Service) Initialize(config *ServiceConfig) error {
6568
service.ErrChan = config.ErrChan
6669
service.Store = config.Store
6770
service.Version = config.Version
71+
service.ChannelMode = config.ChannelMode
6872

6973
logger.Debugf("[Azure CNS] nitialized service: %+v with config: %+v.", service, config)
7074

cns/configuration/cns_config.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,12 @@
77
"HeartBeatIntervalInMins": 30,
88
"DebugMode": false,
99
"SnapshotIntervalInMins": 60
10-
}
10+
},
11+
"ManagedSettings": {
12+
"PrivateEndpoint": "",
13+
"InfrastructureNetworkID": "",
14+
"NodeID": "",
15+
"NodeSyncIntervalInSeconds": 30
16+
},
17+
"ChannelMode": "Direct"
1118
}

cns/configuration/configuration.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"os"
88
"path/filepath"
99

10+
"github.com/Azure/azure-container-networking/cns"
1011
"github.com/Azure/azure-container-networking/cns/logger"
1112
"github.com/Azure/azure-container-networking/common"
1213
)
@@ -17,6 +18,8 @@ const (
1718

1819
type CNSConfig struct {
1920
TelemetrySettings TelemetrySettings
21+
ManagedSettings ManagedSettings
22+
ChannelMode string
2023
}
2124

2225
type TelemetrySettings struct {
@@ -44,6 +47,13 @@ type TelemetrySettings struct {
4447
SnapshotIntervalInMins int
4548
}
4649

50+
type ManagedSettings struct {
51+
PrivateEndpoint string
52+
InfrastructureNetworkID string
53+
NodeID string
54+
NodeSyncIntervalInSeconds int
55+
}
56+
4757
// This functions reads cns config file and save it in a structure
4858
func ReadConfig() (CNSConfig, error) {
4959
var cnsConfig CNSConfig
@@ -99,7 +109,18 @@ func setTelemetrySettingDefaults(telemetrySettings *TelemetrySettings) {
99109
}
100110
}
101111

112+
// set managed setting defaults
113+
func setManagedSettingDefaults(managedSettings *ManagedSettings) {
114+
if managedSettings.NodeSyncIntervalInSeconds == 0 {
115+
managedSettings.NodeSyncIntervalInSeconds = 30
116+
}
117+
}
118+
102119
// Set Default values of CNS config if not specified
103120
func SetCNSConfigDefaults(config *CNSConfig) {
104121
setTelemetrySettingDefaults(&config.TelemetrySettings)
122+
setManagedSettingDefaults(&config.ManagedSettings)
123+
if config.ChannelMode == "" {
124+
config.ChannelMode = cns.Direct
125+
}
105126
}

cns/dockerclient/dockerclient.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
"github.com/Azure/azure-container-networking/cns/imdsclient"
1313
"github.com/Azure/azure-container-networking/cns/logger"
14+
"github.com/Azure/azure-container-networking/common"
1415
"github.com/Azure/azure-container-networking/platform"
1516
)
1617

@@ -117,7 +118,7 @@ func (dockerClient *DockerClient) CreateNetwork(networkName string, nicInfo *imd
117118

118119
res, err := http.Post(
119120
dockerClient.connectionURL+createNetworkPath,
120-
"application/json; charset=utf-8",
121+
common.JsonContent,
121122
netConfigJSON)
122123

123124
if err != nil {
@@ -160,7 +161,7 @@ func (dockerClient *DockerClient) DeleteNetwork(networkName string) error {
160161
return err
161162
}
162163

163-
req.Header.Set("Content-Type", "application/json; charset=utf-8")
164+
req.Header.Set(common.ContentType, common.JsonContent)
164165
client := &http.Client{}
165166
res, err := client.Do(req)
166167
if err != nil {

cns/nmagentclient/nmagentclient.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,17 @@ import (
99
"github.com/Azure/azure-container-networking/common"
1010
)
1111

12+
const (
13+
WireserverIP = "168.63.129.16"
14+
)
15+
16+
// NMANetworkContainerResponse - NMAgent response.
17+
type NMANetworkContainerResponse struct {
18+
ResponseCode string `json:"httpStatusCode"`
19+
NetworkContainerID string `json:"networkContainerId"`
20+
Version string `json:"version"`
21+
}
22+
1223
// JoinNetwork joins the given network
1324
func JoinNetwork(
1425
networkID string,
@@ -62,3 +73,16 @@ func UnpublishNetworkContainer(
6273

6374
return response, err
6475
}
76+
77+
// GetNetworkContainerVersion :- Retrieves NC version from NMAgent
78+
func GetNetworkContainerVersion(
79+
networkContainerID,
80+
getNetworkContainerVersionURL string) (*http.Response, error) {
81+
logger.Printf("[NMAgentClient] GetNetworkContainerVersion NC: %s", networkContainerID)
82+
83+
response, err := common.GetHttpClient().Get(getNetworkContainerVersionURL)
84+
85+
logger.Printf("[NMAgentClient][Response] GetNetworkContainerVersion NC: %s. Response: %+v. Error: %v",
86+
networkContainerID, response, err)
87+
return response, err
88+
}

cns/restserver/api.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -824,7 +824,7 @@ func (service *HTTPRestService) createOrUpdateNetworkContainer(w http.ResponseWr
824824
err = service.Listener.Encode(w, &reserveResp)
825825

826826
// If the NC was created successfully, log NC snapshot.
827-
if returnCode == 0 {
827+
if returnCode == Success {
828828
logNCSnapshot(req)
829829
}
830830

@@ -972,8 +972,6 @@ func (service *HTTPRestService) getNetworkContainerStatus(w http.ResponseWriter,
972972
containerInfo := service.state.ContainerStatus
973973
if containerInfo != nil {
974974
containerDetails, ok = containerInfo[req.NetworkContainerid]
975-
} else {
976-
ok = false
977975
}
978976

979977
var hostVersion string

cns/restserver/api_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,13 @@ const (
7979
)
8080

8181
func getInterfaceInfo(w http.ResponseWriter, r *http.Request) {
82-
w.Header().Set("Content-Type", "application/xml")
82+
w.Header().Set(acncommon.ContentType, "application/xml")
8383
output, _ := xml.Marshal(hostQueryResponse)
8484
w.Write(output)
8585
}
8686

8787
func nmagentHandler(w http.ResponseWriter, r *http.Request) {
88-
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
88+
w.Header().Set(acncommon.ContentType, acncommon.JsonContent)
8989
w.WriteHeader(http.StatusOK)
9090

9191
if strings.Contains(r.RequestURI, "networkContainers") {
@@ -248,7 +248,7 @@ func TestGetNetworkContainerByOrchestratorContext(t *testing.T) {
248248
setEnv(t)
249249
setOrchestratorType(t, cns.Kubernetes)
250250

251-
err := creatOrUpdateNetworkContainerWithName(t, "ethWebApp", "11.0.0.5", "AzureContainerInstance")
251+
err := creatOrUpdateNetworkContainerWithName(t, "ethWebApp", "11.0.0.5", cns.AzureContainerInstance)
252252
if err != nil {
253253
t.Errorf("creatOrUpdateNetworkContainerWithName failed Err:%+v", err)
254254
t.Fatal(err)
@@ -283,7 +283,7 @@ func TestGetNetworkContainerStatus(t *testing.T) {
283283
setEnv(t)
284284
setOrchestratorType(t, cns.Kubernetes)
285285

286-
err := creatOrUpdateNetworkContainerWithName(t, "ethWebApp", "11.0.0.5", "WebApps")
286+
err := creatOrUpdateNetworkContainerWithName(t, "ethWebApp", "11.0.0.5", cns.AzureContainerInstance)
287287
if err != nil {
288288
t.Errorf("creatOrUpdateWebAppContainerWithName failed Err:%+v", err)
289289
t.Fatal(err)
@@ -597,7 +597,7 @@ func getNetworkContainerStatus(t *testing.T, name string) error {
597597
var resp cns.GetNetworkContainerStatusResponse
598598

599599
getReq := &cns.GetNetworkContainerStatusRequest{
600-
NetworkContainerid: "ethWebApp",
600+
NetworkContainerid: name,
601601
}
602602

603603
json.NewEncoder(&body).Encode(getReq)
@@ -624,7 +624,7 @@ func getInterfaceForContainer(t *testing.T, name string) error {
624624
var resp cns.GetInterfaceForContainerResponse
625625

626626
getReq := &cns.GetInterfaceForContainerRequest{
627-
NetworkContainerID: "ethWebApp",
627+
NetworkContainerID: name,
628628
}
629629

630630
json.NewEncoder(&body).Encode(getReq)

cns/restserver/const.go

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,34 @@ package restserver
55

66
// Container Network Service remote API Contract.
77
const (
8-
Success = 0
9-
UnsupportedNetworkType = 1
10-
InvalidParameter = 2
11-
UnsupportedEnvironment = 3
12-
UnreachableHost = 4
13-
ReservationNotFound = 5
14-
MalformedSubnet = 8
15-
UnreachableDockerDaemon = 9
16-
UnspecifiedNetworkName = 10
17-
NotFound = 14
18-
AddressUnavailable = 15
19-
NetworkContainerNotSpecified = 16
20-
CallToHostFailed = 17
21-
UnknownContainerID = 18
22-
UnsupportedOrchestratorType = 19
23-
DockerContainerNotSpecified = 20
24-
UnsupportedVerb = 21
25-
UnsupportedNetworkContainerType = 22
26-
InvalidRequest = 23
27-
NetworkJoinFailed = 24
28-
NetworkContainerPublishFailed = 25
29-
NetworkContainerUnpublishFailed = 26
30-
InvalidPrimaryIPConfig = 27
31-
PrimaryCANotSame = 28
32-
InconsistentIPConfigState = 29
33-
InvalidSecondaryIPConfig = 30
34-
UnexpectedError = 99
8+
Success = 0
9+
UnsupportedNetworkType = 1
10+
InvalidParameter = 2
11+
UnsupportedEnvironment = 3
12+
UnreachableHost = 4
13+
ReservationNotFound = 5
14+
MalformedSubnet = 8
15+
UnreachableDockerDaemon = 9
16+
UnspecifiedNetworkName = 10
17+
NotFound = 14
18+
AddressUnavailable = 15
19+
NetworkContainerNotSpecified = 16
20+
CallToHostFailed = 17
21+
UnknownContainerID = 18
22+
UnsupportedOrchestratorType = 19
23+
DockerContainerNotSpecified = 20
24+
UnsupportedVerb = 21
25+
UnsupportedNetworkContainerType = 22
26+
InvalidRequest = 23
27+
NetworkJoinFailed = 24
28+
NetworkContainerPublishFailed = 25
29+
NetworkContainerUnpublishFailed = 26
30+
InvalidPrimaryIPConfig = 27
31+
PrimaryCANotSame = 28
32+
InconsistentIPConfigState = 29
33+
InvalidSecondaryIPConfig = 30
34+
NetworkContainerPendingStatePropagation = 31
35+
UnexpectedError = 99
3536
)
3637

3738
const (
@@ -42,4 +43,5 @@ const (
4243
detach = "Detach"
4344
// Rest service state identifier for named lock
4445
stateJoinedNetworks = "JoinedNetworks"
46+
dncApiVersion = "?api-version=2018-03-01"
4547
)

0 commit comments

Comments
 (0)