Merge pull request #57488 from mtaufen/kc-bootstrap-refactor

Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

Refactor kubelet config controller bootstrap process

This makes the bootstrap feel much more linear and as a result it is easier to read.

Also simplifies status reporting for local config.

Fixes: #57487

```release-note
NONE
```
This commit is contained in:
Kubernetes Submit Queue 2017-12-21 17:53:04 -08:00 committed by GitHub
commit f4d3f4dcc0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 176 additions and 190 deletions

View File

@ -10,7 +10,6 @@ go_library(
srcs = [
"configsync.go",
"controller.go",
"rollback.go",
"watch.go",
],
importpath = "k8s.io/kubernetes/pkg/kubelet/kubeletconfig",

View File

@ -168,7 +168,7 @@ func (cc *Controller) setCurrentConfig(source checkpoint.RemoteConfigSource) (bo
updated, err := cc.checkpointStore.SetCurrentUpdated(source)
if err != nil {
if source == nil {
return false, status.FailSyncReasonSetCurrentDefault, err
return false, status.FailSyncReasonSetCurrentLocal, err
}
return false, fmt.Sprintf(status.FailSyncReasonSetCurrentUIDFmt, source.UID()), err
}

View File

@ -28,6 +28,8 @@ import (
"k8s.io/client-go/tools/cache"
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/validation"
"k8s.io/kubernetes/pkg/kubelet/kubeletconfig/checkpoint"
"k8s.io/kubernetes/pkg/kubelet/kubeletconfig/checkpoint/store"
"k8s.io/kubernetes/pkg/kubelet/kubeletconfig/configfiles"
"k8s.io/kubernetes/pkg/kubelet/kubeletconfig/status"
@ -55,11 +57,8 @@ type Controller struct {
// defaultConfig is the configuration to use if no initConfig is provided
defaultConfig *kubeletconfig.KubeletConfiguration
// initConfig is the unmarshaled init config, this will be loaded by the Controller if an initConfigDir is provided
initConfig *kubeletconfig.KubeletConfiguration
// initLoader is for loading the Kubelet's init configuration files from disk
initLoader configfiles.Loader
// fileLoader is for loading the Kubelet's local config files from disk
fileLoader configfiles.Loader
// pendingConfigSource; write to this channel to indicate that the config source needs to be synced from the API server
pendingConfigSource chan bool
@ -85,9 +84,9 @@ func NewController(defaultConfig *kubeletconfig.KubeletConfiguration,
fs := utilfs.DefaultFs{}
var initLoader configfiles.Loader
var fileLoader configfiles.Loader
if len(initConfigDir) > 0 {
initLoader, err = configfiles.NewFsLoader(fs, initConfigDir)
fileLoader, err = configfiles.NewFsLoader(fs, initConfigDir)
if err != nil {
return nil, err
}
@ -104,7 +103,7 @@ func NewController(defaultConfig *kubeletconfig.KubeletConfiguration,
pendingConfigSource: make(chan bool, 1),
configOK: status.NewConfigOKCondition(),
checkpointStore: store.NewFsStore(fs, filepath.Join(dynamicConfigDir, checkpointsDir)),
initLoader: initLoader,
fileLoader: fileLoader,
}, nil
}
@ -113,88 +112,72 @@ func NewController(defaultConfig *kubeletconfig.KubeletConfiguration,
func (cc *Controller) Bootstrap() (*kubeletconfig.KubeletConfiguration, error) {
utillog.Infof("starting controller")
// ALWAYS validate the local (default and init) configs. This makes incorrectly provisioned nodes an error.
// These must be valid because they are the foundational last-known-good configs.
utillog.Infof("validating combination of defaults and flags")
if err := validation.ValidateKubeletConfiguration(cc.defaultConfig); err != nil {
return nil, fmt.Errorf("combination of defaults and flags failed validation, error: %v", err)
}
// only attempt to load and validate the init config if the user provided a path
if cc.initLoader != nil {
utillog.Infof("loading init config")
kc, err := cc.initLoader.Load()
if err != nil {
return nil, err
}
// validate the init config
utillog.Infof("validating init config")
if err := validation.ValidateKubeletConfiguration(kc); err != nil {
return nil, fmt.Errorf("failed to validate the init config, error: %v", err)
}
cc.initConfig = kc
}
// Assert: the default and init configs are both valid
// Load and validate the local config (defaults + flags, file)
local, err := cc.loadLocalConfig()
if err != nil {
return nil, err
} // Assert: the default and init configs are both valid
// if dynamic config is disabled, skip trying to load any checkpoints because they won't exist
// if dynamic config is disabled, we just stop here
if !cc.dynamicConfig {
return cc.localConfig(), nil
}
// NOTE(mtaufen): We still need to update the status.
// We expect to be able to disable dynamic config but still get a status update about the config.
// This is because the feature gate covers dynamic config AND config status reporting, while the
// --dynamic-config-dir flag just covers dynamic config.
cc.configOK.Set(status.NotDynamicLocalMessage, status.NotDynamicLocalReason, apiv1.ConditionTrue)
return local, nil
} // Assert: dynamic config is enabled
// assert: now we know that a dynamicConfigDir was provided, and we can rely on that existing
// make sure the filesystem is set up properly
// ensure the filesystem is initialized
if err := cc.initializeDynamicConfigDir(); err != nil {
return nil, err
}
// determine UID of the current config source
curUID := ""
if curSource, err := cc.checkpointStore.Current(); err != nil {
return nil, err
} else if curSource != nil {
curUID = curSource.UID()
}
assigned, curSource, reason, err := cc.loadAssignedConfig(local)
if err == nil {
// set the status to indicate we will use the assigned config
if curSource != nil {
cc.configOK.Set(fmt.Sprintf(status.CurRemoteMessageFmt, curSource.UID()), reason, apiv1.ConditionTrue)
} else {
cc.configOK.Set(status.CurLocalMessage, reason, apiv1.ConditionTrue)
}
// if curUID indicates the local config should be used, return the correct one of those
if len(curUID) == 0 {
return cc.localConfig(), nil
} // Assert: we will not use the local configurations, unless we roll back to lkg; curUID is non-empty
// when the trial period is over, the assigned config becomes the last-known-good
if trial, err := cc.inTrial(assigned.ConfigTrialDuration.Duration); err != nil {
utillog.Errorf("failed to check trial period for assigned config, error: %v", err)
} else if !trial {
utillog.Infof("assigned config passed trial period, will set as last-known-good")
if err := cc.graduateAssignedToLastKnownGood(); err != nil {
utillog.Errorf("failed to set last-known-good to assigned config, error: %v", err)
}
}
// TODO(mtaufen): consider re-verifying integrity and re-attempting download when a load/verify/parse/validate
return assigned, nil
} // Assert: the assigned config failed to load, parse, or validate
// TODO(mtaufen): consider re-attempting download when a load/verify/parse/validate
// error happens outside trial period, we already made it past the trial so it's probably filesystem corruption
// or something else scary (unless someone is using a 0-length trial period)
// load from checkpoint
// load the current config
checkpoint, err := cc.checkpointStore.Load(curUID)
// log the reason and error details for the failure to load the assigned config
utillog.Errorf(fmt.Sprintf("%s, error: %v", reason, err))
// load the last-known-good config
lkg, lkgSource, err := cc.loadLastKnownGoodConfig(local)
if err != nil {
// TODO(mtaufen): rollback for now, but this could reasonably be handled by re-attempting a download,
// it probably indicates some sort of corruption
return cc.lkgRollback(fmt.Sprintf(status.CurFailLoadReasonFmt, curUID), fmt.Sprintf("error: %v", err))
}
// parse the checkpoint into a KubeletConfiguration
cur, err := checkpoint.Parse()
if err != nil {
return cc.lkgRollback(fmt.Sprintf(status.CurFailParseReasonFmt, curUID), fmt.Sprintf("error: %v", err))
}
// validate current config
if err := validation.ValidateKubeletConfiguration(cur); err != nil {
return cc.lkgRollback(fmt.Sprintf(status.CurFailValidateReasonFmt, curUID), fmt.Sprintf("error: %v", err))
}
// when the trial period is over, the current config becomes the last-known-good
if trial, err := cc.inTrial(cur.ConfigTrialDuration.Duration); err != nil {
return nil, err
} else if !trial {
if err := cc.graduateCurrentToLastKnownGood(); err != nil {
return nil, err
}
}
// update the status to note that we will use the current config
cc.configOK.Set(fmt.Sprintf(status.CurRemoteMessageFmt, curUID), status.CurRemoteOKReason, apiv1.ConditionTrue)
return cur, nil
// set the status to indicate that we had to roll back to the lkg for the reason reported when we tried to load the assigned config
if lkgSource != nil {
cc.configOK.Set(fmt.Sprintf(status.LkgRemoteMessageFmt, lkgSource.UID()), reason, apiv1.ConditionFalse)
} else {
cc.configOK.Set(status.LkgLocalMessage, reason, apiv1.ConditionFalse)
}
// return the last-known-good config
return lkg, nil
}
// StartSync launches the controller's sync loops if `client` is non-nil and `nodeName` is non-empty.
@ -243,6 +226,93 @@ func (cc *Controller) StartSync(client clientset.Interface, eventClient v1core.E
}
}
// loadLocalConfig returns the local config: either the defaults provided to the controller or
// a local config file, if the Kubelet is configured to use the local file
func (cc *Controller) loadLocalConfig() (*kubeletconfig.KubeletConfiguration, error) {
// ALWAYS validate the local configs. This makes incorrectly provisioned nodes an error.
// These must be valid because they are the default last-known-good configs.
utillog.Infof("validating combination of defaults and flags")
if err := validation.ValidateKubeletConfiguration(cc.defaultConfig); err != nil {
return nil, fmt.Errorf("combination of defaults and flags failed validation, error: %v", err)
}
// only attempt to load and validate the Kubelet config file if the user provided a path
if cc.fileLoader != nil {
utillog.Infof("loading Kubelet config file")
kc, err := cc.fileLoader.Load()
if err != nil {
return nil, err
}
// validate the Kubelet config file config
utillog.Infof("validating Kubelet config file")
if err := validation.ValidateKubeletConfiguration(kc); err != nil {
return nil, fmt.Errorf("failed to validate the Kubelet config file, error: %v", err)
}
return kc, nil
}
// if no Kubelet config file config, just return the default
return cc.defaultConfig, nil
}
// loadAssignedConfig loads the Kubelet's currently assigned config,
// based on the setting in the local checkpoint store.
// It returns the loaded configuration, the checkpoint store's config source record,
// a clean success or failure reason that can be reported in the status, and any error that occurs.
// If the local config should be used, it will be returned. You should validate local before passing it to this function.
func (cc *Controller) loadAssignedConfig(local *kubeletconfig.KubeletConfiguration) (*kubeletconfig.KubeletConfiguration, checkpoint.RemoteConfigSource, string, error) {
src, err := cc.checkpointStore.Current()
if err != nil {
return nil, nil, fmt.Sprintf(status.CurFailLoadReasonFmt, "unknown"), err
}
// nil source is the signal to use the local config
if src == nil {
return local, src, status.CurLocalOkayReason, nil
}
curUID := src.UID()
// load from checkpoint
checkpoint, err := cc.checkpointStore.Load(curUID)
if err != nil {
return nil, src, fmt.Sprintf(status.CurFailLoadReasonFmt, curUID), err
}
cur, err := checkpoint.Parse()
if err != nil {
return nil, src, fmt.Sprintf(status.CurFailParseReasonFmt, curUID), err
}
if err := validation.ValidateKubeletConfiguration(cur); err != nil {
return nil, src, fmt.Sprintf(status.CurFailValidateReasonFmt, curUID), err
}
return cur, src, status.CurRemoteOkayReason, nil
}
// loadLastKnownGoodConfig loads the Kubelet's last-known-good config,
// based on the setting in the local checkpoint store.
// It returns the loaded configuration, the checkpoint store's config source record,
// and any error that occurs.
// If the local config should be used, it will be returned. You should validate local before passing it to this function.
func (cc *Controller) loadLastKnownGoodConfig(local *kubeletconfig.KubeletConfiguration) (*kubeletconfig.KubeletConfiguration, checkpoint.RemoteConfigSource, error) {
src, err := cc.checkpointStore.LastKnownGood()
if err != nil {
return nil, nil, fmt.Errorf("unable to determine last-known-good config, error: %v", err)
}
// nil source is the signal to use the local config
if src == nil {
return local, src, nil
}
lkgUID := src.UID()
// load from checkpoint
checkpoint, err := cc.checkpointStore.Load(lkgUID)
if err != nil {
return nil, src, fmt.Errorf("%s, error: %v", fmt.Sprintf(status.LkgFailLoadReasonFmt, lkgUID), err)
}
lkg, err := checkpoint.Parse()
if err != nil {
return nil, src, fmt.Errorf("%s, error: %v", fmt.Sprintf(status.LkgFailParseReasonFmt, lkgUID), err)
}
if err := validation.ValidateKubeletConfiguration(lkg); err != nil {
return nil, src, fmt.Errorf("%s, error: %v", fmt.Sprintf(status.LkgFailValidateReasonFmt, lkgUID), err)
}
return lkg, src, nil
}
// initializeDynamicConfigDir makes sure that the storage layers for various controller components are set up correctly
func (cc *Controller) initializeDynamicConfigDir() error {
utillog.Infof("ensuring filesystem is set up correctly")
@ -250,17 +320,6 @@ func (cc *Controller) initializeDynamicConfigDir() error {
return cc.checkpointStore.Initialize()
}
// localConfig returns the initConfig if it is loaded, otherwise returns the defaultConfig.
// It also sets the local configOK condition to match the returned config.
func (cc *Controller) localConfig() *kubeletconfig.KubeletConfiguration {
if cc.initConfig != nil {
cc.configOK.Set(status.CurInitMessage, status.CurInitOKReason, apiv1.ConditionTrue)
return cc.initConfig
}
cc.configOK.Set(status.CurDefaultMessage, status.CurDefaultOKReason, apiv1.ConditionTrue)
return cc.defaultConfig
}
// inTrial returns true if the time elapsed since the last modification of the current config does not exceed `trialDur`, false otherwise
func (cc *Controller) inTrial(trialDur time.Duration) (bool, error) {
now := time.Now()
@ -274,16 +333,16 @@ func (cc *Controller) inTrial(trialDur time.Duration) (bool, error) {
return false, nil
}
// graduateCurrentToLastKnownGood sets the last-known-good UID on the checkpointStore
// graduateAssignedToLastKnownGood sets the last-known-good UID on the checkpointStore
// to the same value as the current UID maintained by the checkpointStore
func (cc *Controller) graduateCurrentToLastKnownGood() error {
func (cc *Controller) graduateAssignedToLastKnownGood() error {
curUID, err := cc.checkpointStore.Current()
if err != nil {
return fmt.Errorf("could not graduate last-known-good config to current config, error: %v", err)
return err
}
err = cc.checkpointStore.SetLastKnownGood(curUID)
if err != nil {
return fmt.Errorf("could not graduate last-known-good config to current config, error: %v", err)
return err
}
return nil
}

View File

@ -1,70 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package kubeletconfig
import (
"fmt"
apiv1 "k8s.io/api/core/v1"
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/validation"
"k8s.io/kubernetes/pkg/kubelet/kubeletconfig/status"
utillog "k8s.io/kubernetes/pkg/kubelet/kubeletconfig/util/log"
)
// lkgRollback returns a valid last-known-good configuration, and updates the `cc.configOK` condition
// regarding the `reason` for the rollback, or returns an error if a valid last-known-good could not be produced
func (cc *Controller) lkgRollback(reason, detail string) (*kubeletconfig.KubeletConfiguration, error) {
utillog.Errorf(fmt.Sprintf("%s, %s", reason, detail))
lkgUID := ""
if lkgSource, err := cc.checkpointStore.LastKnownGood(); err != nil {
return nil, fmt.Errorf("unable to determine last-known-good config, error: %v", err)
} else if lkgSource != nil {
lkgUID = lkgSource.UID()
}
// if lkgUID indicates the default should be used, return initConfig or defaultConfig
if len(lkgUID) == 0 {
if cc.initConfig != nil {
cc.configOK.Set(status.LkgInitMessage, reason, apiv1.ConditionFalse)
return cc.initConfig, nil
}
cc.configOK.Set(status.LkgDefaultMessage, reason, apiv1.ConditionFalse)
return cc.defaultConfig, nil
}
// load
checkpoint, err := cc.checkpointStore.Load(lkgUID)
if err != nil {
return nil, fmt.Errorf("%s, error: %v", fmt.Sprintf(status.LkgFailLoadReasonFmt, lkgUID), err)
}
// parse
lkg, err := checkpoint.Parse()
if err != nil {
return nil, fmt.Errorf("%s, error: %v", fmt.Sprintf(status.LkgFailParseReasonFmt, lkgUID), err)
}
// validate
if err := validation.ValidateKubeletConfiguration(lkg); err != nil {
return nil, fmt.Errorf("%s, error: %v", fmt.Sprintf(status.LkgFailValidateReasonFmt, lkgUID), err)
}
cc.configOK.Set(fmt.Sprintf(status.LkgRemoteMessageFmt, lkgUID), reason, apiv1.ConditionFalse)
return lkg, nil
}

View File

@ -32,28 +32,27 @@ import (
utillog "k8s.io/kubernetes/pkg/kubelet/kubeletconfig/util/log"
)
// TODO(mtaufen): s/current/assigned, as this is more accurate e.g. if you are using lkg, you aren't currently using "current" :)
const (
// CurDefaultMessage indicates the Kubelet is using it's current config, which is the default
CurDefaultMessage = "using current (default)"
// LkgDefaultMessage indicates the Kubelet is using it's last-known-good config, which is the default
LkgDefaultMessage = "using last-known-good (default)"
// NotDynamicLocalMessage indicates that the Kubelet is using its local config - we send this when dynamic Kubelet config is disabled by omitting the --dynamic-config-dir flag
NotDynamicLocalMessage = "using local config"
// NotDynamicLocalReason indicates that the Kubelet is using its local config - we send this when dynamic Kubelet config is disabled by omitting the --dynamic-config-dir flag
NotDynamicLocalReason = "dynamic config is currently disabled by omission of --dynamic-config-dir Kubelet flag"
// CurInitMessage indicates the Kubelet is using it's current config, which is from the init config files
CurInitMessage = "using current (init)"
// LkgInitMessage indicates the Kubelet is using it's last-known-good config, which is from the init config files
LkgInitMessage = "using last-known-good (init)"
// CurLocalMessage indicates that the Kubelet is using its local config, which consists of defaults, flags, and/or local files
CurLocalMessage = "using current (local)"
// LkgLocalMessage indicates that the Kubelet is using its local config, which consists of defaults, flags, and/or local files
LkgLocalMessage = "using last-known-good (local)"
// CurRemoteMessageFmt indicates the Kubelet is usin it's current config, which is from an API source
// CurRemoteMessageFmt indicates the Kubelet is using its current config, which is from an API source
CurRemoteMessageFmt = "using current (UID: %q)"
// LkgRemoteMessageFmt indicates the Kubelet is using it's last-known-good config, which is from an API source
// LkgRemoteMessageFmt indicates the Kubelet is using its last-known-good config, which is from an API source
LkgRemoteMessageFmt = "using last-known-good (UID: %q)"
// CurDefaultOKReason indicates that no init config files were provided
CurDefaultOKReason = "current is set to the local default, and no init config was provided"
// CurInitOKReason indicates that init config files were provided
CurInitOKReason = "current is set to the local default, and an init config was provided"
// CurRemoteOKReason indicates that the config referenced by Node.ConfigSource is currently passing all checks
CurRemoteOKReason = "passing all checks"
// CurLocalOkayReason indicates that the Kubelet is using its local config
CurLocalOkayReason = "when the config source is nil, the Kubelet uses its local config"
// CurRemoteOkayReason indicates that the config referenced by Node.ConfigSource is currently passing all checks
CurRemoteOkayReason = "passing all checks"
// CurFailLoadReasonFmt indicates that the Kubelet failed to load the current config checkpoint for an API source
CurFailLoadReasonFmt = "failed to load current (UID: %q)"
@ -61,8 +60,6 @@ const (
CurFailParseReasonFmt = "failed to parse current (UID: %q)"
// CurFailValidateReasonFmt indicates that the Kubelet failed to validate the current config checkpoint for an API source
CurFailValidateReasonFmt = "failed to validate current (UID: %q)"
// CurFailCrashLoopReasonFmt indicates that the Kubelet experienced a crash loop while using the current config checkpoint for an API source
CurFailCrashLoopReasonFmt = "current failed trial period due to crash loop (UID: %q)"
// LkgFail*ReasonFmt reasons are currently used to print errors in the Kubelet log, but do not appear in Node.Status.Conditions
@ -87,13 +84,13 @@ const (
// FailSyncReasonInformer is used when the informer fails to report the Node object
FailSyncReasonInformer = "failed to read Node from informer object cache"
// FailSyncReasonReset is used when we can't reset the local configuration references, e.g. due to filesystem issues
FailSyncReasonReset = "failed to reset to local (default or init) config"
FailSyncReasonReset = "failed to reset to local config"
// FailSyncReasonCheckpointExistenceFmt is used when we can't determine if a checkpoint already exists, e.g. due to filesystem issues
FailSyncReasonCheckpointExistenceFmt = "failed to determine whether object with UID %q was already checkpointed"
// FailSyncReasonSaveCheckpointFmt is used when we can't save a checkpoint, e.g. due to filesystem issues
FailSyncReasonSaveCheckpointFmt = "failed to save config checkpoint for object with UID %q"
// FailSyncReasonSetCurrentDefault is used when we can't set the current config checkpoint to the local default, e.g. due to filesystem issues
FailSyncReasonSetCurrentDefault = "failed to set current config checkpoint to default"
FailSyncReasonSetCurrentLocal = "failed to set current config checkpoint to local config"
// FailSyncReasonSetCurrentUIDFmt is used when we can't set the current config checkpoint to a checkpointed object, e.g. due to filesystem issues
FailSyncReasonSetCurrentUIDFmt = "failed to set current config checkpoint to object with UID %q"

View File

@ -87,7 +87,7 @@ var _ = framework.KubeDescribe("DynamicKubeletConfiguration [Feature:DynamicKube
Name: originalConfigMap.Name}},
expectConfigOK: &apiv1.NodeCondition{Type: apiv1.NodeConfigOK, Status: apiv1.ConditionTrue,
Message: fmt.Sprintf(status.CurRemoteMessageFmt, originalConfigMap.UID),
Reason: status.CurRemoteOKReason},
Reason: status.CurRemoteOkayReason},
expectConfig: originalKC,
}, false)
})
@ -126,8 +126,8 @@ var _ = framework.KubeDescribe("DynamicKubeletConfiguration [Feature:DynamicKube
{desc: "Node.Spec.ConfigSource is nil",
configSource: nil,
expectConfigOK: &apiv1.NodeCondition{Type: apiv1.NodeConfigOK, Status: apiv1.ConditionTrue,
Message: status.CurDefaultMessage,
Reason: status.CurDefaultOKReason},
Message: status.CurLocalMessage,
Reason: status.CurLocalOkayReason},
expectConfig: nil,
event: true,
},
@ -175,7 +175,7 @@ var _ = framework.KubeDescribe("DynamicKubeletConfiguration [Feature:DynamicKube
Name: correctConfigMap.Name}},
expectConfigOK: &apiv1.NodeCondition{Type: apiv1.NodeConfigOK, Status: apiv1.ConditionTrue,
Message: fmt.Sprintf(status.CurRemoteMessageFmt, correctConfigMap.UID),
Reason: status.CurRemoteOKReason},
Reason: status.CurRemoteOkayReason},
expectConfig: correctKC,
event: true,
},
@ -187,7 +187,7 @@ var _ = framework.KubeDescribe("DynamicKubeletConfiguration [Feature:DynamicKube
Namespace: failParseConfigMap.Namespace,
Name: failParseConfigMap.Name}},
expectConfigOK: &apiv1.NodeCondition{Type: apiv1.NodeConfigOK, Status: apiv1.ConditionFalse,
Message: status.LkgDefaultMessage,
Message: status.LkgLocalMessage,
Reason: fmt.Sprintf(status.CurFailParseReasonFmt, failParseConfigMap.UID)},
expectConfig: nil,
event: true,
@ -200,7 +200,7 @@ var _ = framework.KubeDescribe("DynamicKubeletConfiguration [Feature:DynamicKube
Namespace: failValidateConfigMap.Namespace,
Name: failValidateConfigMap.Name}},
expectConfigOK: &apiv1.NodeCondition{Type: apiv1.NodeConfigOK, Status: apiv1.ConditionFalse,
Message: status.LkgDefaultMessage,
Message: status.LkgLocalMessage,
Reason: fmt.Sprintf(status.CurFailValidateReasonFmt, failValidateConfigMap.UID)},
expectConfig: nil,
event: true,
@ -245,7 +245,7 @@ var _ = framework.KubeDescribe("DynamicKubeletConfiguration [Feature:DynamicKube
Name: lkgConfigMap.Name}},
expectConfigOK: &apiv1.NodeCondition{Type: apiv1.NodeConfigOK, Status: apiv1.ConditionTrue,
Message: fmt.Sprintf(status.CurRemoteMessageFmt, lkgConfigMap.UID),
Reason: status.CurRemoteOKReason},
Reason: status.CurRemoteOkayReason},
expectConfig: lkgKC,
event: true,
},
@ -295,10 +295,11 @@ var _ = framework.KubeDescribe("DynamicKubeletConfiguration [Feature:DynamicKube
Name: cm1.Name}},
expectConfigOK: &apiv1.NodeCondition{Type: apiv1.NodeConfigOK, Status: apiv1.ConditionTrue,
Message: fmt.Sprintf(status.CurRemoteMessageFmt, cm1.UID),
Reason: status.CurRemoteOKReason},
Reason: status.CurRemoteOkayReason},
expectConfig: kc1,
event: true,
},
{desc: "cm2",
configSource: &apiv1.NodeConfigSource{ConfigMapRef: &apiv1.ObjectReference{
UID: cm2.UID,
@ -306,7 +307,7 @@ var _ = framework.KubeDescribe("DynamicKubeletConfiguration [Feature:DynamicKube
Name: cm2.Name}},
expectConfigOK: &apiv1.NodeCondition{Type: apiv1.NodeConfigOK, Status: apiv1.ConditionTrue,
Message: fmt.Sprintf(status.CurRemoteMessageFmt, cm2.UID),
Reason: status.CurRemoteOKReason},
Reason: status.CurRemoteOkayReason},
expectConfig: kc2,
event: true,
},