Skip to content

Commit

Permalink
chore: rename nbcontract to AKSNodeConfig (#5276)
Browse files Browse the repository at this point in the history
  • Loading branch information
Devinwong authored Nov 15, 2024
1 parent c97624f commit 196afeb
Show file tree
Hide file tree
Showing 16 changed files with 132 additions and 145 deletions.
2 changes: 1 addition & 1 deletion aks-node-controller/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ AKS Node Controller relies on two Azure mechanisms to inject the necessary data
Here is an example on how to retrieve node bootstrapping params and pass in the returned `CSE` and `CustomData` to CRP API for creating a VMSS instance.

```go
builder := aksnodeconfigv1.NewNBContractBuilder()
builder := aksnodeconfigv1.NewAKSNodeConfigBuilder()
builder.ApplyConfiguration(aksNodeConfig)
nodeBootstrapping, err = builder.GetNodeBootstrapping()

Expand Down
8 changes: 4 additions & 4 deletions aks-node-controller/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func TestApp_Run(t *testing.T) {
},
{
name: "provision command with valid flag",
args: []string{"aks-node-controller", "provision", "--provision-config=parser/testdata/test_nbc.json"},
args: []string{"aks-node-controller", "provision", "--provision-config=parser/testdata/test_aksnodeconfig.json"},
setupMocks: func(mc *MockCmdRunner) {
mc.RunFunc = func(cmd *exec.Cmd) error {
return nil
Expand All @@ -71,7 +71,7 @@ func TestApp_Run(t *testing.T) {
},
{
name: "provision command with command runner error",
args: []string{"aks-node-controller", "provision", "--provision-config=parser/testdata/test_nbc.json"},
args: []string{"aks-node-controller", "provision", "--provision-config=parser/testdata/test_aksnodeconfig.json"},
setupMocks: func(mc *MockCmdRunner) {
mc.RunFunc = func(cmd *exec.Cmd) error {
return &ExitError{Code: 666}
Expand Down Expand Up @@ -107,7 +107,7 @@ func TestApp_Provision(t *testing.T) {
}{
{
name: "valid provision config",
flags: ProvisionFlags{ProvisionConfig: "parser/testdata/test_nbc.json"},
flags: ProvisionFlags{ProvisionConfig: "parser/testdata/test_aksnodeconfig.json"},
wantErr: false,
},
{
Expand All @@ -117,7 +117,7 @@ func TestApp_Provision(t *testing.T) {
},
{
name: "command runner error",
flags: ProvisionFlags{ProvisionConfig: "parser/testdata/test_nbc.json"},
flags: ProvisionFlags{ProvisionConfig: "parser/testdata/test_aksnodeconfig.json"},
setupMocks: func(mc *MockCmdRunner) {
mc.RunFunc = func(cmd *exec.Cmd) error {
return errors.New("command runner error")
Expand Down
8 changes: 4 additions & 4 deletions aks-node-controller/parser/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,22 +143,22 @@ func getContainerdConfig(aksnodeconfig *aksnodeconfigv1.Configuration) string {
return ""
}

containerdConfig, err := containerdConfigFromNodeBootstrapContract(aksnodeconfig)
containerdConfig, err := containerdConfigFromAKSNodeConfig(aksnodeconfig)
if err != nil {
return fmt.Sprintf("error getting containerd config from node bootstrap variables: %v", err)
}

return base64.StdEncoding.EncodeToString([]byte(containerdConfig))
}

func containerdConfigFromNodeBootstrapContract(aksnodeconfig *aksnodeconfigv1.Configuration) (string, error) {
func containerdConfigFromAKSNodeConfig(aksnodeconfig *aksnodeconfigv1.Configuration) (string, error) {
if aksnodeconfig == nil {
return "", fmt.Errorf("node bootstrap contract is nil")
return "", fmt.Errorf("AKSNodeConfig is nil")
}

var buffer bytes.Buffer
if err := containerdConfigTemplate.Execute(&buffer, aksnodeconfig); err != nil {
return "", fmt.Errorf("error executing containerd config template for NBContract: %w", err)
return "", fmt.Errorf("error executing containerd config template for AKSNodeConfig: %w", err)
}

return buffer.String(), nil
Expand Down
124 changes: 62 additions & 62 deletions aks-node-controller/parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,21 @@ const encodedTestCert = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUgvVENDQmVXZ0F

func TestBuildCSECmd(t *testing.T) {
tests := []struct {
name string
folder string
k8sVersion string
nbcUpdator func(*aksnodeconfigv1.Configuration)
validator func(cmd *exec.Cmd)
name string
folder string
k8sVersion string
aKSNodeConfigUpdator func(*aksnodeconfigv1.Configuration)
validator func(cmd *exec.Cmd)
}{
{
name: "AKSUbuntu2204 containerd with multi-instance GPU",
folder: "AKSUbuntu2204+Containerd+MIG",
k8sVersion: "1.19.13",
nbcUpdator: func(nbc *aksnodeconfigv1.Configuration) {
nbc.GpuConfig.GpuInstanceProfile = "MIG7g"
aKSNodeConfigUpdator: func(aksNodeConfig *aksnodeconfigv1.Configuration) {
aksNodeConfig.GpuConfig.GpuInstanceProfile = "MIG7g"
// Skip GPU driver install
nbc.GpuConfig.EnableNvidia = to.BoolPtr(false)
nbc.VmSize = "Standard_ND96asr_v4"
aksNodeConfig.GpuConfig.EnableNvidia = to.BoolPtr(false)
aksNodeConfig.VmSize = "Standard_ND96asr_v4"
},
validator: func(cmd *exec.Cmd) {
vars := environToMap(cmd.Env)
Expand Down Expand Up @@ -76,8 +76,8 @@ oom_score = 0
name: "AKSUbuntu2204 DisableSSH with enabled ssh",
folder: "AKSUbuntu2204+SSHStatusOn",
k8sVersion: "1.24.2",
nbcUpdator: func(nbc *aksnodeconfigv1.Configuration) {
nbc.EnableSsh = to.BoolPtr(true)
aKSNodeConfigUpdator: func(aksNodeConfig *aksnodeconfigv1.Configuration) {
aksNodeConfig.EnableSsh = to.BoolPtr(true)
},
validator: func(cmd *exec.Cmd) {
vars := environToMap(cmd.Env)
Expand All @@ -88,9 +88,9 @@ oom_score = 0
name: "AKSUbuntu2204 in China",
folder: "AKSUbuntu2204+China",
k8sVersion: "1.24.2",
nbcUpdator: func(nbc *aksnodeconfigv1.Configuration) {
nbc.ClusterConfig.Location = "chinaeast2"
nbc.CustomCloudConfig.CustomCloudEnvName = "AzureChinaCloud"
aKSNodeConfigUpdator: func(aksNodeConfig *aksnodeconfigv1.Configuration) {
aksNodeConfig.ClusterConfig.Location = "chinaeast2"
aksNodeConfig.CustomCloudConfig.CustomCloudEnvName = "AzureChinaCloud"
},
validator: func(cmd *exec.Cmd) {
vars := environToMap(cmd.Env)
Expand All @@ -103,8 +103,8 @@ oom_score = 0
name: "AKSUbuntu2204 with custom cloud",
folder: "AKSUbuntu2204+CustomCloud",
k8sVersion: "1.24.2",
nbcUpdator: func(nbc *aksnodeconfigv1.Configuration) {
nbc.CustomCloudConfig.CustomCloudEnvName = aksnodeconfigv1.AksCustomCloudName
aKSNodeConfigUpdator: func(aksNodeConfig *aksnodeconfigv1.Configuration) {
aksNodeConfig.CustomCloudConfig.CustomCloudEnvName = aksnodeconfigv1.AksCustomCloudName
},
validator: func(cmd *exec.Cmd) {
vars := environToMap(cmd.Env)
Expand All @@ -117,8 +117,8 @@ oom_score = 0
name: "AKSUbuntu2204 with custom osConfig",
folder: "AKSUbuntu2204+CustomOSConfig",
k8sVersion: "1.24.2",
nbcUpdator: func(nbc *aksnodeconfigv1.Configuration) {
nbc.CustomLinuxOsConfig = &aksnodeconfigv1.CustomLinuxOSConfig{
aKSNodeConfigUpdator: func(aksNodeConfig *aksnodeconfigv1.Configuration) {
aksNodeConfig.CustomLinuxOsConfig = &aksnodeconfigv1.CustomLinuxOSConfig{
EnableSwapConfig: true,
SwapFileSize: int32(1500),
TransparentHugepageSupport: "never",
Expand Down Expand Up @@ -150,10 +150,10 @@ oom_score = 0
name: "AzureLinux v2 with kata and DisableUnattendedUpgrades=false",
folder: "AzureLinuxv2+Kata+DisableUnattendedUpgrades=false",
k8sVersion: "1.28.0",
nbcUpdator: func(nbc *aksnodeconfigv1.Configuration) {
nbc.IsKata = true
nbc.EnableUnattendedUpgrade = true
nbc.NeedsCgroupv2 = to.BoolPtr(true)
aKSNodeConfigUpdator: func(aksNodeConfig *aksnodeconfigv1.Configuration) {
aksNodeConfig.IsKata = true
aksNodeConfig.EnableUnattendedUpgrade = true
aksNodeConfig.NeedsCgroupv2 = to.BoolPtr(true)
},
validator: func(cmd *exec.Cmd) {
vars := environToMap(cmd.Env)
Expand All @@ -166,8 +166,8 @@ oom_score = 0
name: "AKSUbuntu1804 with containerd and kubenet cni",
folder: "AKSUbuntu1804+Containerd+Kubenet",
k8sVersion: "1.19.13",
nbcUpdator: func(nbc *aksnodeconfigv1.Configuration) {
nbc.NetworkConfig.NetworkPlugin = aksnodeconfigv1.GetNetworkPluginType(aksnodeconfigv1.NetworkPluginKubenet)
aKSNodeConfigUpdator: func(aksNodeConfig *aksnodeconfigv1.Configuration) {
aksNodeConfig.NetworkConfig.NetworkPlugin = aksnodeconfigv1.GetNetworkPluginType(aksnodeconfigv1.NetworkPluginKubenet)
},
validator: func(cmd *exec.Cmd) {
vars := environToMap(cmd.Env)
Expand All @@ -179,8 +179,8 @@ oom_score = 0
name: "AKSUbuntu1804 with http proxy config",
folder: "AKSUbuntu1804+HTTPProxy",
k8sVersion: "1.18.14",
nbcUpdator: func(nbc *aksnodeconfigv1.Configuration) {
nbc.HttpProxyConfig = &aksnodeconfigv1.HTTPProxyConfig{
aKSNodeConfigUpdator: func(aksNodeConfig *aksnodeconfigv1.Configuration) {
aksNodeConfig.HttpProxyConfig = &aksnodeconfigv1.HTTPProxyConfig{
HttpProxy: "http://myproxy.server.com:8080/",
HttpsProxy: "https://myproxy.server.com:8080/",
NoProxyEntries: []string{
Expand All @@ -200,8 +200,8 @@ oom_score = 0
name: "AKSUbuntu1804 with custom ca trust",
folder: "AKSUbuntu1804+CustomCATrust",
k8sVersion: "1.18.14",
nbcUpdator: func(nbc *aksnodeconfigv1.Configuration) {
nbc.CustomCaCerts = []string{encodedTestCert, encodedTestCert, encodedTestCert}
aKSNodeConfigUpdator: func(aksNodeConfig *aksnodeconfigv1.Configuration) {
aksNodeConfig.CustomCaCerts = []string{encodedTestCert, encodedTestCert, encodedTestCert}
},
validator: func(cmd *exec.Cmd) {
vars := environToMap(cmd.Env)
Expand Down Expand Up @@ -288,8 +288,8 @@ oom_score = 0
}

aksnodeconfigv1.ValidateAndSetLinuxKubeletFlags(kubeletConfig, cs, agentPool)
nBCB := aksnodeconfigv1.NewNBContractBuilder()
nbc := &aksnodeconfigv1.Configuration{
aKSNodeConfigBuilder := aksnodeconfigv1.NewAKSNodeConfigBuilder()
aksNodeConfig := &aksnodeconfigv1.Configuration{
LinuxAdminUsername: "azureuser",
VmSize: "Standard_DS1_v2",
ClusterConfig: &aksnodeconfigv1.ClusterConfig{
Expand Down Expand Up @@ -331,14 +331,14 @@ oom_score = 0
KubeletNodeLabels: aksnodeconfigv1.GetKubeletNodeLabels(agentPool),
},
}
nBCB.ApplyConfiguration(nbc)
nbc = nBCB.GetNodeBootstrapConfig()
aKSNodeConfigBuilder.ApplyConfiguration(aksNodeConfig)
aksNodeConfig = aKSNodeConfigBuilder.GetAKSNodeConfig()

if tt.nbcUpdator != nil {
tt.nbcUpdator(nbc)
if tt.aKSNodeConfigUpdator != nil {
tt.aKSNodeConfigUpdator(aksNodeConfig)
}

cseCMD, err := parser.BuildCSECmd(context.TODO(), nBCB.GetNodeBootstrapConfig())
cseCMD, err := parser.BuildCSECmd(context.TODO(), aKSNodeConfigBuilder.GetAKSNodeConfig())
require.NoError(t, err)

generateTestDataIfRequested(t, tt.folder, cseCMD)
Expand All @@ -350,7 +350,7 @@ oom_score = 0
}
}

func TestNBContractCompatibilityFromJsonToCSECommand(t *testing.T) {
func TestAKSNodeConfigCompatibilityFromJsonToCSECommand(t *testing.T) {
tests := []struct {
name string
folder string
Expand Down Expand Up @@ -404,10 +404,10 @@ func TestNBContractCompatibilityFromJsonToCSECommand(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
nBCB := aksnodeconfigv1.NewNBContractBuilder()
nBCB.ApplyConfiguration(&aksnodeconfigv1.Configuration{})
aKSNodeConfigBuilder := aksnodeconfigv1.NewAKSNodeConfigBuilder()
aKSNodeConfigBuilder.ApplyConfiguration(&aksnodeconfigv1.Configuration{})

cseCMD, err := parser.BuildCSECmd(context.TODO(), nBCB.GetNodeBootstrapConfig())
cseCMD, err := parser.BuildCSECmd(context.TODO(), aKSNodeConfigBuilder.GetAKSNodeConfig())
require.NoError(t, err)

generateTestDataIfRequested(t, tt.folder, cseCMD)
Expand All @@ -432,47 +432,47 @@ func environToMap(env []string) map[string]string {

func TestContractCompatibilityHandledByProtobuf(t *testing.T) {
tests := []struct {
name string
nbcUTFilePath string
validator func(*aksnodeconfigv1.Configuration, *aksnodeconfigv1.Configuration)
name string
aKSNodeConfigUTFilePath string
validator func(*aksnodeconfigv1.Configuration, *aksnodeconfigv1.Configuration)
}{
{
name: "with unexpected new fields in json should be ignored",
nbcUTFilePath: "./testdata/test_nbc_fields_unexpected.json",
validator: func(nbcExpected *aksnodeconfigv1.Configuration, nbcUT *aksnodeconfigv1.Configuration) {
name: "with unexpected new fields in json should be ignored",
aKSNodeConfigUTFilePath: "./testdata/test_aksnodeconfig_fields_unexpected.json",
validator: func(aKSNodeConfigExpected *aksnodeconfigv1.Configuration, aKSNodeConfigUT *aksnodeconfigv1.Configuration) {
// The unexpected fields will natively be ignored when unmarshalling the json to the contract object.
// We use this test to ensure it.
assert.Equal(t, nbcExpected, nbcUT)
assert.Equal(t, aKSNodeConfigExpected, aKSNodeConfigUT)
},
},
{
name: "with missing fields in json should be set with default values",
nbcUTFilePath: "./testdata/test_nbc_fields_missing.json",
validator: func(_ *aksnodeconfigv1.Configuration, nbcUT *aksnodeconfigv1.Configuration) {
name: "with missing fields in json should be set with default values",
aKSNodeConfigUTFilePath: "./testdata/test_aksnodeconfig_fields_missing.json",
validator: func(_ *aksnodeconfigv1.Configuration, aKSNodeConfigUT *aksnodeconfigv1.Configuration) {
// if a string field is unset, it will be set to empty string by protobuf by default
assert.Equal(t, "", nbcUT.GetLinuxAdminUsername())
assert.Equal(t, "", aKSNodeConfigUT.GetLinuxAdminUsername())

// if an optional (explicit presence) bool field is unset, it will be set to nil by protobuf by default.
// Here we don't use the getter because getter is nil safe and will default to false.
assert.Nil(t, nbcUT.IsVhd)
assert.Nil(t, aKSNodeConfigUT.IsVhd)

// if an optional (explicit presence) field is unset, it will be set to nil by protobuf by default.
// Here we don't use the getter because getter is nil safe and will default to false.
assert.Nil(t, nbcUT.ClusterConfig.LoadBalancerConfig.ExcludeMasterFromStandardLoadBalancer)
assert.Nil(t, aKSNodeConfigUT.ClusterConfig.LoadBalancerConfig.ExcludeMasterFromStandardLoadBalancer)

// if an optional enum field is unset, it will be set to 0 (in this case LoadBalancerConfig_UNSPECIFIED) by protobuf by default.
assert.Equal(t, aksnodeconfigv1.LoadBalancerConfig_UNSPECIFIED, nbcUT.ClusterConfig.LoadBalancerConfig.GetLoadBalancerSku())
assert.Equal(t, aksnodeconfigv1.LoadBalancerConfig_UNSPECIFIED, aKSNodeConfigUT.ClusterConfig.LoadBalancerConfig.GetLoadBalancerSku())
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
nbcExpected := getNBCInstance("./testdata/test_nbc.json")
nbcUT := getNBCInstance(tt.nbcUTFilePath)
aKSNodeConfigExpected := getaKSNodeConfigInstance("./testdata/test_aksnodeconfig.json")
aKSNodeConfigUT := getaKSNodeConfigInstance(tt.aKSNodeConfigUTFilePath)

if tt.validator != nil {
tt.validator(nbcExpected, nbcUT)
tt.validator(aKSNodeConfigExpected, aKSNodeConfigUT)
}
})
}
Expand All @@ -487,18 +487,18 @@ func getBase64DecodedValue(data []byte) (string, error) {
return string(decoded), nil
}

func getNBCInstance(jsonFilePath string) *aksnodeconfigv1.Configuration {
nBCB := aksnodeconfigv1.NewNBContractBuilder()
nbc := aksnodeconfigv1.Configuration{}
func getaKSNodeConfigInstance(jsonFilePath string) *aksnodeconfigv1.Configuration {
aKSNodeConfigBuilder := aksnodeconfigv1.NewAKSNodeConfigBuilder()
aksNodeConfig := aksnodeconfigv1.Configuration{}
content, err := os.ReadFile(jsonFilePath)
if err != nil {
log.Fatal(err)
}
if err = json.Unmarshal(content, &nbc); err != nil {
if err = json.Unmarshal(content, &aksNodeConfig); err != nil {
log.Printf("Failed to unmarshal the aksnodeconfigv1 from json: %v", err)
}
nBCB.ApplyConfiguration(&nbc)
return nBCB.GetNodeBootstrapConfig()
aKSNodeConfigBuilder.ApplyConfiguration(&aksNodeConfig)
return aKSNodeConfigBuilder.GetAKSNodeConfig()
}

func generateTestDataIfRequested(t *testing.T, folder string, cmd *exec.Cmd) {
Expand Down
13 changes: 1 addition & 12 deletions aks-node-controller/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,11 @@ import (
"github.com/Azure/agentbaker/pkg/agent/datamodel"
)

//func getFile(t *testing.T, nbc *datamodel.NodeBootstrappingConfiguration, path string, expectedMode fs.FileMode) string {
// t.Helper()
// files, err := customData(nbc)
// require.NoError(t, err)
// require.Contains(t, files, path)
// actual := files[path]
// assert.Equal(t, expectedMode, actual.Mode)
//
// return actual.Content
//}

func Ptr[T any](input T) *T {
return &input
}

func validNBC() *datamodel.NodeBootstrappingConfiguration {
func validAKSNodeConfig() *datamodel.NodeBootstrappingConfiguration {
return &datamodel.NodeBootstrappingConfiguration{
ContainerService: &datamodel.ContainerService{
Properties: &datamodel.Properties{
Expand Down
2 changes: 1 addition & 1 deletion apiserver/getnodebootstrapdata.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const (
defaultTimeout = 30 * time.Second
)

// GetNodeBootstrapConfig endpoint for getting node bootstrapping data.
// GetNodeBootstrapData endpoint for getting node bootstrapping data.
func (api *APIServer) GetNodeBootstrapData(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx, cancel := context.WithTimeout(ctx, defaultTimeout)
Expand Down
2 changes: 1 addition & 1 deletion e2e/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func prepareCluster(ctx context.Context, t *testing.T, cluster *armcontainerserv
SubnetID: subnetID,
NodeBootstrappingConfiguration: nbc,
Maintenance: maintenance,
AKSNodeConfig: nbcToNbcContractV1(nbc), // TODO: replace with base template
AKSNodeConfig: nbcToAKSNodeConfigV1(nbc), // TODO: replace with base template
}, nil
}

Expand Down
2 changes: 1 addition & 1 deletion e2e/node_bootstrapper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func CSEAKSNodeController(t *testing.T, cluster *Cluster) string {
nbc := nbcAny.(*datamodel.NodeBootstrappingConfiguration)
agent.ValidateAndSetLinuxNodeBootstrappingConfiguration(nbc)

configContent := nbcToNbcContractV1(nbc)
configContent := nbcToAKSNodeConfigV1(nbc)

configJSON, err := json.Marshal(configContent)
require.NoError(t, err)
Expand Down
Loading

0 comments on commit 196afeb

Please sign in to comment.