diff --git a/aks-node-controller/parser/parser.go b/aks-node-controller/parser/parser.go index 73c9618bb7f..e23b5917777 100644 --- a/aks-node-controller/parser/parser.go +++ b/aks-node-controller/parser/parser.go @@ -139,6 +139,10 @@ func getCSEEnv(config *aksnodeconfigv1.Configuration) map[string]string { "SECURE_TLS_BOOTSTRAPPING_GET_CREDENTIAL_TIMEOUT": config.GetBootstrappingConfig().GetSecureTlsBootstrappingGetCredentialTimeout(), //nolint:staticcheck // keeping for now for backwards compatibility - will soon be removed "SECURE_TLS_BOOTSTRAPPING_DEADLINE": config.GetBootstrappingConfig().GetSecureTlsBootstrappingDeadline(), + "SECURE_TLS_BOOTSTRAPPING_MAX_ATTEMPTS": config.GetBootstrappingConfig().GetSecureTlsBootstrappingMaxAttempts(), + "SECURE_TLS_BOOTSTRAPPING_MAX_TOTAL_SECONDS": config.GetBootstrappingConfig().GetSecureTlsBootstrappingMaxTotalSeconds(), + "SECURE_TLS_BOOTSTRAPPING_INITIAL_BACKOFF_SECONDS": config.GetBootstrappingConfig().GetSecureTlsBootstrappingInitialBackoffSeconds(), + "SECURE_TLS_BOOTSTRAPPING_MAX_BACKOFF_SECONDS": config.GetBootstrappingConfig().GetSecureTlsBootstrappingMaxBackoffSeconds(), "CUSTOM_SECURE_TLS_BOOTSTRAPPING_CLIENT_DOWNLOAD_URL": config.GetBootstrappingConfig().GetSecureTlsBootstrappingCustomClientDownloadUrl(), "ENABLE_KUBELET_SERVING_CERTIFICATE_ROTATION": fmt.Sprintf("%v", config.GetKubeletConfig().GetKubeletConfigFileConfig().GetServerTlsBootstrap()), "DHCPV6_SERVICE_FILEPATH": getDHCPV6ServiceFilepath(), diff --git a/aks-node-controller/parser/parser_test.go b/aks-node-controller/parser/parser_test.go index d43ece17486..c35d0f9319a 100644 --- a/aks-node-controller/parser/parser_test.go +++ b/aks-node-controller/parser/parser_test.go @@ -475,6 +475,10 @@ func TestAKSNodeConfigCompatibilityFromJsonToCSECommand(t *testing.T) { assertHasKeyWithValue(t, vars, "SECURE_TLS_BOOTSTRAPPING_GET_ATTESTED_DATA_TIMEOUT", "") assertHasKeyWithValue(t, vars, "SECURE_TLS_BOOTSTRAPPING_GET_CREDENTIAL_TIMEOUT", "") assertHasKeyWithValue(t, vars, "SECURE_TLS_BOOTSTRAPPING_DEADLINE", "") + assertHasKeyWithValue(t, vars, "SECURE_TLS_BOOTSTRAPPING_MAX_ATTEMPTS", "") + assertHasKeyWithValue(t, vars, "SECURE_TLS_BOOTSTRAPPING_MAX_TOTAL_SECONDS", "") + assertHasKeyWithValue(t, vars, "SECURE_TLS_BOOTSTRAPPING_INITIAL_BACKOFF_SECONDS", "") + assertHasKeyWithValue(t, vars, "SECURE_TLS_BOOTSTRAPPING_MAX_BACKOFF_SECONDS", "") }, }, } diff --git a/aks-node-controller/pkg/gen/aksnodeconfig/v1/bootstrapping_config.pb.go b/aks-node-controller/pkg/gen/aksnodeconfig/v1/bootstrapping_config.pb.go index 92fee881294..888f3acefc9 100644 --- a/aks-node-controller/pkg/gen/aksnodeconfig/v1/bootstrapping_config.pb.go +++ b/aks-node-controller/pkg/gen/aksnodeconfig/v1/bootstrapping_config.pb.go @@ -179,6 +179,22 @@ type BootstrappingConfig struct { // Only used when secure TLS bootstrapping is enabled. Optional override passed to the secure TLS bootstrap client during provisioning. // This is the amount of time given to the bootstrap client to retrieve a credential from the bootstrap server. SecureTlsBootstrappingGetCredentialTimeout *string `protobuf:"bytes,15,opt,name=secure_tls_bootstrapping_get_credential_timeout,json=secureTlsBootstrappingGetCredentialTimeout,proto3,oneof" json:"secure_tls_bootstrapping_get_credential_timeout,omitempty"` + // Only used when secure TLS bootstrapping is enabled. Optional override consumed by the on-VM + // wrapper that bounds per-VM retry attempts. Caps the number of times the secure TLS bootstrap + // client may be re-invoked by systemd within a single provisioning session before the wrapper + // gives up and emits a terminal RetryCapReached event. See AB#38327355. + SecureTlsBootstrappingMaxAttempts *string `protobuf:"bytes,16,opt,name=secure_tls_bootstrapping_max_attempts,json=secureTlsBootstrappingMaxAttempts,proto3,oneof" json:"secure_tls_bootstrapping_max_attempts,omitempty"` + // Only used when secure TLS bootstrapping is enabled. Optional override consumed by the on-VM + // wrapper. Caps the total wall-clock time (in seconds) the wrapper will keep re-attempting + // within a single provisioning session before giving up. + SecureTlsBootstrappingMaxTotalSeconds *string `protobuf:"bytes,17,opt,name=secure_tls_bootstrapping_max_total_seconds,json=secureTlsBootstrappingMaxTotalSeconds,proto3,oneof" json:"secure_tls_bootstrapping_max_total_seconds,omitempty"` + // Only used when secure TLS bootstrapping is enabled. Optional override consumed by the on-VM + // wrapper. Initial backoff (in seconds) between consecutive attempts; doubled on each attempt + // up to secure_tls_bootstrapping_max_backoff_seconds. + SecureTlsBootstrappingInitialBackoffSeconds *string `protobuf:"bytes,18,opt,name=secure_tls_bootstrapping_initial_backoff_seconds,json=secureTlsBootstrappingInitialBackoffSeconds,proto3,oneof" json:"secure_tls_bootstrapping_initial_backoff_seconds,omitempty"` + // Only used when secure TLS bootstrapping is enabled. Optional override consumed by the on-VM + // wrapper. Caps the exponential backoff delay (in seconds) between consecutive attempts. + SecureTlsBootstrappingMaxBackoffSeconds *string `protobuf:"bytes,19,opt,name=secure_tls_bootstrapping_max_backoff_seconds,json=secureTlsBootstrappingMaxBackoffSeconds,proto3,oneof" json:"secure_tls_bootstrapping_max_backoff_seconds,omitempty"` } func (x *BootstrappingConfig) Reset() { @@ -303,6 +319,34 @@ func (x *BootstrappingConfig) GetSecureTlsBootstrappingGetCredentialTimeout() st return "" } +func (x *BootstrappingConfig) GetSecureTlsBootstrappingMaxAttempts() string { + if x != nil && x.SecureTlsBootstrappingMaxAttempts != nil { + return *x.SecureTlsBootstrappingMaxAttempts + } + return "" +} + +func (x *BootstrappingConfig) GetSecureTlsBootstrappingMaxTotalSeconds() string { + if x != nil && x.SecureTlsBootstrappingMaxTotalSeconds != nil { + return *x.SecureTlsBootstrappingMaxTotalSeconds + } + return "" +} + +func (x *BootstrappingConfig) GetSecureTlsBootstrappingInitialBackoffSeconds() string { + if x != nil && x.SecureTlsBootstrappingInitialBackoffSeconds != nil { + return *x.SecureTlsBootstrappingInitialBackoffSeconds + } + return "" +} + +func (x *BootstrappingConfig) GetSecureTlsBootstrappingMaxBackoffSeconds() string { + if x != nil && x.SecureTlsBootstrappingMaxBackoffSeconds != nil { + return *x.SecureTlsBootstrappingMaxBackoffSeconds + } + return "" +} + var File_aksnodeconfig_v1_bootstrapping_config_proto protoreflect.FileDescriptor var file_aksnodeconfig_v1_bootstrapping_config_proto_rawDesc = []byte{ @@ -310,7 +354,7 @@ var file_aksnodeconfig_v1_bootstrapping_config_proto_rawDesc = []byte{ 0x76, 0x31, 0x2f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x10, 0x61, 0x6b, 0x73, 0x6e, 0x6f, 0x64, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x22, - 0xf4, 0x0e, 0x0a, 0x13, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, + 0xba, 0x13, 0x0a, 0x13, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x65, 0x0a, 0x19, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x61, 0x6b, 0x73, @@ -392,75 +436,111 @@ var file_aksnodeconfig_v1_bootstrapping_config_proto_rawDesc = []byte{ 0x01, 0x28, 0x09, 0x48, 0x0a, 0x52, 0x2a, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x6c, 0x73, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x47, 0x65, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, - 0x74, 0x88, 0x01, 0x01, 0x42, 0x1a, 0x0a, 0x18, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x62, 0x6f, 0x6f, - 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x42, 0x28, 0x0a, 0x26, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x5f, 0x74, 0x6c, 0x73, 0x5f, - 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x61, - 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x35, 0x0a, 0x33, 0x5f, 0x73, + 0x74, 0x88, 0x01, 0x01, 0x12, 0x55, 0x0a, 0x25, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x5f, 0x74, + 0x6c, 0x73, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, + 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x73, 0x18, 0x10, 0x20, + 0x01, 0x28, 0x09, 0x48, 0x0b, 0x52, 0x21, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x6c, 0x73, + 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x78, + 0x41, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x73, 0x88, 0x01, 0x01, 0x12, 0x5e, 0x0a, 0x2a, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, - 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x73, 0x73, - 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, - 0x64, 0x42, 0x36, 0x0a, 0x34, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x5f, 0x74, 0x6c, 0x73, - 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x63, - 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x64, 0x6f, 0x77, - 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x75, 0x72, 0x6c, 0x42, 0x24, 0x0a, 0x22, 0x5f, 0x73, 0x65, - 0x63, 0x75, 0x72, 0x65, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, - 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x42, - 0x37, 0x0a, 0x35, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x62, - 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x42, 0x34, 0x0a, 0x32, 0x5f, 0x73, 0x65, 0x63, + 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x74, 0x6f, 0x74, 0x61, + 0x6c, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x48, + 0x0c, 0x52, 0x25, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x6c, 0x73, 0x42, 0x6f, 0x6f, 0x74, + 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x78, 0x54, 0x6f, 0x74, 0x61, + 0x6c, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x88, 0x01, 0x01, 0x12, 0x6a, 0x0a, 0x30, 0x73, + 0x65, 0x63, 0x75, 0x72, 0x65, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, + 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x5f, + 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, + 0x12, 0x20, 0x01, 0x28, 0x09, 0x48, 0x0d, 0x52, 0x2b, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, + 0x6c, 0x73, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x49, + 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x53, 0x65, 0x63, + 0x6f, 0x6e, 0x64, 0x73, 0x88, 0x01, 0x01, 0x12, 0x62, 0x0a, 0x2c, 0x73, 0x65, 0x63, 0x75, 0x72, + 0x65, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, + 0x69, 0x6e, 0x67, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x5f, + 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x48, 0x0e, 0x52, + 0x27, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x6c, 0x73, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, + 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x78, 0x42, 0x61, 0x63, 0x6b, 0x6f, 0x66, + 0x66, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x88, 0x01, 0x01, 0x42, 0x1a, 0x0a, 0x18, 0x5f, + 0x74, 0x6c, 0x73, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, + 0x67, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x42, 0x28, 0x0a, 0x26, 0x5f, 0x73, 0x65, 0x63, 0x75, + 0x72, 0x65, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, + 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x61, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x42, 0x35, 0x0a, 0x33, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x5f, 0x74, 0x6c, 0x73, + 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x75, + 0x73, 0x65, 0x72, 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x42, 0x36, 0x0a, 0x34, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, - 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x42, 0x35, - 0x0a, 0x33, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x62, 0x6f, - 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x67, 0x65, 0x74, 0x5f, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x42, 0x2d, 0x0a, 0x2b, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, + 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x75, 0x72, 0x6c, + 0x42, 0x24, 0x0a, 0x22, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x5f, 0x74, 0x6c, 0x73, 0x5f, + 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x65, + 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x42, 0x37, 0x0a, 0x35, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, + 0x65, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, + 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x75, 0x62, + 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x42, + 0x34, 0x0a, 0x32, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x62, + 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x67, 0x65, 0x74, + 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x42, 0x35, 0x0a, 0x33, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, - 0x6e, 0x67, 0x5f, 0x67, 0x65, 0x74, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x5f, 0x74, 0x69, 0x6d, - 0x65, 0x6f, 0x75, 0x74, 0x42, 0x35, 0x0a, 0x33, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x5f, - 0x74, 0x6c, 0x73, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, - 0x67, 0x5f, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x64, - 0x61, 0x74, 0x61, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x42, 0x32, 0x0a, 0x30, 0x5f, + 0x6e, 0x67, 0x5f, 0x67, 0x65, 0x74, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, + 0x64, 0x61, 0x74, 0x61, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x42, 0x2d, 0x0a, 0x2b, + 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x62, 0x6f, 0x6f, 0x74, + 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x67, 0x65, 0x74, 0x5f, 0x6e, 0x6f, + 0x6e, 0x63, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x42, 0x35, 0x0a, 0x33, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x73, - 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x67, 0x65, 0x74, 0x5f, 0x63, 0x72, 0x65, - 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4a, - 0x04, 0x08, 0x04, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x52, 0x13, 0x63, 0x75, 0x73, - 0x74, 0x6f, 0x6d, 0x5f, 0x61, 0x61, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x52, 0x14, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x61, 0x61, 0x64, 0x5f, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x2a, 0xfb, 0x01, 0x0a, 0x17, 0x42, 0x6f, 0x6f, 0x74, 0x73, - 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x41, 0x75, 0x74, 0x68, 0x4d, 0x65, 0x74, 0x68, - 0x6f, 0x64, 0x12, 0x29, 0x0a, 0x25, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, 0x50, + 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x74, 0x74, + 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, + 0x75, 0x74, 0x42, 0x32, 0x0a, 0x30, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x5f, 0x74, 0x6c, + 0x73, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, + 0x67, 0x65, 0x74, 0x5f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x42, 0x28, 0x0a, 0x26, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, + 0x65, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, + 0x69, 0x6e, 0x67, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x73, + 0x42, 0x2d, 0x0a, 0x2b, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x5f, 0x74, 0x6c, 0x73, 0x5f, + 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x6d, 0x61, + 0x78, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x42, + 0x33, 0x0a, 0x31, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x62, + 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x6e, 0x69, + 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x5f, 0x73, 0x65, 0x63, + 0x6f, 0x6e, 0x64, 0x73, 0x42, 0x2f, 0x0a, 0x2d, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x5f, + 0x74, 0x6c, 0x73, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, + 0x67, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x5f, 0x73, 0x65, + 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x05, 0x10, + 0x06, 0x52, 0x13, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x61, 0x61, 0x64, 0x5f, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x14, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x61, + 0x61, 0x64, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x2a, 0xfb, 0x01, 0x0a, + 0x17, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x41, 0x75, + 0x74, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x29, 0x0a, 0x25, 0x42, 0x4f, 0x4f, 0x54, + 0x53, 0x54, 0x52, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x5f, 0x4d, + 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x10, 0x00, 0x12, 0x2d, 0x0a, 0x29, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, + 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, + 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, 0x5f, 0x54, 0x4f, 0x4b, 0x45, 0x4e, + 0x10, 0x01, 0x12, 0x36, 0x0a, 0x32, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, - 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x2d, 0x0a, - 0x29, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x41, - 0x55, 0x54, 0x48, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, - 0x54, 0x52, 0x41, 0x50, 0x5f, 0x54, 0x4f, 0x4b, 0x45, 0x4e, 0x10, 0x01, 0x12, 0x36, 0x0a, 0x32, - 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x41, 0x55, - 0x54, 0x48, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x53, 0x45, 0x43, 0x55, 0x52, 0x45, - 0x5f, 0x54, 0x4c, 0x53, 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, 0x50, 0x49, - 0x4e, 0x47, 0x10, 0x02, 0x12, 0x25, 0x0a, 0x21, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, - 0x50, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, - 0x44, 0x5f, 0x41, 0x52, 0x43, 0x5f, 0x4d, 0x53, 0x49, 0x10, 0x03, 0x12, 0x27, 0x0a, 0x23, 0x42, - 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x41, 0x55, 0x54, - 0x48, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x41, 0x5a, 0x55, 0x52, 0x45, 0x5f, 0x4d, - 0x53, 0x49, 0x10, 0x04, 0x2a, 0x8e, 0x01, 0x0a, 0x11, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x4a, 0x6f, 0x69, 0x6e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x23, 0x0a, 0x1f, 0x43, 0x4c, - 0x55, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, - 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, - 0x24, 0x0a, 0x20, 0x43, 0x4c, 0x55, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, - 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x45, 0x5f, - 0x43, 0x53, 0x52, 0x10, 0x01, 0x12, 0x2e, 0x0a, 0x2a, 0x43, 0x4c, 0x55, 0x53, 0x54, 0x45, 0x52, - 0x5f, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x55, 0x53, 0x45, - 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x41, - 0x55, 0x54, 0x48, 0x10, 0x02, 0x42, 0x5a, 0x5a, 0x58, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x62, - 0x61, 0x6b, 0x65, 0x72, 0x2f, 0x61, 0x6b, 0x73, 0x2d, 0x6e, 0x6f, 0x64, 0x65, 0x2d, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x67, 0x65, 0x6e, - 0x2f, 0x61, 0x6b, 0x73, 0x6e, 0x6f, 0x64, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, - 0x31, 0x3b, 0x61, 0x6b, 0x73, 0x6e, 0x6f, 0x64, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x76, - 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x53, 0x45, 0x43, 0x55, 0x52, 0x45, 0x5f, 0x54, 0x4c, 0x53, 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, + 0x54, 0x52, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x25, 0x0a, 0x21, 0x42, 0x4f, + 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x41, 0x55, 0x54, 0x48, + 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x41, 0x52, 0x43, 0x5f, 0x4d, 0x53, 0x49, 0x10, + 0x03, 0x12, 0x27, 0x0a, 0x23, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, 0x50, 0x49, + 0x4e, 0x47, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x41, + 0x5a, 0x55, 0x52, 0x45, 0x5f, 0x4d, 0x53, 0x49, 0x10, 0x04, 0x2a, 0x8e, 0x01, 0x0a, 0x11, 0x43, + 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4a, 0x6f, 0x69, 0x6e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x12, 0x23, 0x0a, 0x1f, 0x43, 0x4c, 0x55, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4a, 0x4f, 0x49, 0x4e, + 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, + 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x24, 0x0a, 0x20, 0x43, 0x4c, 0x55, 0x53, 0x54, 0x45, 0x52, + 0x5f, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x47, 0x45, 0x4e, + 0x45, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x43, 0x53, 0x52, 0x10, 0x01, 0x12, 0x2e, 0x0a, 0x2a, 0x43, + 0x4c, 0x55, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x54, 0x48, + 0x4f, 0x44, 0x5f, 0x55, 0x53, 0x45, 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, + 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x10, 0x02, 0x42, 0x5a, 0x5a, 0x58, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x2f, + 0x61, 0x67, 0x65, 0x6e, 0x74, 0x62, 0x61, 0x6b, 0x65, 0x72, 0x2f, 0x61, 0x6b, 0x73, 0x2d, 0x6e, + 0x6f, 0x64, 0x65, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x70, + 0x6b, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x6b, 0x73, 0x6e, 0x6f, 0x64, 0x65, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x6b, 0x73, 0x6e, 0x6f, 0x64, 0x65, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/aks-node-controller/proto/aksnodeconfig/v1/bootstrapping_config.proto b/aks-node-controller/proto/aksnodeconfig/v1/bootstrapping_config.proto index 66626a8fb3f..e1876bf7690 100644 --- a/aks-node-controller/proto/aksnodeconfig/v1/bootstrapping_config.proto +++ b/aks-node-controller/proto/aksnodeconfig/v1/bootstrapping_config.proto @@ -83,4 +83,24 @@ message BootstrappingConfig { // Only used when secure TLS bootstrapping is enabled. Optional override passed to the secure TLS bootstrap client during provisioning. // This is the amount of time given to the bootstrap client to retrieve a credential from the bootstrap server. optional string secure_tls_bootstrapping_get_credential_timeout = 15; + + // Only used when secure TLS bootstrapping is enabled. Optional override consumed by the on-VM + // wrapper that bounds per-VM retry attempts. Caps the number of times the secure TLS bootstrap + // client may be re-invoked by systemd within a single provisioning session before the wrapper + // gives up and emits a terminal RetryCapReached event. See AB#38327355. + optional string secure_tls_bootstrapping_max_attempts = 16; + + // Only used when secure TLS bootstrapping is enabled. Optional override consumed by the on-VM + // wrapper. Caps the total wall-clock time (in seconds) the wrapper will keep re-attempting + // within a single provisioning session before giving up. + optional string secure_tls_bootstrapping_max_total_seconds = 17; + + // Only used when secure TLS bootstrapping is enabled. Optional override consumed by the on-VM + // wrapper. Initial backoff (in seconds) between consecutive attempts; doubled on each attempt + // up to secure_tls_bootstrapping_max_backoff_seconds. + optional string secure_tls_bootstrapping_initial_backoff_seconds = 18; + + // Only used when secure TLS bootstrapping is enabled. Optional override consumed by the on-VM + // wrapper. Caps the exponential backoff delay (in seconds) between consecutive attempts. + optional string secure_tls_bootstrapping_max_backoff_seconds = 19; } diff --git a/parts/linux/cloud-init/artifacts/cse_cmd.sh b/parts/linux/cloud-init/artifacts/cse_cmd.sh index d184b6e5356..0b930af31e3 100644 --- a/parts/linux/cloud-init/artifacts/cse_cmd.sh +++ b/parts/linux/cloud-init/artifacts/cse_cmd.sh @@ -140,6 +140,10 @@ SECURE_TLS_BOOTSTRAPPING_GET_NONCE_TIMEOUT="{{GetSecureTLSBootstrappingGetNonceT SECURE_TLS_BOOTSTRAPPING_GET_ATTESTED_DATA_TIMEOUT="{{GetSecureTLSBootstrappingGetAttestedDataTimeout}}" SECURE_TLS_BOOTSTRAPPING_GET_CREDENTIAL_TIMEOUT="{{GetSecureTLSBootstrappingGetCredentialTimeout}}" SECURE_TLS_BOOTSTRAPPING_DEADLINE="{{GetSecureTLSBootstrappingDeadline}}" +SECURE_TLS_BOOTSTRAPPING_MAX_ATTEMPTS="{{GetSecureTLSBootstrappingMaxAttempts}}" +SECURE_TLS_BOOTSTRAPPING_MAX_TOTAL_SECONDS="{{GetSecureTLSBootstrappingMaxTotalSeconds}}" +SECURE_TLS_BOOTSTRAPPING_INITIAL_BACKOFF_SECONDS="{{GetSecureTLSBootstrappingInitialBackoffSeconds}}" +SECURE_TLS_BOOTSTRAPPING_MAX_BACKOFF_SECONDS="{{GetSecureTLSBootstrappingMaxBackoffSeconds}}" CUSTOM_SECURE_TLS_BOOTSTRAPPING_CLIENT_DOWNLOAD_URL="{{GetCustomSecureTLSBootstrappingClientDownloadURL}}" ENABLE_KUBELET_SERVING_CERTIFICATE_ROTATION="{{EnableKubeletServingCertificateRotation}}" DHCPV6_SERVICE_FILEPATH="{{GetDHCPv6ServiceCSEScriptFilepath}}" diff --git a/parts/linux/cloud-init/artifacts/cse_config.sh b/parts/linux/cloud-init/artifacts/cse_config.sh index 136da897279..e927031fc5d 100755 --- a/parts/linux/cloud-init/artifacts/cse_config.sh +++ b/parts/linux/cloud-init/artifacts/cse_config.sh @@ -521,7 +521,13 @@ ensureKubeCACert() { # file paths defined outside so configureAndStartSecureTLSBootstrapping can be unit tested SECURE_TLS_BOOTSTRAPPING_DEFAULT_FILE="/etc/default/secure-tls-bootstrap" SECURE_TLS_BOOTSTRAPPING_DROP_IN="/etc/systemd/system/secure-tls-bootstrap.service.d/10-securetlsbootstrap.conf" +SECURE_TLS_BOOTSTRAPPING_STATE_DIR="/var/lib/aks-secure-tls-bootstrap" configureAndStartSecureTLSBootstrapping() { + # Reset retry-cap state at the start of every provisioning session so the + # wrapper (secure-tls-bootstrap-retry-cap.sh) counts from zero on fresh + # bootstraps. See AB#38327355. + rm -rf "${SECURE_TLS_BOOTSTRAPPING_STATE_DIR}" + BOOTSTRAP_CLIENT_FLAGS="--aad-resource=${SECURE_TLS_BOOTSTRAPPING_AAD_RESOURCE:-$AKS_AAD_SERVER_APP_ID} --apiserver-fqdn=${API_SERVER_NAME} --cloud-provider-config=${AZURE_JSON_PATH}" if [ -n "${SECURE_TLS_BOOTSTRAPPING_USER_ASSIGNED_IDENTITY_ID}" ]; then BOOTSTRAP_CLIENT_FLAGS="${BOOTSTRAP_CLIENT_FLAGS} --user-assigned-identity-id=$SECURE_TLS_BOOTSTRAPPING_USER_ASSIGNED_IDENTITY_ID" @@ -555,6 +561,21 @@ configureAndStartSecureTLSBootstrapping() { if [ -n "${AZURE_ENVIRONMENT_FILEPATH}" ]; then echo "AZURE_ENVIRONMENT_FILEPATH=${AZURE_ENVIRONMENT_FILEPATH}" >> "${SECURE_TLS_BOOTSTRAPPING_DEFAULT_FILE}" fi + # Retry-cap knobs consumed by secure-tls-bootstrap-retry-cap.sh. If unset, + # the wrapper falls back to its built-in defaults + # (50 attempts / 7200s budget / 1s initial backoff / 300s max backoff). + if [ -n "${SECURE_TLS_BOOTSTRAPPING_MAX_ATTEMPTS}" ]; then + echo "SECURE_TLS_BOOTSTRAPPING_MAX_ATTEMPTS=${SECURE_TLS_BOOTSTRAPPING_MAX_ATTEMPTS}" >> "${SECURE_TLS_BOOTSTRAPPING_DEFAULT_FILE}" + fi + if [ -n "${SECURE_TLS_BOOTSTRAPPING_MAX_TOTAL_SECONDS}" ]; then + echo "SECURE_TLS_BOOTSTRAPPING_MAX_TOTAL_SECONDS=${SECURE_TLS_BOOTSTRAPPING_MAX_TOTAL_SECONDS}" >> "${SECURE_TLS_BOOTSTRAPPING_DEFAULT_FILE}" + fi + if [ -n "${SECURE_TLS_BOOTSTRAPPING_INITIAL_BACKOFF_SECONDS}" ]; then + echo "SECURE_TLS_BOOTSTRAPPING_INITIAL_BACKOFF_SECONDS=${SECURE_TLS_BOOTSTRAPPING_INITIAL_BACKOFF_SECONDS}" >> "${SECURE_TLS_BOOTSTRAPPING_DEFAULT_FILE}" + fi + if [ -n "${SECURE_TLS_BOOTSTRAPPING_MAX_BACKOFF_SECONDS}" ]; then + echo "SECURE_TLS_BOOTSTRAPPING_MAX_BACKOFF_SECONDS=${SECURE_TLS_BOOTSTRAPPING_MAX_BACKOFF_SECONDS}" >> "${SECURE_TLS_BOOTSTRAPPING_DEFAULT_FILE}" + fi mkdir -p "$(dirname "${SECURE_TLS_BOOTSTRAPPING_DROP_IN}")" touch "${SECURE_TLS_BOOTSTRAPPING_DROP_IN}" diff --git a/parts/linux/cloud-init/artifacts/secure-tls-bootstrap-retry-cap.sh b/parts/linux/cloud-init/artifacts/secure-tls-bootstrap-retry-cap.sh new file mode 100755 index 00000000000..a43bbaa7696 --- /dev/null +++ b/parts/linux/cloud-init/artifacts/secure-tls-bootstrap-retry-cap.sh @@ -0,0 +1,318 @@ +#!/bin/bash +# +# secure-tls-bootstrap-retry-cap.sh +# +# Wrapper around the aks-secure-tls-bootstrap-client binary that enforces a +# per-provisioning-session retry cap. Without this wrapper, a single stuck VM +# (e.g. transient DNS failure) drives the binary in a kubelet-restart loop and +# emits thousands of failure events per VM, dominating per-event QoS metrics. +# +# Behavior per invocation: +# - Acquires a flock on the state dir lock file +# - On a different boot id (reboot), resets all state +# - If the cap-sentinel already exists, exits 0 immediately (no event) +# - If attempts >= max OR elapsed >= total budget, emits a single distinct +# terminal event (TaskName=...SecureTLSBootstrapping.RetryCapReached) and +# exits 0 so systemd marks the unit successful and stops re-triggering it +# - Otherwise sleeps for max(0, backoff - elapsed_since_last) and runs the +# binary as a subprocess; captures the binary's FinalErrorType from the +# newest event file it produced +# - Exits with the binary's exit code on the happy / non-capped path +# +# Configurable via env vars (overridable from BootstrappingConfig): +# SECURE_TLS_BOOTSTRAPPING_MAX_ATTEMPTS (default 50) +# SECURE_TLS_BOOTSTRAPPING_MAX_TOTAL_SECONDS (default 7200 = 2 h) +# SECURE_TLS_BOOTSTRAPPING_INITIAL_BACKOFF_SECONDS (default 1) +# SECURE_TLS_BOOTSTRAPPING_MAX_BACKOFF_SECONDS (default 300) +# +# Per-provisioning-session reset: configureAndStartSecureTLSBootstrapping in +# cse_config.sh wipes the state dir before starting the unit. A reboot also +# resets state via the boot-id check below. + +set -u + +STATE_DIR="${SECURE_TLS_BOOTSTRAPPING_STATE_DIR:-/var/lib/aks-secure-tls-bootstrap}" +EVENTS_DIR="${SECURE_TLS_BOOTSTRAPPING_EVENTS_DIR:-/var/log/azure/Microsoft.Azure.Extensions.CustomScript/events}" +BINARY="${SECURE_TLS_BOOTSTRAPPING_BINARY:-/opt/bin/aks-secure-tls-bootstrap-client}" +BOOT_ID_FILE="${SECURE_TLS_BOOTSTRAPPING_BOOT_ID_SRC:-/proc/sys/kernel/random/boot_id}" + +MAX_ATTEMPTS="${SECURE_TLS_BOOTSTRAPPING_MAX_ATTEMPTS:-50}" +MAX_TOTAL_SECONDS="${SECURE_TLS_BOOTSTRAPPING_MAX_TOTAL_SECONDS:-7200}" +INITIAL_BACKOFF_SECONDS="${SECURE_TLS_BOOTSTRAPPING_INITIAL_BACKOFF_SECONDS:-1}" +MAX_BACKOFF_SECONDS="${SECURE_TLS_BOOTSTRAPPING_MAX_BACKOFF_SECONDS:-300}" + +# Clamp non-numeric / negative values to safe defaults to harden against +# garbage env (e.g. apiserver renders an empty override). +sanitize_positive_int() { + local val="$1" + local fallback="$2" + case "$val" in + ''|*[!0-9]*) echo "$fallback" ;; + *) echo "$val" ;; + esac +} + +MAX_ATTEMPTS=$(sanitize_positive_int "$MAX_ATTEMPTS" 50) +MAX_TOTAL_SECONDS=$(sanitize_positive_int "$MAX_TOTAL_SECONDS" 7200) +INITIAL_BACKOFF_SECONDS=$(sanitize_positive_int "$INITIAL_BACKOFF_SECONDS" 1) +MAX_BACKOFF_SECONDS=$(sanitize_positive_int "$MAX_BACKOFF_SECONDS" 300) +[ "$INITIAL_BACKOFF_SECONDS" -lt 1 ] && INITIAL_BACKOFF_SECONDS=1 +[ "$MAX_BACKOFF_SECONDS" -lt "$INITIAL_BACKOFF_SECONDS" ] && MAX_BACKOFF_SECONDS="$INITIAL_BACKOFF_SECONDS" + +ATTEMPTS_FILE="${STATE_DIR}/attempts" +FIRST_ATTEMPT_FILE="${STATE_DIR}/first-attempt" +LAST_ATTEMPT_FILE="${STATE_DIR}/last-attempt" +BOOT_ID_STATE_FILE="${STATE_DIR}/boot-id" +LAST_FINAL_ERROR_FILE="${STATE_DIR}/last-final-error" +CAPPED_SENTINEL="${STATE_DIR}/capped" +LOCK_FILE="${STATE_DIR}/.lock" + +read_int_file() { + local f="$1" + local default="$2" + if [ -r "$f" ]; then + local v + v=$(head -c 32 "$f" 2>/dev/null | tr -d '[:space:]') + case "$v" in + ''|*[!0-9]*) echo "$default" ;; + *) echo "$v" ;; + esac + else + echo "$default" + fi +} + +read_text_file() { + local f="$1" + local default="$2" + if [ -r "$f" ]; then + head -c 256 "$f" 2>/dev/null | tr -d '\n\r' + else + echo "$default" + fi +} + +compute_backoff() { + # Loop-double from INITIAL_BACKOFF_SECONDS, n times, capped at MAX_BACKOFF_SECONDS. + # Loop-based to avoid integer overflow on large attempts (2^63 etc.). + local n="$1" + local b="$INITIAL_BACKOFF_SECONDS" + local i=0 + while [ "$i" -lt "$n" ]; do + b=$((b * 2)) + if [ "$b" -ge "$MAX_BACKOFF_SECONDS" ]; then + echo "$MAX_BACKOFF_SECONDS" + return + fi + i=$((i + 1)) + done + echo "$b" +} + +emit_cap_event() { + local attempts="$1" + local elapsed="$2" + local final_error="$3" + local now_unix_ms + now_unix_ms=$(date +%s%3N) + local now_fmt + now_fmt=$(date +"%F %T.%3N") + + mkdir -p "$EVENTS_DIR" + + local client_version="unknown" + if [ -x "$BINARY" ]; then + client_version=$("$BINARY" --version 2>/dev/null | head -1 | tr -d '\n\r' || echo "unknown") + [ -z "$client_version" ] && client_version="unknown" + fi + + # Build the inner Message JSON (a single string field per WALinuxAgent + # schema). Keep all values as strings for parser robustness. + local message + if command -v jq >/dev/null 2>&1; then + message=$(jq -nc \ + --arg status "Failure" \ + --arg reason "RetryCapReached" \ + --arg attempts "$attempts" \ + --arg elapsed "$elapsed" \ + --arg final "$final_error" \ + --arg maxAttempts "$MAX_ATTEMPTS" \ + --arg maxTotal "$MAX_TOTAL_SECONDS" \ + --arg client "$client_version" \ + '{Status:$status, Reason:$reason, Attempts:$attempts, ElapsedSeconds:$elapsed, FinalErrorType:$final, MaxAttempts:$maxAttempts, MaxTotalSeconds:$maxTotal, ClientVersion:$client}') + else + # Defensive fallback (jq is on the VHD, but if missing we still emit + # a valid event so the cap signal isn't lost). + message="{\"Status\":\"Failure\",\"Reason\":\"RetryCapReached\",\"Attempts\":\"$attempts\",\"ElapsedSeconds\":\"$elapsed\",\"FinalErrorType\":\"$final_error\",\"MaxAttempts\":\"$MAX_ATTEMPTS\",\"MaxTotalSeconds\":\"$MAX_TOTAL_SECONDS\",\"ClientVersion\":\"$client_version\"}" + fi + + local event_json + if command -v jq >/dev/null 2>&1; then + event_json=$(jq -nc \ + --arg ts "$now_fmt" \ + --arg op "$now_fmt" \ + --arg ver "1.23" \ + --arg task "AKS.Bootstrap.SecureTLSBootstrapping.RetryCapReached" \ + --arg lvl "Error" \ + --arg msg "$message" \ + --arg pid "$$" \ + --arg tid "0" \ + '{Timestamp:$ts, OperationId:$op, Version:$ver, TaskName:$task, EventLevel:$lvl, Message:$msg, EventPid:$pid, EventTid:$tid}') + else + local esc_msg + esc_msg=$(printf '%s' "$message" | sed 's/\\/\\\\/g; s/"/\\"/g') + event_json="{\"Timestamp\":\"$now_fmt\",\"OperationId\":\"$now_fmt\",\"Version\":\"1.23\",\"TaskName\":\"AKS.Bootstrap.SecureTLSBootstrapping.RetryCapReached\",\"EventLevel\":\"Error\",\"Message\":\"$esc_msg\",\"EventPid\":\"$$\",\"EventTid\":\"0\"}" + fi + + local event_file="${EVENTS_DIR}/${now_unix_ms}.json" + umask 077 + printf '%s' "$event_json" > "$event_file" + chmod 0600 "$event_file" 2>/dev/null || true +} + +update_last_final_error() { + # Best-effort: find the newest event JSON produced under EVENTS_DIR after + # invocation start. Parse its Message field for FinalErrorType. Used to + # propagate the binary's last failure reason into the cap event. + local since_unix="$1" + [ -d "$EVENTS_DIR" ] || return 0 + local newest + newest=$(find "$EVENTS_DIR" -maxdepth 1 -type f -name '*.json' -newermt "@$since_unix" -printf '%T@ %p\n' 2>/dev/null \ + | sort -nr | head -1 | awk '{print $2}') + [ -z "$newest" ] && return 0 + [ -r "$newest" ] || return 0 + + local final="" + if command -v jq >/dev/null 2>&1; then + # Two layers: top-level Message is a string holding JSON. + local inner + inner=$(jq -r '.Message // ""' "$newest" 2>/dev/null) + if [ -n "$inner" ]; then + final=$(printf '%s' "$inner" | jq -r '.FinalErrorType // ""' 2>/dev/null) + fi + fi + if [ -n "$final" ] && [ "$final" != "null" ]; then + printf '%s' "$final" > "$LAST_FINAL_ERROR_FILE" + fi +} + +run_capped() { + local current_boot + current_boot=$(cat "$BOOT_ID_FILE" 2>/dev/null | tr -d '\n\r' || echo "") + + mkdir -p "$STATE_DIR" + chmod 0700 "$STATE_DIR" 2>/dev/null || true + + # Boot-id reset: if we're on a different boot than the last persisted one, + # this is a fresh recovery attempt — wipe state. + if [ -f "$BOOT_ID_STATE_FILE" ]; then + local persisted_boot + persisted_boot=$(read_text_file "$BOOT_ID_STATE_FILE" "") + if [ -n "$persisted_boot" ] && [ "$persisted_boot" != "$current_boot" ]; then + rm -f "$ATTEMPTS_FILE" "$FIRST_ATTEMPT_FILE" "$LAST_ATTEMPT_FILE" \ + "$LAST_FINAL_ERROR_FILE" "$CAPPED_SENTINEL" 2>/dev/null || true + fi + fi + + # If we've already capped in this boot, no-op (and exit 0 so systemd + # marks the unit successful — important: this is what stops kubelet's + # restart loop from continually re-triggering the unit). + if [ -e "$CAPPED_SENTINEL" ]; then + echo "secure-tls-bootstrap-retry-cap: cap already reached this boot; exiting 0" >&2 + return 0 + fi + + local now attempts first last + now=$(date +%s) + attempts=$(read_int_file "$ATTEMPTS_FILE" 0) + first=$(read_int_file "$FIRST_ATTEMPT_FILE" 0) + last=$(read_int_file "$LAST_ATTEMPT_FILE" 0) + + local elapsed=0 + [ "$first" -gt 0 ] && elapsed=$((now - first)) + [ "$elapsed" -lt 0 ] && elapsed=0 + + if [ "$attempts" -ge "$MAX_ATTEMPTS" ] || \ + { [ "$first" -gt 0 ] && [ "$elapsed" -ge "$MAX_TOTAL_SECONDS" ]; }; then + local final_error + final_error=$(read_text_file "$LAST_FINAL_ERROR_FILE" "Unknown") + echo "secure-tls-bootstrap-retry-cap: cap reached (attempts=$attempts/$MAX_ATTEMPTS, elapsed=${elapsed}s/${MAX_TOTAL_SECONDS}s, finalError=$final_error). Giving up." >&2 + emit_cap_event "$attempts" "$elapsed" "$final_error" + : > "$CAPPED_SENTINEL" + chmod 0600 "$CAPPED_SENTINEL" 2>/dev/null || true + return 0 + fi + + # Backoff: sleep so we wait at least `backoff` between attempt N and N+1. + local backoff sleep_for since_last + backoff=$(compute_backoff "$attempts") + if [ "$last" -gt 0 ]; then + since_last=$((now - last)) + [ "$since_last" -lt 0 ] && since_last=0 + if [ "$since_last" -lt "$backoff" ]; then + sleep_for=$((backoff - since_last)) + echo "secure-tls-bootstrap-retry-cap: backoff sleep ${sleep_for}s (attempt $((attempts + 1))/$MAX_ATTEMPTS, since_last=${since_last}s, target=${backoff}s)" >&2 + sleep "$sleep_for" + fi + fi + + # Persist updated counters before invoking the binary so a kill-mid-run + # still counts as an attempt. + now=$(date +%s) + attempts=$((attempts + 1)) + printf '%s' "$attempts" > "$ATTEMPTS_FILE" + printf '%s' "$now" > "$LAST_ATTEMPT_FILE" + if [ "$first" -le 0 ]; then + printf '%s' "$now" > "$FIRST_ATTEMPT_FILE" + fi + if [ -n "$current_boot" ]; then + printf '%s' "$current_boot" > "$BOOT_ID_STATE_FILE" + fi + chmod 0600 "$ATTEMPTS_FILE" "$LAST_ATTEMPT_FILE" "$FIRST_ATTEMPT_FILE" \ + "$BOOT_ID_STATE_FILE" 2>/dev/null || true + + local invocation_start + invocation_start=$(date +%s) + + # Run the binary as a subprocess (NOT exec) so we can post-process events. + "$BINARY" "$@" + local rc=$? + + update_last_final_error "$invocation_start" + + return $rc +} + +main() { + if [ ! -x "$BINARY" ]; then + echo "secure-tls-bootstrap-retry-cap: binary not found or not executable at $BINARY" >&2 + # Exit non-zero so the systemd unit fails loudly during VHD validation. + exit 127 + fi + + mkdir -p "$STATE_DIR" + chmod 0700 "$STATE_DIR" 2>/dev/null || true + + # flock the entire wrapper body — systemd shouldn't run two ExecStart + # instances concurrently, but this defends against manual systemctl + # operations and unit-config changes. flock isn't available on every + # platform (notably macOS in unit tests); when absent we proceed without + # the lock — production targets (Ubuntu / Azure Linux) always have it + # via util-linux. + if command -v flock >/dev/null 2>&1; then + exec 9>"$LOCK_FILE" + if ! flock -n 9; then + echo "secure-tls-bootstrap-retry-cap: another instance is running; exiting 0" >&2 + exit 0 + fi + fi + + run_capped "$@" + exit $? +} + +# Only invoke main when executed directly. Sourcing (e.g. from ShellSpec) skips +# this so tests can exercise helpers in isolation. +if [ "${BASH_SOURCE[0]}" = "$0" ] || [ -z "${BASH_SOURCE[0]:-}" ]; then + main "$@" +fi diff --git a/parts/linux/cloud-init/artifacts/secure-tls-bootstrap.service b/parts/linux/cloud-init/artifacts/secure-tls-bootstrap.service index 7f2c880629d..1116b9cf817 100644 --- a/parts/linux/cloud-init/artifacts/secure-tls-bootstrap.service +++ b/parts/linux/cloud-init/artifacts/secure-tls-bootstrap.service @@ -1,6 +1,6 @@ [Unit] Description=AKS Secure TLS Bootstrap Client -ConditionPathExists=/opt/bin/aks-secure-tls-bootstrap-client +ConditionPathExists=/opt/azure/containers/secure-tls-bootstrap-retry-cap.sh Wants=network-online.target After=network-online.target @@ -8,7 +8,10 @@ After=network-online.target Type=oneshot RemainAfterExit=yes -ExecStart=/opt/bin/aks-secure-tls-bootstrap-client \ +# Wrapped via secure-tls-bootstrap-retry-cap.sh to bound per-VM retries when +# the bootstrap client is stuck. See AB#38327355 for context: a single stuck +# VM previously generated thousands of failure events and dominated QoS. +ExecStart=/opt/azure/containers/secure-tls-bootstrap-retry-cap.sh \ --verbose \ --ensure-authorized \ --next-proto=aks-tls-bootstrap \ diff --git a/pkg/agent/baker.go b/pkg/agent/baker.go index cc7ae255de9..80c340264af 100644 --- a/pkg/agent/baker.go +++ b/pkg/agent/baker.go @@ -695,6 +695,18 @@ func getContainerServiceFuncMap(config *datamodel.NodeBootstrappingConfiguration "GetSecureTLSBootstrappingDeadline": func() string { return config.SecureTLSBootstrappingConfig.GetDeadline() }, + "GetSecureTLSBootstrappingMaxAttempts": func() string { + return config.SecureTLSBootstrappingConfig.GetMaxAttempts() + }, + "GetSecureTLSBootstrappingMaxTotalSeconds": func() string { + return config.SecureTLSBootstrappingConfig.GetMaxTotalSeconds() + }, + "GetSecureTLSBootstrappingInitialBackoffSeconds": func() string { + return config.SecureTLSBootstrappingConfig.GetInitialBackoffSeconds() + }, + "GetSecureTLSBootstrappingMaxBackoffSeconds": func() string { + return config.SecureTLSBootstrappingConfig.GetMaxBackoffSeconds() + }, "GetTLSBootstrapTokenForKubeConfig": func() string { return GetTLSBootstrapTokenForKubeConfig(config.KubeletClientTLSBootstrapToken) }, diff --git a/pkg/agent/baker_test.go b/pkg/agent/baker_test.go index 15f1c6a1e9e..75694d94a7b 100644 --- a/pkg/agent/baker_test.go +++ b/pkg/agent/baker_test.go @@ -1149,6 +1149,10 @@ var _ = Describe("getLinuxNodeCSECommand", func() { GetAttestedDataTimeout: "custom-get-attested-data-timeout", GetCredentialTimeout: "custom-get-credential-timeout", Deadline: "custom-deadline", + MaxAttempts: "custom-max-attempts", + MaxTotalSeconds: "custom-max-total-seconds", + InitialBackoffSeconds: "custom-initial-backoff-seconds", + MaxBackoffSeconds: "custom-max-backoff-seconds", } cseCmd := templateGenerator.getLinuxNodeCSECommand(baseConfig) @@ -1168,6 +1172,10 @@ var _ = Describe("getLinuxNodeCSECommand", func() { Expect(vars).To(HaveKeyWithValue("SECURE_TLS_BOOTSTRAPPING_GET_CREDENTIAL_TIMEOUT", "custom-get-credential-timeout")) Expect(vars).To(HaveKeyWithValue("SECURE_TLS_BOOTSTRAPPING_DEADLINE", "custom-deadline")) Expect(vars).To(HaveKeyWithValue("CUSTOM_SECURE_TLS_BOOTSTRAPPING_CLIENT_DOWNLOAD_URL", "custom-client-download-url")) + Expect(vars).To(HaveKeyWithValue("SECURE_TLS_BOOTSTRAPPING_MAX_ATTEMPTS", "custom-max-attempts")) + Expect(vars).To(HaveKeyWithValue("SECURE_TLS_BOOTSTRAPPING_MAX_TOTAL_SECONDS", "custom-max-total-seconds")) + Expect(vars).To(HaveKeyWithValue("SECURE_TLS_BOOTSTRAPPING_INITIAL_BACKOFF_SECONDS", "custom-initial-backoff-seconds")) + Expect(vars).To(HaveKeyWithValue("SECURE_TLS_BOOTSTRAPPING_MAX_BACKOFF_SECONDS", "custom-max-backoff-seconds")) }) It("should handle kubelet serving certificate rotation", func() { diff --git a/pkg/agent/datamodel/types.go b/pkg/agent/datamodel/types.go index 24839ca1cce..48ac573d32e 100644 --- a/pkg/agent/datamodel/types.go +++ b/pkg/agent/datamodel/types.go @@ -1902,6 +1902,29 @@ type SecureTLSBootstrappingConfig struct { // // Deprecated: Use individual RPC timeouts instead. Deadline string `json:"secureTLSBootstrappingDeadline,omitempty"` + + // MaxAttempts is an optional override that bounds the number of times the secure TLS bootstrap + // client may be re-invoked by systemd within a single provisioning session before the wrapper + // gives up and emits a terminal "RetryCapReached" event. See AB#38327355. + // When unset, the wrapper falls back to its built-in default (50). + MaxAttempts string `json:"secureTLSBootstrappingMaxAttempts,omitempty"` + + // MaxTotalSeconds is an optional override that bounds the total wall-clock time the secure TLS + // bootstrap wrapper will keep re-attempting within a single provisioning session before giving + // up and emitting a terminal "RetryCapReached" event. + // When unset, the wrapper falls back to its built-in default (7200 seconds / 2 hours). + MaxTotalSeconds string `json:"secureTLSBootstrappingMaxTotalSeconds,omitempty"` + + // InitialBackoffSeconds is an optional override for the initial backoff duration the secure + // TLS bootstrap wrapper sleeps between consecutive attempts. Doubled on each attempt up to + // MaxBackoffSeconds. + // When unset, the wrapper falls back to its built-in default (1 second). + InitialBackoffSeconds string `json:"secureTLSBootstrappingInitialBackoffSeconds,omitempty"` + + // MaxBackoffSeconds is an optional override that caps the exponential backoff delay between + // consecutive secure TLS bootstrap attempts. + // When unset, the wrapper falls back to its built-in default (300 seconds / 5 minutes). + MaxBackoffSeconds string `json:"secureTLSBootstrappingMaxBackoffSeconds,omitempty"` } func (c *SecureTLSBootstrappingConfig) GetEnabled() bool { @@ -1981,6 +2004,34 @@ func (c *SecureTLSBootstrappingConfig) GetDeadline() string { return c.Deadline } +func (c *SecureTLSBootstrappingConfig) GetMaxAttempts() string { + if c == nil { + return "" + } + return c.MaxAttempts +} + +func (c *SecureTLSBootstrappingConfig) GetMaxTotalSeconds() string { + if c == nil { + return "" + } + return c.MaxTotalSeconds +} + +func (c *SecureTLSBootstrappingConfig) GetInitialBackoffSeconds() string { + if c == nil { + return "" + } + return c.InitialBackoffSeconds +} + +func (c *SecureTLSBootstrappingConfig) GetMaxBackoffSeconds() string { + if c == nil { + return "" + } + return c.MaxBackoffSeconds +} + // AKSKubeletConfiguration contains the configuration for the Kubelet that AKS set. /* this is a subset of KubeletConfiguration defined in https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/kubelet/config/v1beta1/types.go diff --git a/spec/parts/linux/cloud-init/artifacts/cse_config_spec.sh b/spec/parts/linux/cloud-init/artifacts/cse_config_spec.sh index 3b7c970bb3d..a8e00cf402e 100755 --- a/spec/parts/linux/cloud-init/artifacts/cse_config_spec.sh +++ b/spec/parts/linux/cloud-init/artifacts/cse_config_spec.sh @@ -1220,6 +1220,7 @@ SETUP_EOF SECURE_TLS_BOOTSTRAPPING_DROP_IN="${SECURE_TLS_BOOTSTRAPPING_DROP_IN_DIR}/10-securetlsbootstrap.conf" SECURE_TLS_BOOTSTRAPPING_DEFAULT_FILE_DIR="default" SECURE_TLS_BOOTSTRAPPING_DEFAULT_FILE="${SECURE_TLS_BOOTSTRAPPING_DEFAULT_FILE_DIR}/secure-tls-bootstrap" + SECURE_TLS_BOOTSTRAPPING_STATE_DIR="stls-state" API_SERVER_NAME="fqdn" AZURE_JSON_PATH="/etc/kubernetes/azure.json" @@ -1230,6 +1231,7 @@ SETUP_EOF cleanup() { rm -rf "$SECURE_TLS_BOOTSTRAPPING_DROP_IN_DIR" rm -rf "$SECURE_TLS_BOOTSTRAPPING_DEFAULT_FILE_DIR" + rm -rf "$SECURE_TLS_BOOTSTRAPPING_STATE_DIR" } AfterEach 'cleanup' @@ -1291,6 +1293,54 @@ SETUP_EOF The contents of file "default/secure-tls-bootstrap" should include 'BOOTSTRAP_FLAGS=--aad-resource=custom-resource --apiserver-fqdn=fqdn --cloud-provider-config=/etc/kubernetes/azure.json --user-assigned-identity-id=custom-identity-id --validate-kubeconfig-timeout=custom-validate-kubeconfig-timeout --get-access-token-timeout=custom-get-access-token-timeout --get-instance-data-timeout=custom-get-instance-data-timeout --get-nonce-timeout=custom-get-nonce-timeout --get-attested-data-timeout=custom-get-attested-data-timeout --get-credential-timeout=custom-get-credential-timeout --deadline=custom-deadline' The status should be success End + + It 'should wipe stale retry-cap state at the start of every provisioning session' + systemctlEnableAndStartNoBlock() { + echo "systemctlEnableAndStartNoBlock $@" + } + mkdir -p "${SECURE_TLS_BOOTSTRAPPING_STATE_DIR}" + echo "999" > "${SECURE_TLS_BOOTSTRAPPING_STATE_DIR}/attempts" + echo "1234567890" > "${SECURE_TLS_BOOTSTRAPPING_STATE_DIR}/first-attempt" + : > "${SECURE_TLS_BOOTSTRAPPING_STATE_DIR}/capped" + When call configureAndStartSecureTLSBootstrapping + The path "${SECURE_TLS_BOOTSTRAPPING_STATE_DIR}/attempts" should not be exist + The path "${SECURE_TLS_BOOTSTRAPPING_STATE_DIR}/first-attempt" should not be exist + The path "${SECURE_TLS_BOOTSTRAPPING_STATE_DIR}/capped" should not be exist + The path "${SECURE_TLS_BOOTSTRAPPING_STATE_DIR}" should not be exist + The status should be success + End + + It 'should not forward retry-cap env vars when unset (wrapper uses defaults)' + systemctlEnableAndStartNoBlock() { + echo "systemctlEnableAndStartNoBlock $@" + } + unset SECURE_TLS_BOOTSTRAPPING_MAX_ATTEMPTS + unset SECURE_TLS_BOOTSTRAPPING_MAX_TOTAL_SECONDS + unset SECURE_TLS_BOOTSTRAPPING_INITIAL_BACKOFF_SECONDS + unset SECURE_TLS_BOOTSTRAPPING_MAX_BACKOFF_SECONDS + When call configureAndStartSecureTLSBootstrapping + The contents of file "default/secure-tls-bootstrap" should not include 'SECURE_TLS_BOOTSTRAPPING_MAX_ATTEMPTS' + The contents of file "default/secure-tls-bootstrap" should not include 'SECURE_TLS_BOOTSTRAPPING_MAX_TOTAL_SECONDS' + The contents of file "default/secure-tls-bootstrap" should not include 'SECURE_TLS_BOOTSTRAPPING_INITIAL_BACKOFF_SECONDS' + The contents of file "default/secure-tls-bootstrap" should not include 'SECURE_TLS_BOOTSTRAPPING_MAX_BACKOFF_SECONDS' + The status should be success + End + + It 'should forward retry-cap env vars to the default file when set' + systemctlEnableAndStartNoBlock() { + echo "systemctlEnableAndStartNoBlock $@" + } + SECURE_TLS_BOOTSTRAPPING_MAX_ATTEMPTS="42" + SECURE_TLS_BOOTSTRAPPING_MAX_TOTAL_SECONDS="3600" + SECURE_TLS_BOOTSTRAPPING_INITIAL_BACKOFF_SECONDS="2" + SECURE_TLS_BOOTSTRAPPING_MAX_BACKOFF_SECONDS="120" + When call configureAndStartSecureTLSBootstrapping + The contents of file "default/secure-tls-bootstrap" should include 'SECURE_TLS_BOOTSTRAPPING_MAX_ATTEMPTS=42' + The contents of file "default/secure-tls-bootstrap" should include 'SECURE_TLS_BOOTSTRAPPING_MAX_TOTAL_SECONDS=3600' + The contents of file "default/secure-tls-bootstrap" should include 'SECURE_TLS_BOOTSTRAPPING_INITIAL_BACKOFF_SECONDS=2' + The contents of file "default/secure-tls-bootstrap" should include 'SECURE_TLS_BOOTSTRAPPING_MAX_BACKOFF_SECONDS=120' + The status should be success + End End Describe 'configureKubeletAndKubectl' diff --git a/spec/parts/linux/cloud-init/artifacts/secure_tls_bootstrap_retry_cap_spec.sh b/spec/parts/linux/cloud-init/artifacts/secure_tls_bootstrap_retry_cap_spec.sh new file mode 100644 index 00000000000..7e55d793cbd --- /dev/null +++ b/spec/parts/linux/cloud-init/artifacts/secure_tls_bootstrap_retry_cap_spec.sh @@ -0,0 +1,261 @@ +# shellcheck shell=bash +# shellcheck disable=SC2034 # SHELLSPEC_TMPBASE set by ShellSpec +# +# Tests for parts/linux/cloud-init/artifacts/secure-tls-bootstrap-retry-cap.sh +# +# These tests exercise the wrapper end-to-end against fake binaries / state +# directories so behavior is verified without touching real /var paths. + +Describe 'secure-tls-bootstrap-retry-cap.sh' + WRAPPER="parts/linux/cloud-init/artifacts/secure-tls-bootstrap-retry-cap.sh" + + # Helper: read filesystem mode portably (GNU stat -c on Linux, + # BSD stat -f on macOS). + state_dir_mode() { + stat -c '%a' "${SCRATCH}/state" 2>/dev/null \ + || stat -f '%Lp' "${SCRATCH}/state" 2>/dev/null + } + + # Helper: concatenated content of all event JSON files written under + # ${SCRATCH}/events. Returns empty string if directory is absent. + event_files_contents() { + # shellcheck disable=SC2010 + if [ -d "${SCRATCH}/events" ]; then + cat "${SCRATCH}"/events/*.json 2>/dev/null + fi + } + + # Helper: count of event JSON files written under ${SCRATCH}/events. + event_files_count() { + if [ -d "${SCRATCH}/events" ]; then + find "${SCRATCH}/events" -mindepth 1 -maxdepth 1 -type f 2>/dev/null \ + | wc -l | tr -d '[:space:]' + else + printf '0' + fi + } + + # Helper: write a fake STLS binary that does not produce side effects + # for --version invocations (the wrapper queries --version when + # emitting the RetryCapReached event, and tests must not confuse that + # invocation with a real bootstrap attempt). + write_fake_binary() { + local marker_path="${1:-}" + cat > "${SCRATCH}/binary.sh" <> "${SCRATCH}/binary.sh" <> "${SCRATCH}/binary.sh" <<'EOS' +exit 0 +EOS + chmod +x "${SCRATCH}/binary.sh" + } + + setup() { + # Per-test scratch root inside the ShellSpec tmpbase (auto-cleaned). + # shellcheck disable=SC2154 + SCRATCH="${SHELLSPEC_TMPBASE}/stls-retry-cap-$$-${RANDOM}" + mkdir -p "${SCRATCH}" + export SECURE_TLS_BOOTSTRAPPING_STATE_DIR="${SCRATCH}/state" + export SECURE_TLS_BOOTSTRAPPING_EVENTS_DIR="${SCRATCH}/events" + export SECURE_TLS_BOOTSTRAPPING_BOOT_ID_SRC="${SCRATCH}/boot_id" + printf 'shellspec-boot-id-aaaa-bbbb-cccc' > "${SECURE_TLS_BOOTSTRAPPING_BOOT_ID_SRC}" + + write_fake_binary + export SECURE_TLS_BOOTSTRAPPING_BINARY="${SCRATCH}/binary.sh" + + # Conservative defaults that keep tests fast. + export SECURE_TLS_BOOTSTRAPPING_MAX_ATTEMPTS="3" + export SECURE_TLS_BOOTSTRAPPING_MAX_TOTAL_SECONDS="9999" + export SECURE_TLS_BOOTSTRAPPING_INITIAL_BACKOFF_SECONDS="1" + export SECURE_TLS_BOOTSTRAPPING_MAX_BACKOFF_SECONDS="4" + } + + cleanup() { + [ -n "${SCRATCH:-}" ] && rm -rf "${SCRATCH}" + unset SECURE_TLS_BOOTSTRAPPING_STATE_DIR + unset SECURE_TLS_BOOTSTRAPPING_EVENTS_DIR + unset SECURE_TLS_BOOTSTRAPPING_BOOT_ID_SRC + unset SECURE_TLS_BOOTSTRAPPING_BINARY + unset SECURE_TLS_BOOTSTRAPPING_MAX_ATTEMPTS + unset SECURE_TLS_BOOTSTRAPPING_MAX_TOTAL_SECONDS + unset SECURE_TLS_BOOTSTRAPPING_INITIAL_BACKOFF_SECONDS + unset SECURE_TLS_BOOTSTRAPPING_MAX_BACKOFF_SECONDS + } + + BeforeEach 'setup' + AfterEach 'cleanup' + + Describe 'happy path' + It 'runs the binary on first invocation and increments the attempts counter' + When run script "${WRAPPER}" + The status should be success + The output should include "fake-stls-binary called" + The contents of file "${SCRATCH}/state/attempts" should equal "1" + The path "${SCRATCH}/state/first-attempt" should be exist + The path "${SCRATCH}/state/last-attempt" should be exist + The path "${SCRATCH}/state/capped" should not be exist + End + + It 'creates the state directory with 0700 mode if missing' + When run script "${WRAPPER}" + The status should be success + The path "${SCRATCH}/state" should be directory + The output should include "fake-stls-binary called" + The result of function state_dir_mode should equal "700" + End + + It 'propagates the binary exit code on the non-capped path' + cat > "${SCRATCH}/binary.sh" <<'EOS' +#!/bin/bash +if [ "${1:-}" = "--version" ]; then + echo "v1.1.4-fake" + exit 0 +fi +exit 42 +EOS + chmod +x "${SCRATCH}/binary.sh" + When run script "${WRAPPER}" + The status should equal 42 + The contents of file "${SCRATCH}/state/attempts" should equal "1" + End + End + + Describe 'attempt cap' + It 'emits a single RetryCapReached event when the attempts cap is hit and does NOT run the binary' + # Seed the state as if we'd already done MAX_ATTEMPTS attempts. + mkdir -p "${SCRATCH}/state" + chmod 700 "${SCRATCH}/state" + echo "3" > "${SCRATCH}/state/attempts" + now_seed=$(date +%s) + echo "$((now_seed - 10))" > "${SCRATCH}/state/first-attempt" + echo "$((now_seed - 5))" > "${SCRATCH}/state/last-attempt" + printf 'shellspec-boot-id-aaaa-bbbb-cccc' > "${SCRATCH}/state/boot-id" + echo "GetNonceFailure" > "${SCRATCH}/state/last-final-error" + # If the binary is invoked as a bootstrap attempt (not as + # `--version`), it creates this marker — assert it doesn't. + write_fake_binary "${SCRATCH}/binary-ran" + + When run script "${WRAPPER}" + The status should be success + The stderr should include "cap reached" + The path "${SCRATCH}/binary-ran" should not be exist + The path "${SCRATCH}/state/capped" should be exist + End + + It 'writes a RetryCapReached event with the expected TaskName and FinalErrorType' + mkdir -p "${SCRATCH}/state" + chmod 700 "${SCRATCH}/state" + echo "3" > "${SCRATCH}/state/attempts" + now_seed=$(date +%s) + echo "$((now_seed - 10))" > "${SCRATCH}/state/first-attempt" + echo "$((now_seed - 5))" > "${SCRATCH}/state/last-attempt" + printf 'shellspec-boot-id-aaaa-bbbb-cccc' > "${SCRATCH}/state/boot-id" + echo "GetNonceFailure" > "${SCRATCH}/state/last-final-error" + + When run script "${WRAPPER}" + The status should be success + The stderr should include "cap reached" + The path "${SCRATCH}/state/capped" should be exist + The result of function event_files_contents should include "AKS.Bootstrap.SecureTLSBootstrapping.RetryCapReached" + The result of function event_files_contents should include "RetryCapReached" + The result of function event_files_contents should include "GetNonceFailure" + End + + It 'no-ops on subsequent invocations once the capped sentinel exists' + mkdir -p "${SCRATCH}/state" + chmod 700 "${SCRATCH}/state" + : > "${SCRATCH}/state/capped" + write_fake_binary "${SCRATCH}/binary-ran" + + When run script "${WRAPPER}" + The status should be success + The stderr should include "cap already reached" + The path "${SCRATCH}/binary-ran" should not be exist + # No new event written on the no-op path. + The result of function event_files_count should equal "0" + End + End + + Describe 'time-budget cap' + It 'fires the cap when elapsed time exceeds MAX_TOTAL_SECONDS even if attempts are low' + export SECURE_TLS_BOOTSTRAPPING_MAX_ATTEMPTS="999" + export SECURE_TLS_BOOTSTRAPPING_MAX_TOTAL_SECONDS="60" + mkdir -p "${SCRATCH}/state" + chmod 700 "${SCRATCH}/state" + echo "2" > "${SCRATCH}/state/attempts" + now_seed=$(date +%s) + # first-attempt was 5 minutes ago: budget exceeded. + echo "$((now_seed - 300))" > "${SCRATCH}/state/first-attempt" + echo "$((now_seed - 5))" > "${SCRATCH}/state/last-attempt" + printf 'shellspec-boot-id-aaaa-bbbb-cccc' > "${SCRATCH}/state/boot-id" + + When run script "${WRAPPER}" + The status should be success + The stderr should include "cap reached" + The path "${SCRATCH}/state/capped" should be exist + End + End + + Describe 'boot-id reset' + It 'wipes state when the boot-id changes between invocations' + mkdir -p "${SCRATCH}/state" + chmod 700 "${SCRATCH}/state" + echo "2" > "${SCRATCH}/state/attempts" + echo "100" > "${SCRATCH}/state/first-attempt" + echo "200" > "${SCRATCH}/state/last-attempt" + # Old boot id is different from the one we'll present below. + printf 'old-boot-id-xxx' > "${SCRATCH}/state/boot-id" + + When run script "${WRAPPER}" + The status should be success + The output should include "fake-stls-binary called" + # Counter was wiped then incremented to 1 on this invocation. + The contents of file "${SCRATCH}/state/attempts" should equal "1" + End + End + + Describe 'env-var overrides' + It 'honors a custom MAX_ATTEMPTS value when seeding right at the override' + export SECURE_TLS_BOOTSTRAPPING_MAX_ATTEMPTS="7" + mkdir -p "${SCRATCH}/state" + chmod 700 "${SCRATCH}/state" + echo "7" > "${SCRATCH}/state/attempts" + now_seed=$(date +%s) + echo "$((now_seed - 60))" > "${SCRATCH}/state/first-attempt" + echo "$((now_seed - 5))" > "${SCRATCH}/state/last-attempt" + printf 'shellspec-boot-id-aaaa-bbbb-cccc' > "${SCRATCH}/state/boot-id" + + When run script "${WRAPPER}" + The status should be success + The stderr should include "cap reached" + The path "${SCRATCH}/state/capped" should be exist + End + + It 'clamps a non-numeric MAX_ATTEMPTS to the safe default (50) and runs normally' + export SECURE_TLS_BOOTSTRAPPING_MAX_ATTEMPTS="not-a-number" + When run script "${WRAPPER}" + The status should be success + The output should include "fake-stls-binary called" + The contents of file "${SCRATCH}/state/attempts" should equal "1" + End + End + + Describe 'missing binary' + It 'exits 127 when the binary is not present' + export SECURE_TLS_BOOTSTRAPPING_BINARY="${SCRATCH}/does-not-exist" + When run script "${WRAPPER}" + The status should equal 127 + The stderr should include "binary not found" + End + End +End diff --git a/vhdbuilder/packer/packer_source.sh b/vhdbuilder/packer/packer_source.sh index 77eec3c2277..d6af4918472 100644 --- a/vhdbuilder/packer/packer_source.sh +++ b/vhdbuilder/packer/packer_source.sh @@ -131,6 +131,8 @@ copyPackerFiles() { KUBELET_SERVICE_DEST=/etc/systemd/system/kubelet.service SECURE_TLS_BOOTSTRAP_SERVICE_SRC=/home/packer/secure-tls-bootstrap.service SECURE_TLS_BOOTSTRAP_SERVICE_DEST=/etc/systemd/system/secure-tls-bootstrap.service + SECURE_TLS_BOOTSTRAP_RETRY_CAP_SCRIPT_SRC=/home/packer/secure-tls-bootstrap-retry-cap.sh + SECURE_TLS_BOOTSTRAP_RETRY_CAP_SCRIPT_DEST=/opt/azure/containers/secure-tls-bootstrap-retry-cap.sh USU_SH_SRC=/home/packer/ubuntu-snapshot-update.sh USU_SH_DEST=/opt/azure/containers/ubuntu-snapshot-update.sh MPU_SH_SRC=/home/packer/mariner-package-update.sh @@ -415,6 +417,7 @@ copyPackerFiles() { cpAndMode $KUBELET_SERVICE_SRC $KUBELET_SERVICE_DEST 600 cpAndMode $SECURE_TLS_BOOTSTRAP_SERVICE_SRC $SECURE_TLS_BOOTSTRAP_SERVICE_DEST 600 + cpAndMode $SECURE_TLS_BOOTSTRAP_RETRY_CAP_SCRIPT_SRC $SECURE_TLS_BOOTSTRAP_RETRY_CAP_SCRIPT_DEST 755 cpAndMode $BLOCK_WIRESERVER_SRC $BLOCK_WIRESERVER_DEST 755 cpAndMode $ENSURE_IMDS_RESTRICTION_SRC $ENSURE_IMDS_RESTRICTION_DEST 755 cpAndMode $MEASURE_TLS_BOOTSTRAPPING_LATENCY_SCRIPT_SRC $MEASURE_TLS_BOOTSTRAPPING_LATENCY_SCRIPT_DEST 755 diff --git a/vhdbuilder/packer/vhd-image-builder-acl-arm64.json b/vhdbuilder/packer/vhd-image-builder-acl-arm64.json index e212a973da5..98d3339f1f2 100644 --- a/vhdbuilder/packer/vhd-image-builder-acl-arm64.json +++ b/vhdbuilder/packer/vhd-image-builder-acl-arm64.json @@ -187,6 +187,11 @@ "source": "parts/linux/cloud-init/artifacts/secure-tls-bootstrap.service", "destination": "/home/packer/secure-tls-bootstrap.service" }, + { + "type": "file", + "source": "parts/linux/cloud-init/artifacts/secure-tls-bootstrap-retry-cap.sh", + "destination": "/home/packer/secure-tls-bootstrap-retry-cap.sh" + }, { "type": "file", "source": "parts/linux/cloud-init/artifacts/reconcile-private-hosts.sh", diff --git a/vhdbuilder/packer/vhd-image-builder-acl.json b/vhdbuilder/packer/vhd-image-builder-acl.json index 8fc19ab5f7c..bddc3abfd03 100644 --- a/vhdbuilder/packer/vhd-image-builder-acl.json +++ b/vhdbuilder/packer/vhd-image-builder-acl.json @@ -187,6 +187,11 @@ "source": "parts/linux/cloud-init/artifacts/secure-tls-bootstrap.service", "destination": "/home/packer/secure-tls-bootstrap.service" }, + { + "type": "file", + "source": "parts/linux/cloud-init/artifacts/secure-tls-bootstrap-retry-cap.sh", + "destination": "/home/packer/secure-tls-bootstrap-retry-cap.sh" + }, { "type": "file", "source": "parts/linux/cloud-init/artifacts/reconcile-private-hosts.sh", diff --git a/vhdbuilder/packer/vhd-image-builder-arm64-gb.json b/vhdbuilder/packer/vhd-image-builder-arm64-gb.json index fa25d264ec0..13329bc8019 100644 --- a/vhdbuilder/packer/vhd-image-builder-arm64-gb.json +++ b/vhdbuilder/packer/vhd-image-builder-arm64-gb.json @@ -212,6 +212,11 @@ "source": "parts/linux/cloud-init/artifacts/secure-tls-bootstrap.service", "destination": "/home/packer/secure-tls-bootstrap.service" }, + { + "type": "file", + "source": "parts/linux/cloud-init/artifacts/secure-tls-bootstrap-retry-cap.sh", + "destination": "/home/packer/secure-tls-bootstrap-retry-cap.sh" + }, { "type": "file", "source": "parts/linux/cloud-init/artifacts/reconcile-private-hosts.sh", diff --git a/vhdbuilder/packer/vhd-image-builder-arm64-gen2.json b/vhdbuilder/packer/vhd-image-builder-arm64-gen2.json index cf571b3431c..4dc7330d95d 100644 --- a/vhdbuilder/packer/vhd-image-builder-arm64-gen2.json +++ b/vhdbuilder/packer/vhd-image-builder-arm64-gen2.json @@ -197,6 +197,11 @@ "source": "parts/linux/cloud-init/artifacts/secure-tls-bootstrap.service", "destination": "/home/packer/secure-tls-bootstrap.service" }, + { + "type": "file", + "source": "parts/linux/cloud-init/artifacts/secure-tls-bootstrap-retry-cap.sh", + "destination": "/home/packer/secure-tls-bootstrap-retry-cap.sh" + }, { "type": "file", "source": "parts/linux/cloud-init/artifacts/reconcile-private-hosts.sh", diff --git a/vhdbuilder/packer/vhd-image-builder-base.json b/vhdbuilder/packer/vhd-image-builder-base.json index 1bb630a346e..191abc8ec0f 100644 --- a/vhdbuilder/packer/vhd-image-builder-base.json +++ b/vhdbuilder/packer/vhd-image-builder-base.json @@ -200,6 +200,11 @@ "source": "parts/linux/cloud-init/artifacts/secure-tls-bootstrap.service", "destination": "/home/packer/secure-tls-bootstrap.service" }, + { + "type": "file", + "source": "parts/linux/cloud-init/artifacts/secure-tls-bootstrap-retry-cap.sh", + "destination": "/home/packer/secure-tls-bootstrap-retry-cap.sh" + }, { "type": "file", "source": "parts/linux/cloud-init/artifacts/reconcile-private-hosts.sh", diff --git a/vhdbuilder/packer/vhd-image-builder-cvm.json b/vhdbuilder/packer/vhd-image-builder-cvm.json index a4b6e438c9d..20a7f04f8e3 100644 --- a/vhdbuilder/packer/vhd-image-builder-cvm.json +++ b/vhdbuilder/packer/vhd-image-builder-cvm.json @@ -204,6 +204,11 @@ "source": "parts/linux/cloud-init/artifacts/secure-tls-bootstrap.service", "destination": "/home/packer/secure-tls-bootstrap.service" }, + { + "type": "file", + "source": "parts/linux/cloud-init/artifacts/secure-tls-bootstrap-retry-cap.sh", + "destination": "/home/packer/secure-tls-bootstrap-retry-cap.sh" + }, { "type": "file", "source": "parts/linux/cloud-init/artifacts/reconcile-private-hosts.sh", diff --git a/vhdbuilder/packer/vhd-image-builder-flatcar-arm64.json b/vhdbuilder/packer/vhd-image-builder-flatcar-arm64.json index 669a381cce3..9f93ba68f1a 100644 --- a/vhdbuilder/packer/vhd-image-builder-flatcar-arm64.json +++ b/vhdbuilder/packer/vhd-image-builder-flatcar-arm64.json @@ -188,6 +188,11 @@ "source": "parts/linux/cloud-init/artifacts/secure-tls-bootstrap.service", "destination": "/home/packer/secure-tls-bootstrap.service" }, + { + "type": "file", + "source": "parts/linux/cloud-init/artifacts/secure-tls-bootstrap-retry-cap.sh", + "destination": "/home/packer/secure-tls-bootstrap-retry-cap.sh" + }, { "type": "file", "source": "parts/linux/cloud-init/artifacts/reconcile-private-hosts.sh", diff --git a/vhdbuilder/packer/vhd-image-builder-flatcar.json b/vhdbuilder/packer/vhd-image-builder-flatcar.json index 88f911705de..012e52951ce 100644 --- a/vhdbuilder/packer/vhd-image-builder-flatcar.json +++ b/vhdbuilder/packer/vhd-image-builder-flatcar.json @@ -188,6 +188,11 @@ "source": "parts/linux/cloud-init/artifacts/secure-tls-bootstrap.service", "destination": "/home/packer/secure-tls-bootstrap.service" }, + { + "type": "file", + "source": "parts/linux/cloud-init/artifacts/secure-tls-bootstrap-retry-cap.sh", + "destination": "/home/packer/secure-tls-bootstrap-retry-cap.sh" + }, { "type": "file", "source": "parts/linux/cloud-init/artifacts/reconcile-private-hosts.sh", diff --git a/vhdbuilder/packer/vhd-image-builder-mariner-arm64.json b/vhdbuilder/packer/vhd-image-builder-mariner-arm64.json index 96a506cd113..aa3464614bb 100644 --- a/vhdbuilder/packer/vhd-image-builder-mariner-arm64.json +++ b/vhdbuilder/packer/vhd-image-builder-mariner-arm64.json @@ -196,6 +196,11 @@ "source": "parts/linux/cloud-init/artifacts/secure-tls-bootstrap.service", "destination": "/home/packer/secure-tls-bootstrap.service" }, + { + "type": "file", + "source": "parts/linux/cloud-init/artifacts/secure-tls-bootstrap-retry-cap.sh", + "destination": "/home/packer/secure-tls-bootstrap-retry-cap.sh" + }, { "type": "file", "source": "parts/linux/cloud-init/artifacts/reconcile-private-hosts.sh", diff --git a/vhdbuilder/packer/vhd-image-builder-mariner-cvm.json b/vhdbuilder/packer/vhd-image-builder-mariner-cvm.json index f2260889fd8..5cfd029e4c1 100644 --- a/vhdbuilder/packer/vhd-image-builder-mariner-cvm.json +++ b/vhdbuilder/packer/vhd-image-builder-mariner-cvm.json @@ -202,6 +202,11 @@ "source": "parts/linux/cloud-init/artifacts/secure-tls-bootstrap.service", "destination": "/home/packer/secure-tls-bootstrap.service" }, + { + "type": "file", + "source": "parts/linux/cloud-init/artifacts/secure-tls-bootstrap-retry-cap.sh", + "destination": "/home/packer/secure-tls-bootstrap-retry-cap.sh" + }, { "type": "file", "source": "parts/linux/cloud-init/artifacts/reconcile-private-hosts.sh", diff --git a/vhdbuilder/packer/vhd-image-builder-mariner.json b/vhdbuilder/packer/vhd-image-builder-mariner.json index 7c43894b629..6900f840108 100644 --- a/vhdbuilder/packer/vhd-image-builder-mariner.json +++ b/vhdbuilder/packer/vhd-image-builder-mariner.json @@ -198,6 +198,11 @@ "source": "parts/linux/cloud-init/artifacts/secure-tls-bootstrap.service", "destination": "/home/packer/secure-tls-bootstrap.service" }, + { + "type": "file", + "source": "parts/linux/cloud-init/artifacts/secure-tls-bootstrap-retry-cap.sh", + "destination": "/home/packer/secure-tls-bootstrap-retry-cap.sh" + }, { "type": "file", "source": "parts/linux/cloud-init/artifacts/reconcile-private-hosts.sh",