mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 03:11:40 +00:00
Merge remote-tracking branch 'upstream/master' into test-cmd-what
This commit is contained in:
commit
4fc5be8d5a
189
Godeps/Godeps.json
generated
189
Godeps/Godeps.json
generated
@ -201,178 +201,193 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/awserr",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/awsutil",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/client",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/client/metadata",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/corehandlers",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials/endpointcreds",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials/processcreds",
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials/stscreds",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/csm",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/defaults",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/ec2metadata",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/endpoints",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/request",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/session",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/signer/v4",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/internal/ini",
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/internal/sdkio",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/internal/sdkrand",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/internal/sdkuri",
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/internal/shareddefaults",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/ec2query",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/jsonrpc",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/query",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/query/queryutil",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/rest",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/autoscaling",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/ec2",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/ecr",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/elb",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/elbv2",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/kms",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/sts",
|
||||
"Comment": "v1.14.12",
|
||||
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
|
||||
"Comment": "v1.16.26",
|
||||
"Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/bazelbuild/bazel-gazelle/cmd/gazelle",
|
||||
@ -2080,7 +2095,7 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/gofuzz",
|
||||
"Rev": "44d81051d367757e1c7c6a5a86423ece9afcf63c"
|
||||
"Rev": "24818f796faf91cd76ec7bddd72458fbced7a6c1"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/uuid",
|
||||
@ -2998,8 +3013,8 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/quobyte/api",
|
||||
"Comment": "v0.1.1-4-g206ef832283c1a",
|
||||
"Rev": "206ef832283c1a0144bbc762be2634d49987b5ff"
|
||||
"Comment": "v0.1.2",
|
||||
"Rev": "9cfd29338dd9fdaaf956b7082e5550aab5fe3841"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/rancher/go-rancher/client",
|
||||
@ -4068,6 +4083,10 @@
|
||||
"ImportPath": "k8s.io/kube-openapi/pkg/handler",
|
||||
"Rev": "ced9eb3070a5f1c548ef46e8dfe2a97c208d9f03"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/kube-openapi/pkg/schemaconv",
|
||||
"Rev": "ced9eb3070a5f1c548ef46e8dfe2a97c208d9f03"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/kube-openapi/pkg/util",
|
||||
"Rev": "ced9eb3070a5f1c548ef46e8dfe2a97c208d9f03"
|
||||
@ -4120,6 +4139,10 @@
|
||||
"ImportPath": "k8s.io/utils/keymutex",
|
||||
"Rev": "ed37f7428a91fc2a81070808937195dcd46d320e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/utils/net",
|
||||
"Rev": "ed37f7428a91fc2a81070808937195dcd46d320e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/utils/nsenter",
|
||||
"Rev": "ed37f7428a91fc2a81070808937195dcd46d320e"
|
||||
@ -4140,6 +4163,26 @@
|
||||
"ImportPath": "k8s.io/utils/trace",
|
||||
"Rev": "ed37f7428a91fc2a81070808937195dcd46d320e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/structured-merge-diff/fieldpath",
|
||||
"Rev": "e5e029740eb81ee0217ecf9d950c25a0eeb9688a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/structured-merge-diff/merge",
|
||||
"Rev": "e5e029740eb81ee0217ecf9d950c25a0eeb9688a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/structured-merge-diff/schema",
|
||||
"Rev": "e5e029740eb81ee0217ecf9d950c25a0eeb9688a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/structured-merge-diff/typed",
|
||||
"Rev": "e5e029740eb81ee0217ecf9d950c25a0eeb9688a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/structured-merge-diff/value",
|
||||
"Rev": "e5e029740eb81ee0217ecf9d950c25a0eeb9688a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/yaml",
|
||||
"Comment": "v1.1.0",
|
||||
|
2095
Godeps/LICENSES
generated
2095
Godeps/LICENSES
generated
File diff suppressed because it is too large
Load Diff
879
api/openapi-spec/swagger.json
generated
879
api/openapi-spec/swagger.json
generated
File diff suppressed because it is too large
Load Diff
@ -1343,6 +1343,11 @@ EOF
|
||||
if [ -n "${ADDON_MANAGER_LEADER_ELECTION:-}" ]; then
|
||||
cat >>$file <<EOF
|
||||
ADDON_MANAGER_LEADER_ELECTION: $(yaml-quote ${ADDON_MANAGER_LEADER_ELECTION})
|
||||
EOF
|
||||
fi
|
||||
if [ -n "${API_SERVER_TEST_LOG_LEVEL:-}" ]; then
|
||||
cat >>$file <<EOF
|
||||
API_SERVER_TEST_LOG_LEVEL: $(yaml-quote ${API_SERVER_TEST_LOG_LEVEL})
|
||||
EOF
|
||||
fi
|
||||
|
||||
|
@ -51,6 +51,7 @@ readonly kern_logfile="kern.log"
|
||||
readonly initd_logfiles="docker/log"
|
||||
readonly supervisord_logfiles="kubelet.log supervisor/supervisord.log supervisor/kubelet-stdout.log supervisor/kubelet-stderr.log supervisor/docker-stdout.log supervisor/docker-stderr.log"
|
||||
readonly systemd_services="kubelet kubelet-monitor kube-container-runtime-monitor ${LOG_DUMP_SYSTEMD_SERVICES:-docker}"
|
||||
readonly dump_systemd_journal="${LOG_DUMP_SYSTEMD_JOURNAL:-false}"
|
||||
|
||||
# Limit the number of concurrent node connections so that we don't run out of
|
||||
# file descriptors for large clusters.
|
||||
@ -164,6 +165,10 @@ function save-logs() {
|
||||
for svc in "${services[@]}"; do
|
||||
log-dump-ssh "${node_name}" "sudo journalctl --output=cat -u ${svc}.service" > "${dir}/${svc}.log" || true
|
||||
done
|
||||
|
||||
if [[ "$dump_systemd_journal" == "true" ]]; then
|
||||
log-dump-ssh "${node_name}" "sudo journalctl --output=short-precise" > "${dir}/systemd.log" || true
|
||||
fi
|
||||
else
|
||||
files="${kern_logfile} ${files} ${initd_logfiles} ${supervisord_logfiles}"
|
||||
fi
|
||||
|
@ -212,11 +212,6 @@ func (s *ServerRunOptions) Flags() (fss apiserverflag.NamedFlagSets) {
|
||||
fs.StringVar(&s.KubeletConfig.CAFile, "kubelet-certificate-authority", s.KubeletConfig.CAFile,
|
||||
"Path to a cert file for the certificate authority.")
|
||||
|
||||
// TODO: delete this flag in 1.13
|
||||
repair := false
|
||||
fs.BoolVar(&repair, "repair-malformed-updates", false, "deprecated")
|
||||
fs.MarkDeprecated("repair-malformed-updates", "This flag will be removed in a future version")
|
||||
|
||||
fs.StringVar(&s.ProxyClientCertFile, "proxy-client-cert-file", s.ProxyClientCertFile, ""+
|
||||
"Client certificate used to prove the identity of the aggregator or kube-apiserver "+
|
||||
"when it must call out during a request. This includes proxying requests to a user "+
|
||||
|
@ -36,6 +36,7 @@ import (
|
||||
cacheddiscovery "k8s.io/client-go/discovery/cached"
|
||||
"k8s.io/client-go/dynamic"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
csiclientset "k8s.io/csi-api/pkg/client/clientset/versioned"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
cloudcontroller "k8s.io/kubernetes/pkg/controller/cloud"
|
||||
@ -331,6 +332,10 @@ func startNamespaceController(ctx ControllerContext) (http.Handler, bool, error)
|
||||
nsKubeconfig.QPS *= 20
|
||||
nsKubeconfig.Burst *= 100
|
||||
namespaceKubeClient := clientset.NewForConfigOrDie(nsKubeconfig)
|
||||
return startModifiedNamespaceController(ctx, namespaceKubeClient, nsKubeconfig)
|
||||
}
|
||||
|
||||
func startModifiedNamespaceController(ctx ControllerContext, namespaceKubeClient clientset.Interface, nsKubeconfig *restclient.Config) (http.Handler, bool, error) {
|
||||
|
||||
dynamicClient, err := dynamic.NewForConfig(nsKubeconfig)
|
||||
if err != nil {
|
||||
|
@ -17,6 +17,7 @@ limitations under the License.
|
||||
package app
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -34,8 +35,11 @@ type TestClientBuilder struct {
|
||||
clientset clientset.Interface
|
||||
}
|
||||
|
||||
func (TestClientBuilder) Config(name string) (*restclient.Config, error) { return nil, nil }
|
||||
func (TestClientBuilder) ConfigOrDie(name string) *restclient.Config { return nil }
|
||||
func (TestClientBuilder) Config(name string) (*restclient.Config, error) { return nil, nil }
|
||||
func (TestClientBuilder) ConfigOrDie(name string) *restclient.Config {
|
||||
return &restclient.Config{}
|
||||
}
|
||||
|
||||
func (TestClientBuilder) Client(name string) (clientset.Interface, error) { return nil, nil }
|
||||
func (m TestClientBuilder) ClientOrDie(name string) clientset.Interface {
|
||||
return m.clientset
|
||||
@ -62,6 +66,10 @@ func (c *FakeClientSet) Discovery() discovery.DiscoveryInterface {
|
||||
return c.DiscoveryObj
|
||||
}
|
||||
|
||||
func (c *FakeClientSet) GetPossibleResources() []*metav1.APIResourceList {
|
||||
return c.DiscoveryObj.PossibleResources
|
||||
}
|
||||
|
||||
// Create a fake Clientset with its Discovery method overridden.
|
||||
func NewFakeClientset(fakeDiscovery FakeDiscoveryWithError) *FakeClientSet {
|
||||
cs := &FakeClientSet{}
|
||||
@ -69,7 +77,30 @@ func NewFakeClientset(fakeDiscovery FakeDiscoveryWithError) *FakeClientSet {
|
||||
return cs
|
||||
}
|
||||
|
||||
func TestStartResourceQuotaController_DiscoveryError(t *testing.T) {
|
||||
func possibleDiscoveryResource() []*metav1.APIResourceList {
|
||||
return []*metav1.APIResourceList{
|
||||
{
|
||||
GroupVersion: "create/v1",
|
||||
APIResources: []metav1.APIResource{
|
||||
{
|
||||
Name: "jobs",
|
||||
Verbs: []string{"create", "list", "watch", "delete"},
|
||||
ShortNames: []string{"jz"},
|
||||
Categories: []string{"all"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type controllerInitFunc func(ControllerContext) (http.Handler, bool, error)
|
||||
|
||||
func TestController_DiscoveryError(t *testing.T) {
|
||||
controllerInitFuncMap := map[string]controllerInitFunc{
|
||||
"ResourceQuotaController": startResourceQuotaController,
|
||||
"GarbageCollectorController": startGarbageCollectorController,
|
||||
}
|
||||
|
||||
tcs := map[string]struct {
|
||||
discoveryError error
|
||||
expectedErr bool
|
||||
@ -77,25 +108,13 @@ func TestStartResourceQuotaController_DiscoveryError(t *testing.T) {
|
||||
}{
|
||||
"No Discovery Error": {
|
||||
discoveryError: nil,
|
||||
possibleResources: nil,
|
||||
possibleResources: possibleDiscoveryResource(),
|
||||
expectedErr: false,
|
||||
},
|
||||
"Discovery Calls Partially Failed": {
|
||||
discoveryError: new(discovery.ErrGroupDiscoveryFailed),
|
||||
possibleResources: []*metav1.APIResourceList{
|
||||
{
|
||||
GroupVersion: "create/v1",
|
||||
APIResources: []metav1.APIResource{
|
||||
{
|
||||
Name: "jobs",
|
||||
Verbs: []string{"create", "list", "watch", "delete"},
|
||||
ShortNames: []string{"jz"},
|
||||
Categories: []string{"all"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedErr: false,
|
||||
discoveryError: new(discovery.ErrGroupDiscoveryFailed),
|
||||
possibleResources: possibleDiscoveryResource(),
|
||||
expectedErr: false,
|
||||
},
|
||||
}
|
||||
for name, test := range tcs {
|
||||
@ -107,9 +126,16 @@ func TestStartResourceQuotaController_DiscoveryError(t *testing.T) {
|
||||
InformerFactory: informers.NewSharedInformerFactoryWithOptions(testClientset, time.Duration(1)),
|
||||
InformersStarted: make(chan struct{}),
|
||||
}
|
||||
_, _, err := startResourceQuotaController(ctx)
|
||||
for funcName, controllerInit := range controllerInitFuncMap {
|
||||
_, _, err := controllerInit(ctx)
|
||||
if test.expectedErr != (err != nil) {
|
||||
t.Errorf("%v test failed for use case: %v", funcName, name)
|
||||
}
|
||||
}
|
||||
_, _, err := startModifiedNamespaceController(
|
||||
ctx, testClientset, testClientBuilder.ConfigOrDie("namespace-controller"))
|
||||
if test.expectedErr != (err != nil) {
|
||||
t.Errorf("test failed for use case: %v", name)
|
||||
t.Errorf("Namespace Controller test failed for use case: %v", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,8 @@
|
||||
"k8s.io/utils/exec",
|
||||
"k8s.io/utils/integer",
|
||||
"k8s.io/utils/path",
|
||||
"k8s.io/utils/pointer"
|
||||
"k8s.io/utils/pointer",
|
||||
"k8s.io/utils/net"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -82,7 +83,6 @@
|
||||
"k8s.io/kubernetes/pkg/util/initsystem",
|
||||
"k8s.io/kubernetes/pkg/util/ipvs",
|
||||
"k8s.io/kubernetes/pkg/util/metrics",
|
||||
"k8s.io/kubernetes/pkg/util/net/sets",
|
||||
"k8s.io/kubernetes/pkg/util/node",
|
||||
"k8s.io/kubernetes/pkg/util/normalizer",
|
||||
"k8s.io/kubernetes/pkg/util/parsers",
|
||||
|
@ -28,6 +28,8 @@ go_library(
|
||||
"//cmd/kubeadm/app/cmd/alpha:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd/options:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd/phases:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd/phases/init:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd/phases/join:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd/phases/workflow:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd/upgrade:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd/util:go_default_library",
|
||||
@ -38,7 +40,6 @@ go_library(
|
||||
"//cmd/kubeadm/app/images:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/bootstraptoken/node:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/certs:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/controlplane:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/etcd:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/kubelet:go_default_library",
|
||||
|
@ -7,7 +7,6 @@ go_library(
|
||||
"certs.go",
|
||||
"kubeconfig.go",
|
||||
"kubelet.go",
|
||||
"preflight.go",
|
||||
"selfhosting.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/cmd/alpha",
|
||||
|
@ -33,7 +33,6 @@ func NewCmdAlpha(in io.Reader, out io.Writer) *cobra.Command {
|
||||
cmd.AddCommand(newCmdCertsUtility())
|
||||
cmd.AddCommand(newCmdKubeletUtility())
|
||||
cmd.AddCommand(newCmdKubeConfigUtility(out))
|
||||
cmd.AddCommand(newCmdPreFlightUtility())
|
||||
cmd.AddCommand(NewCmdSelfhosting(in))
|
||||
|
||||
// TODO: This command should be removed as soon as the kubeadm init phase refactoring is completed.
|
||||
|
@ -1,103 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 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 alpha
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme"
|
||||
kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
|
||||
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
||||
"k8s.io/kubernetes/pkg/util/normalizer"
|
||||
utilsexec "k8s.io/utils/exec"
|
||||
)
|
||||
|
||||
var (
|
||||
nodePreflightLongDesc = normalizer.LongDesc(`
|
||||
Run node pre-flight checks, functionally equivalent to what implemented by kubeadm join.
|
||||
` + cmdutil.AlphaDisclaimer)
|
||||
|
||||
nodePreflightExample = normalizer.Examples(`
|
||||
# Run node pre-flight checks.
|
||||
kubeadm alpha preflight node
|
||||
`)
|
||||
|
||||
errorMissingConfigFlag = errors.New("the --config flag is mandatory")
|
||||
)
|
||||
|
||||
// newCmdPreFlightUtility calls cobra.Command for preflight checks
|
||||
func newCmdPreFlightUtility() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "preflight",
|
||||
Short: "Commands related to pre-flight checks",
|
||||
Long: cmdutil.MacroCommandLongDescription,
|
||||
}
|
||||
|
||||
cmd.AddCommand(newCmdPreFlightNode())
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// newCmdPreFlightNode calls cobra.Command for node preflight checks
|
||||
func newCmdPreFlightNode() *cobra.Command {
|
||||
var cfgPath string
|
||||
var ignorePreflightErrors []string
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "node",
|
||||
Short: "Run node pre-flight checks",
|
||||
Long: nodePreflightLongDesc,
|
||||
Example: nodePreflightExample,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if len(cfgPath) == 0 {
|
||||
kubeadmutil.CheckErr(errorMissingConfigFlag)
|
||||
}
|
||||
ignorePreflightErrorsSet, err := validation.ValidateIgnorePreflightErrors(ignorePreflightErrors)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
cfg := &kubeadmapiv1beta1.JoinConfiguration{}
|
||||
kubeadmscheme.Scheme.Default(cfg)
|
||||
|
||||
internalcfg, err := configutil.JoinConfigFileAndDefaultsToInternalConfig(cfgPath, cfg)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
if internalcfg.ControlPlane != nil {
|
||||
err = configutil.VerifyAPIServerBindAddress(internalcfg.ControlPlane.LocalAPIEndpoint.AdvertiseAddress)
|
||||
kubeadmutil.CheckErr(err)
|
||||
}
|
||||
|
||||
fmt.Println("[preflight] running pre-flight checks")
|
||||
|
||||
err = preflight.RunJoinNodeChecks(utilsexec.New(), internalcfg, ignorePreflightErrorsSet)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
fmt.Println("[preflight] pre-flight checks passed")
|
||||
},
|
||||
}
|
||||
|
||||
options.AddConfigFlag(cmd.PersistentFlags(), &cfgPath)
|
||||
options.AddIgnorePreflightErrorsFlag(cmd.PersistentFlags(), &ignorePreflightErrors)
|
||||
|
||||
return cmd
|
||||
}
|
@ -141,7 +141,7 @@ func getSelfhostingSubCommand(in io.Reader) *cobra.Command {
|
||||
// Add flags to the command
|
||||
// flags bound to the configuration object
|
||||
cmd.Flags().StringVar(&cfg.CertificatesDir, "cert-dir", cfg.CertificatesDir, `The path where certificates are stored`)
|
||||
cmd.Flags().StringVar(&cfgPath, "config", cfgPath, "Path to a kubeadm config file. WARNING: Usage of a configuration file is experimental")
|
||||
options.AddConfigFlag(cmd.Flags(), &cfgPath)
|
||||
|
||||
cmd.Flags().BoolVarP(
|
||||
&certsInSecrets, "store-certs-in-secrets", "s",
|
||||
|
@ -329,7 +329,7 @@ func NewCmdConfigUploadFromFile(out io.Writer, kubeConfigFile *string) *cobra.Co
|
||||
kubeadmutil.CheckErr(err)
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringVar(&cfgPath, "config", "", "Path to a kubeadm config file. WARNING: Usage of a configuration file is experimental.")
|
||||
options.AddConfigFlag(cmd.Flags(), &cfgPath)
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ import (
|
||||
kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases"
|
||||
phases "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/init"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow"
|
||||
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
@ -168,7 +168,7 @@ func NewCmdInit(out io.Writer, initOptions *initOptions) *cobra.Command {
|
||||
})
|
||||
|
||||
// initialize the workflow runner with the list of phases
|
||||
initRunner.AppendPhase(phases.NewPreflightMasterPhase())
|
||||
initRunner.AppendPhase(phases.NewPreflightPhase())
|
||||
initRunner.AppendPhase(phases.NewKubeletStartPhase())
|
||||
initRunner.AppendPhase(phases.NewCertsPhase())
|
||||
initRunner.AppendPhase(phases.NewKubeConfigPhase())
|
||||
@ -238,10 +238,7 @@ func AddInitConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiv1beta1.InitConfig
|
||||
|
||||
// AddInitOtherFlags adds init flags that are not bound to a configuration file to the given flagset
|
||||
func AddInitOtherFlags(flagSet *flag.FlagSet, cfgPath *string, skipTokenPrint, dryRun *bool, ignorePreflightErrors *[]string) {
|
||||
flagSet.StringVar(
|
||||
cfgPath, options.CfgPath, *cfgPath,
|
||||
"Path to kubeadm config file. WARNING: Usage of a configuration file is experimental.",
|
||||
)
|
||||
options.AddConfigFlag(flagSet, cfgPath)
|
||||
flagSet.StringSliceVar(
|
||||
ignorePreflightErrors, options.IgnorePreflightErrors, *ignorePreflightErrors,
|
||||
"A list of checks whose errors will be shown as warnings. Example: 'IsPrivilegedUser,Swap'. Value 'all' ignores errors from all checks.",
|
||||
|
@ -29,6 +29,7 @@ import (
|
||||
flag "github.com/spf13/pflag"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
certutil "k8s.io/client-go/util/cert"
|
||||
"k8s.io/klog"
|
||||
@ -37,15 +38,12 @@ import (
|
||||
kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases"
|
||||
phases "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/join"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow"
|
||||
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/discovery"
|
||||
certsphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs"
|
||||
controlplanephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/controlplane"
|
||||
etcdphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/etcd"
|
||||
kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
|
||||
kubeletphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubelet"
|
||||
markcontrolplanephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/markcontrolplane"
|
||||
patchnodephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/patchnode"
|
||||
@ -161,6 +159,7 @@ type joinData struct {
|
||||
cfg *kubeadmapi.JoinConfiguration
|
||||
initCfg *kubeadmapi.InitConfiguration
|
||||
tlsBootstrapCfg *clientcmdapi.Config
|
||||
clientSets map[string]*clientset.Clientset
|
||||
ignorePreflightErrors sets.String
|
||||
outputWriter io.Writer
|
||||
}
|
||||
@ -199,7 +198,9 @@ func NewCmdJoin(out io.Writer, joinOptions *joinOptions) *cobra.Command {
|
||||
addJoinConfigFlags(cmd.Flags(), joinOptions.externalcfg)
|
||||
addJoinOtherFlags(cmd.Flags(), &joinOptions.cfgPath, &joinOptions.ignorePreflightErrors, &joinOptions.controlPlane, &joinOptions.token)
|
||||
|
||||
joinRunner.AppendPhase(phases.NewPreflightJoinPhase())
|
||||
joinRunner.AppendPhase(phases.NewPreflightPhase())
|
||||
joinRunner.AppendPhase(phases.NewControlPlanePreparePhase())
|
||||
joinRunner.AppendPhase(phases.NewCheckEtcdPhase())
|
||||
|
||||
// sets the data builder function, that will be used by the runner
|
||||
// both when running the entire workflow or single phases
|
||||
@ -373,6 +374,7 @@ func newJoinData(cmd *cobra.Command, args []string, options *joinOptions, out io
|
||||
|
||||
return &joinData{
|
||||
cfg: cfg,
|
||||
clientSets: map[string]*clientset.Clientset{},
|
||||
ignorePreflightErrors: ignorePreflightErrorsSet,
|
||||
outputWriter: out,
|
||||
}, nil
|
||||
@ -408,6 +410,18 @@ func (j *joinData) InitCfg() (*kubeadmapi.InitConfiguration, error) {
|
||||
return initCfg, err
|
||||
}
|
||||
|
||||
func (j *joinData) ClientSetFromFile(path string) (*clientset.Clientset, error) {
|
||||
if client, ok := j.clientSets[path]; ok {
|
||||
return client, nil
|
||||
}
|
||||
client, err := kubeconfigutil.ClientSetFromFile(path)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "[join] couldn't create Kubernetes client")
|
||||
}
|
||||
j.clientSets[path] = client
|
||||
return client, nil
|
||||
}
|
||||
|
||||
// IgnorePreflightErrors returns the list of preflight errors to ignore.
|
||||
func (j *joinData) IgnorePreflightErrors() sets.String {
|
||||
return j.ignorePreflightErrors
|
||||
@ -432,13 +446,6 @@ func (j *joinData) Run() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if j.cfg.ControlPlane != nil {
|
||||
// Prepares the node for hosting a new control plane instance by writing necessary
|
||||
// kubeconfig files, and static pod manifests
|
||||
if err := j.PrepareForHostingControlPlane(initCfg); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Executes the kubelet TLS bootstrap process, that completes with the node
|
||||
// joining the cluster with a dedicates set of credentials as required by
|
||||
@ -478,47 +485,6 @@ func (j *joinData) Run() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// PrepareForHostingControlPlane makes all preparation activities require for a node hosting a new control plane instance
|
||||
func (j *joinData) PrepareForHostingControlPlane(initConfiguration *kubeadmapi.InitConfiguration) error {
|
||||
|
||||
// Generate missing certificates (if any)
|
||||
if err := certsphase.CreatePKIAssets(initConfiguration); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Generate kubeconfig files for controller manager, scheduler and for the admin/kubeadm itself
|
||||
// NB. The kubeconfig file for kubelet will be generated by the TLS bootstrap process in
|
||||
// following steps of the join --experimental-control plane workflow
|
||||
if err := kubeconfigphase.CreateJoinControlPlaneKubeConfigFiles(kubeadmconstants.KubernetesDir, initConfiguration); err != nil {
|
||||
return errors.Wrap(err, "error generating kubeconfig files")
|
||||
}
|
||||
|
||||
// Creates static pod manifests file for the control plane components to be deployed on this node
|
||||
// Static pods will be created and managed by the kubelet as soon as it starts
|
||||
if err := controlplanephase.CreateInitStaticPodManifestFiles(kubeadmconstants.GetStaticPodDirectory(), initConfiguration); err != nil {
|
||||
return errors.Wrap(err, "error creating static pod manifest files for the control plane components")
|
||||
}
|
||||
|
||||
// in case of local etcd
|
||||
if initConfiguration.Etcd.External == nil {
|
||||
// Checks that the etcd cluster is healthy
|
||||
// NB. this check cannot be implemented before because it requires the admin.conf and all the certificates
|
||||
// for connecting to etcd already in place
|
||||
kubeConfigFile := filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.AdminKubeConfigFileName)
|
||||
|
||||
client, err := kubeconfigutil.ClientSetFromFile(kubeConfigFile)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "couldn't create Kubernetes client")
|
||||
}
|
||||
|
||||
if err := etcdphase.CheckLocalEtcdClusterStatus(client, &initConfiguration.ClusterConfiguration); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// BootstrapKubelet executes the kubelet TLS bootstrap process.
|
||||
// This process is executed by the kubelet and completes with the node joining the cluster
|
||||
// with a dedicates set of credentials as required by the node authorizer
|
||||
|
@ -2,77 +2,22 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"addons.go",
|
||||
"bootstraptoken.go",
|
||||
"certs.go",
|
||||
"controlplane.go",
|
||||
"etcd.go",
|
||||
"kubeconfig.go",
|
||||
"kubelet.go",
|
||||
"markcontrolplane.go",
|
||||
"preflight.go",
|
||||
"uploadconfig.go",
|
||||
"util.go",
|
||||
"waitcontrolplane.go",
|
||||
],
|
||||
srcs = ["util.go"],
|
||||
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//cmd/kubeadm/app/apis/kubeadm/scheme:go_default_library",
|
||||
"//cmd/kubeadm/app/apis/kubeadm/v1beta1:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd/options:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd/phases/workflow:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd/util:go_default_library",
|
||||
"//cmd/kubeadm/app/constants:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/addons/dns:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/addons/proxy:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/bootstraptoken/clusterinfo:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/bootstraptoken/node:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/certs:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/controlplane:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/etcd:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/kubelet:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/markcontrolplane:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/patchnode:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/uploadconfig:go_default_library",
|
||||
"//cmd/kubeadm/app/preflight:go_default_library",
|
||||
"//cmd/kubeadm/app/util:go_default_library",
|
||||
"//cmd/kubeadm/app/util/apiclient:go_default_library",
|
||||
"//cmd/kubeadm/app/util/dryrun:go_default_library",
|
||||
"//cmd/kubeadm/app/util/pkiutil:go_default_library",
|
||||
"//pkg/util/normalizer:go_default_library",
|
||||
"//pkg/version:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//vendor/github.com/lithammer/dedent:go_default_library",
|
||||
"//vendor/github.com/pkg/errors:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"certs_test.go",
|
||||
"util_test.go",
|
||||
],
|
||||
srcs = ["util_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//cmd/kubeadm/app/apis/kubeadm/v1beta1:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd/phases/workflow:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/certs:go_default_library",
|
||||
"//cmd/kubeadm/app/util/certs:go_default_library",
|
||||
"//cmd/kubeadm/app/util/pkiutil:go_default_library",
|
||||
"//cmd/kubeadm/test:go_default_library",
|
||||
"//pkg/version:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@ -87,6 +32,8 @@ filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//cmd/kubeadm/app/cmd/phases/init:all-srcs",
|
||||
"//cmd/kubeadm/app/cmd/phases/join:all-srcs",
|
||||
"//cmd/kubeadm/app/cmd/phases/workflow:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
|
84
cmd/kubeadm/app/cmd/phases/init/BUILD
Normal file
84
cmd/kubeadm/app/cmd/phases/init/BUILD
Normal file
@ -0,0 +1,84 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"addons.go",
|
||||
"bootstraptoken.go",
|
||||
"certs.go",
|
||||
"controlplane.go",
|
||||
"etcd.go",
|
||||
"kubeconfig.go",
|
||||
"kubelet.go",
|
||||
"markcontrolplane.go",
|
||||
"preflight.go",
|
||||
"uploadconfig.go",
|
||||
"waitcontrolplane.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/init",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//cmd/kubeadm/app/apis/kubeadm/scheme:go_default_library",
|
||||
"//cmd/kubeadm/app/apis/kubeadm/v1beta1:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd/options:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd/phases/workflow:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd/util:go_default_library",
|
||||
"//cmd/kubeadm/app/constants:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/addons/dns:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/addons/proxy:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/bootstraptoken/clusterinfo:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/bootstraptoken/node:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/certs:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/controlplane:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/etcd:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/kubelet:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/markcontrolplane:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/patchnode:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/uploadconfig:go_default_library",
|
||||
"//cmd/kubeadm/app/preflight:go_default_library",
|
||||
"//cmd/kubeadm/app/util:go_default_library",
|
||||
"//cmd/kubeadm/app/util/apiclient:go_default_library",
|
||||
"//cmd/kubeadm/app/util/dryrun:go_default_library",
|
||||
"//cmd/kubeadm/app/util/pkiutil:go_default_library",
|
||||
"//pkg/util/normalizer:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//vendor/github.com/lithammer/dedent:go_default_library",
|
||||
"//vendor/github.com/pkg/errors:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["certs_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd/phases/workflow:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/certs:go_default_library",
|
||||
"//cmd/kubeadm/app/util/certs:go_default_library",
|
||||
"//cmd/kubeadm/app/util/pkiutil:go_default_library",
|
||||
"//cmd/kubeadm/test:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
@ -32,7 +32,7 @@ import (
|
||||
|
||||
var (
|
||||
controlPlaneExample = normalizer.Examples(`
|
||||
# Generates all static Pod manifest files for control plane components,
|
||||
# Generates all static Pod manifest files for control plane components,
|
||||
# functionally equivalent to what is generated by kubeadm init.
|
||||
kubeadm init phase control-plane all
|
||||
|
||||
@ -83,20 +83,20 @@ func NewControlPlanePhase() workflow.Phase {
|
||||
Example: controlPlaneExample,
|
||||
RunAllSiblings: true,
|
||||
},
|
||||
newControlPlaneSubPhase(kubeadmconstants.KubeAPIServer),
|
||||
newControlPlaneSubPhase(kubeadmconstants.KubeControllerManager),
|
||||
newControlPlaneSubPhase(kubeadmconstants.KubeScheduler),
|
||||
newControlPlaneSubphase(kubeadmconstants.KubeAPIServer),
|
||||
newControlPlaneSubphase(kubeadmconstants.KubeControllerManager),
|
||||
newControlPlaneSubphase(kubeadmconstants.KubeScheduler),
|
||||
},
|
||||
Run: runControlPlanePhase,
|
||||
}
|
||||
return phase
|
||||
}
|
||||
|
||||
func newControlPlaneSubPhase(component string) workflow.Phase {
|
||||
func newControlPlaneSubphase(component string) workflow.Phase {
|
||||
phase := workflow.Phase{
|
||||
Name: controlPlanePhaseProperties[component].name,
|
||||
Short: controlPlanePhaseProperties[component].short,
|
||||
Run: runControlPlaneSubPhase(component),
|
||||
Run: runControlPlaneSubphase(component),
|
||||
InheritFlags: getControlPlanePhaseFlags(component),
|
||||
}
|
||||
return phase
|
||||
@ -142,7 +142,7 @@ func runControlPlanePhase(c workflow.RunData) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func runControlPlaneSubPhase(component string) func(c workflow.RunData) error {
|
||||
func runControlPlaneSubphase(component string) func(c workflow.RunData) error {
|
||||
return func(c workflow.RunData) error {
|
||||
data, ok := c.(controlPlaneData)
|
||||
if !ok {
|
87
cmd/kubeadm/app/cmd/phases/init/preflight.go
Normal file
87
cmd/kubeadm/app/cmd/phases/init/preflight.go
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
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 phases
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
|
||||
"k8s.io/kubernetes/pkg/util/normalizer"
|
||||
utilsexec "k8s.io/utils/exec"
|
||||
)
|
||||
|
||||
var (
|
||||
preflightExample = normalizer.Examples(`
|
||||
# Run pre-flight checks for kubeadm init using a config file.
|
||||
kubeadm init phase preflight --config kubeadm-config.yml
|
||||
`)
|
||||
)
|
||||
|
||||
// preflightData defines the behavior that a runtime data struct passed to the Preflight phase
|
||||
// should have. Please note that we are using an interface in order to make this phase reusable in different workflows
|
||||
// (and thus with different runtime data struct, all of them requested to be compliant to this interface)
|
||||
type preflightData interface {
|
||||
Cfg() *kubeadmapi.InitConfiguration
|
||||
DryRun() bool
|
||||
IgnorePreflightErrors() sets.String
|
||||
}
|
||||
|
||||
// NewPreflightPhase creates a kubeadm workflow phase that implements preflight checks for a new control-plane node.
|
||||
func NewPreflightPhase() workflow.Phase {
|
||||
return workflow.Phase{
|
||||
Name: "preflight",
|
||||
Short: "Run pre-flight checks",
|
||||
Long: "Run pre-flight checks for kubeadm init.",
|
||||
Example: preflightExample,
|
||||
Run: runPreflight,
|
||||
InheritFlags: []string{
|
||||
options.CfgPath,
|
||||
options.IgnorePreflightErrors,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// runPreflight executes preflight checks logic.
|
||||
func runPreflight(c workflow.RunData) error {
|
||||
data, ok := c.(preflightData)
|
||||
if !ok {
|
||||
return errors.New("preflight phase invoked with an invalid data struct")
|
||||
}
|
||||
|
||||
fmt.Println("[preflight] Running pre-flight checks")
|
||||
if err := preflight.RunInitMasterChecks(utilsexec.New(), data.Cfg(), data.IgnorePreflightErrors()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !data.DryRun() {
|
||||
fmt.Println("[preflight] Pulling images required for setting up a Kubernetes cluster")
|
||||
fmt.Println("[preflight] This might take a minute or two, depending on the speed of your internet connection")
|
||||
fmt.Println("[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'")
|
||||
if err := preflight.RunPullImagesCheck(utilsexec.New(), data.Cfg(), data.IgnorePreflightErrors()); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
fmt.Println("[preflight] Would pull the required images (like 'kubeadm config images pull')")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
45
cmd/kubeadm/app/cmd/phases/join/BUILD
Normal file
45
cmd/kubeadm/app/cmd/phases/join/BUILD
Normal file
@ -0,0 +1,45 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"checketcd.go",
|
||||
"controlplane.go",
|
||||
"preflight.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/join",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd/options:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd/phases/workflow:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd/util:go_default_library",
|
||||
"//cmd/kubeadm/app/constants:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/certs:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/controlplane:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/etcd:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
|
||||
"//cmd/kubeadm/app/preflight:go_default_library",
|
||||
"//pkg/util/normalizer:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//vendor/github.com/lithammer/dedent:go_default_library",
|
||||
"//vendor/github.com/pkg/errors:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
78
cmd/kubeadm/app/cmd/phases/join/checketcd.go
Normal file
78
cmd/kubeadm/app/cmd/phases/join/checketcd.go
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
Copyright 2019 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 phases
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
etcdphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/etcd"
|
||||
)
|
||||
|
||||
type checkEtcdData interface {
|
||||
Cfg() *kubeadmapi.JoinConfiguration
|
||||
ClientSetFromFile(string) (*clientset.Clientset, error)
|
||||
InitCfg() (*kubeadmapi.InitConfiguration, error)
|
||||
}
|
||||
|
||||
// NewCheckEtcdPhase is a hidden phase that runs after the control-plane-prepare and
|
||||
// before the bootstrap-kubelet phase that ensures etcd is healthy
|
||||
func NewCheckEtcdPhase() workflow.Phase {
|
||||
return workflow.Phase{
|
||||
Name: "check-etcd",
|
||||
Run: runCheckEtcdPhase,
|
||||
Hidden: true,
|
||||
}
|
||||
}
|
||||
|
||||
func runCheckEtcdPhase(c workflow.RunData) error {
|
||||
data, ok := c.(checkEtcdData)
|
||||
if !ok {
|
||||
return errors.New("check-etcd phase invoked with an invalid data struct")
|
||||
}
|
||||
|
||||
// Skip if this is not a control plane
|
||||
if data.Cfg().ControlPlane == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
cfg, err := data.InitCfg()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cfg.Etcd.External != nil {
|
||||
fmt.Println("[check-etcd] Skipping etcd check in external mode")
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Println("[check-etcd] Checking that the etcd cluster is healthy")
|
||||
|
||||
// Checks that the etcd cluster is healthy
|
||||
// NB. this check cannot be implemented before because it requires the admin.conf and all the certificates
|
||||
// for connecting to etcd already in place
|
||||
client, err := data.ClientSetFromFile(kubeadmconstants.GetAdminKubeConfigPath())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return etcdphase.CheckLocalEtcdClusterStatus(client, &cfg.ClusterConfiguration)
|
||||
}
|
191
cmd/kubeadm/app/cmd/phases/join/controlplane.go
Normal file
191
cmd/kubeadm/app/cmd/phases/join/controlplane.go
Normal file
@ -0,0 +1,191 @@
|
||||
/*
|
||||
Copyright 2018 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 phases
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow"
|
||||
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
certsphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/controlplane"
|
||||
kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
|
||||
)
|
||||
|
||||
type controlPlanePrepareData interface {
|
||||
Cfg() *kubeadmapi.JoinConfiguration
|
||||
ClientSetFromFile(string) (*clientset.Clientset, error)
|
||||
InitCfg() (*kubeadmapi.InitConfiguration, error)
|
||||
}
|
||||
|
||||
// NewControlPlanePreparePhase creates a kubeadm workflow phase that implements the preparation of the node to serve a control plane
|
||||
func NewControlPlanePreparePhase() workflow.Phase {
|
||||
return workflow.Phase{
|
||||
Name: "control-plane-prepare",
|
||||
Short: "Prepares the machine for serving a control plane.",
|
||||
Long: cmdutil.MacroCommandLongDescription,
|
||||
Phases: []workflow.Phase{
|
||||
{
|
||||
Name: "all",
|
||||
Short: "Prepares the machine for serving a control plane.",
|
||||
InheritFlags: getControlPlanePreparePhaseFlags(),
|
||||
RunAllSiblings: true,
|
||||
},
|
||||
newControlPlanePrepareCertsSubphase(),
|
||||
newControlPlanePrepareKubeconfigSubphase(),
|
||||
newControlPlanePrepareManifestsSubphases(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func getControlPlanePreparePhaseFlags() []string {
|
||||
return []string{
|
||||
options.APIServerAdvertiseAddress,
|
||||
options.APIServerBindPort,
|
||||
options.CfgPath,
|
||||
options.ControlPlane,
|
||||
options.NodeName,
|
||||
options.TokenDiscovery,
|
||||
options.TokenDiscoveryCAHash,
|
||||
options.TokenDiscoverySkipCAHash,
|
||||
}
|
||||
}
|
||||
|
||||
func newControlPlanePrepareCertsSubphase() workflow.Phase {
|
||||
return workflow.Phase{
|
||||
Name: "certs",
|
||||
Short: "Generates the certificates for the new control plane components",
|
||||
Run: runControlPlanePrepareCertsPhaseLocal,
|
||||
InheritFlags: getControlPlanePreparePhaseFlags(), //NB. eventually in future we would like to break down this in sub phases for each cert or add the --csr option
|
||||
}
|
||||
}
|
||||
|
||||
func newControlPlanePrepareKubeconfigSubphase() workflow.Phase {
|
||||
return workflow.Phase{
|
||||
Name: "kubeconfig",
|
||||
Short: "Generates the kubeconfig for the new control plane components",
|
||||
Run: runControlPlanePrepareKubeconfigPhaseLocal,
|
||||
InheritFlags: getControlPlanePreparePhaseFlags(), //NB. eventually in future we would like to break down this in sub phases for each kubeconfig
|
||||
}
|
||||
}
|
||||
|
||||
func newControlPlanePrepareManifestsSubphases() workflow.Phase {
|
||||
return workflow.Phase{
|
||||
Name: "manifests",
|
||||
Short: "Generates the manifests for the new control plane components",
|
||||
Run: runControlPlaneSubphase,
|
||||
InheritFlags: getControlPlanePreparePhaseFlags(), //NB. eventually in future we would like to break down this in sub phases for each component
|
||||
}
|
||||
}
|
||||
|
||||
func runControlPlaneSubphase(c workflow.RunData) error {
|
||||
data, ok := c.(controlPlanePrepareData)
|
||||
if !ok {
|
||||
return errors.New("control-plane-prepare phase invoked with an invalid data struct")
|
||||
}
|
||||
|
||||
// Skip if this is not a control plane
|
||||
if data.Cfg().ControlPlane == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
cfg, err := data.InitCfg()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Generate missing certificates (if any)
|
||||
return controlplane.CreateInitStaticPodManifestFiles(kubeadmconstants.GetStaticPodDirectory(), cfg)
|
||||
}
|
||||
|
||||
func runControlPlanePrepareCertsPhaseLocal(c workflow.RunData) error {
|
||||
data, ok := c.(controlPlanePrepareData)
|
||||
if !ok {
|
||||
return errors.New("control-plane-prepare phase invoked with an invalid data struct")
|
||||
}
|
||||
|
||||
// Skip if this is not a control plane
|
||||
if data.Cfg().ControlPlane == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
cfg, err := data.InitCfg()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Generate missing certificates (if any)
|
||||
return certsphase.CreatePKIAssets(cfg)
|
||||
}
|
||||
|
||||
func runControlPlanePrepareKubeconfigPhaseLocal(c workflow.RunData) error {
|
||||
data, ok := c.(controlPlanePrepareData)
|
||||
if !ok {
|
||||
return errors.New("control-plane-prepare phase invoked with an invalid data struct")
|
||||
}
|
||||
|
||||
// Skip if this is not a control plane
|
||||
if data.Cfg().ControlPlane == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
cfg, err := data.InitCfg()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("[control-plane-prepare] Generating kubeconfig files")
|
||||
|
||||
// Generate kubeconfig files for controller manager, scheduler and for the admin/kubeadm itself
|
||||
// NB. The kubeconfig file for kubelet will be generated by the TLS bootstrap process in
|
||||
// following steps of the join --experimental-control plane workflow
|
||||
if err := kubeconfigphase.CreateJoinControlPlaneKubeConfigFiles(kubeadmconstants.KubernetesDir, cfg); err != nil {
|
||||
return errors.Wrap(err, "error generating kubeconfig files")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func runControlPlanePrepareJoinSubphase(component string) func(c workflow.RunData) error {
|
||||
return func(c workflow.RunData) error {
|
||||
data, ok := c.(controlPlanePrepareData)
|
||||
if !ok {
|
||||
return errors.New("control-plane-prepare phase invoked with an invalid data struct")
|
||||
}
|
||||
|
||||
// Skip if this is not a control plane
|
||||
if data.Cfg().ControlPlane == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
cfg, err := data.InitCfg()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Creates static pod manifests file for the control plane components to be deployed on this node
|
||||
// Static pods will be created and managed by the kubelet as soon as it starts
|
||||
fmt.Printf("[control-plane-prepare] Creating static Pod manifest for %q\n", component)
|
||||
return controlplane.CreateStaticPodFiles(kubeadmconstants.GetStaticPodDirectory(), &cfg.ClusterConfiguration, &cfg.LocalAPIEndpoint, component)
|
||||
}
|
||||
}
|
@ -35,11 +35,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
initPreflightExample = normalizer.Examples(`
|
||||
# Run master pre-flight checks using a config file.
|
||||
kubeadm init phase preflight --config kubeadm-config.yml
|
||||
`)
|
||||
joinPreflightExample = normalizer.Examples(`
|
||||
preflightExample = normalizer.Examples(`
|
||||
# Run join pre-flight checks using a config file.
|
||||
kubeadm join phase preflight --config kubeadm-config.yml
|
||||
`)
|
||||
@ -56,71 +52,20 @@ var (
|
||||
`)))
|
||||
)
|
||||
|
||||
// preflightMasterData defines the behavior that a runtime data struct passed to the PreflightMaster master phase
|
||||
// should have. Please note that we are using an interface in order to make this phase reusable in different workflows
|
||||
// (and thus with different runtime data struct, all of them requested to be compliant to this interface)
|
||||
type preflightMasterData interface {
|
||||
Cfg() *kubeadmapi.InitConfiguration
|
||||
DryRun() bool
|
||||
IgnorePreflightErrors() sets.String
|
||||
}
|
||||
|
||||
type preflightJoinData interface {
|
||||
type preflightData interface {
|
||||
Cfg() *kubeadmapi.JoinConfiguration
|
||||
InitCfg() (*kubeadmapi.InitConfiguration, error)
|
||||
IgnorePreflightErrors() sets.String
|
||||
}
|
||||
|
||||
// NewPreflightMasterPhase creates a kubeadm workflow phase that implements preflight checks for a new master node.
|
||||
func NewPreflightMasterPhase() workflow.Phase {
|
||||
return workflow.Phase{
|
||||
Name: "preflight",
|
||||
Short: "Run master pre-flight checks",
|
||||
Long: "Run master pre-flight checks, functionally equivalent to what implemented by kubeadm init.",
|
||||
Example: initPreflightExample,
|
||||
Run: runPreflightMaster,
|
||||
InheritFlags: []string{
|
||||
options.CfgPath,
|
||||
options.IgnorePreflightErrors,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(dmaiocchi): rename all instances of master to controlPlane in this file.
|
||||
// runPreflightMaster executes preflight checks logic.
|
||||
func runPreflightMaster(c workflow.RunData) error {
|
||||
data, ok := c.(preflightMasterData)
|
||||
if !ok {
|
||||
return errors.New("preflight phase invoked with an invalid data struct")
|
||||
}
|
||||
|
||||
fmt.Println("[preflight] Running pre-flight checks")
|
||||
if err := preflight.RunInitMasterChecks(utilsexec.New(), data.Cfg(), data.IgnorePreflightErrors()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !data.DryRun() {
|
||||
fmt.Println("[preflight] Pulling images required for setting up a Kubernetes cluster")
|
||||
fmt.Println("[preflight] This might take a minute or two, depending on the speed of your internet connection")
|
||||
fmt.Println("[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'")
|
||||
if err := preflight.RunPullImagesCheck(utilsexec.New(), data.Cfg(), data.IgnorePreflightErrors()); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
fmt.Println("[preflight] Would pull the required images (like 'kubeadm config images pull')")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewPreflightJoinPhase creates a kubeadm workflow phase that implements preflight checks for a new node join
|
||||
func NewPreflightJoinPhase() workflow.Phase {
|
||||
// NewPreflightPhase creates a kubeadm workflow phase that implements preflight checks for a new node join
|
||||
func NewPreflightPhase() workflow.Phase {
|
||||
return workflow.Phase{
|
||||
Name: "preflight",
|
||||
Short: "Run join pre-flight checks",
|
||||
Long: "Run join pre-flight checks, functionally equivalent to what is implemented by kubeadm join.",
|
||||
Example: joinPreflightExample,
|
||||
Run: runPreflightJoin,
|
||||
Long: "Run pre-flight checks for kubeadm join.",
|
||||
Example: preflightExample,
|
||||
Run: runPreflight,
|
||||
InheritFlags: []string{
|
||||
options.CfgPath,
|
||||
options.IgnorePreflightErrors,
|
||||
@ -139,12 +84,14 @@ func NewPreflightJoinPhase() workflow.Phase {
|
||||
}
|
||||
}
|
||||
|
||||
// runPreflightJoin executes preflight checks logic.
|
||||
func runPreflightJoin(c workflow.RunData) error {
|
||||
j, ok := c.(preflightJoinData)
|
||||
// runPreflight executes preflight checks logic.
|
||||
func runPreflight(c workflow.RunData) error {
|
||||
j, ok := c.(preflightData)
|
||||
if !ok {
|
||||
return errors.New("preflight phase invoked with an invalid data struct")
|
||||
}
|
||||
fmt.Println("[preflight] Running pre-flight checks")
|
||||
|
||||
// Start with general checks
|
||||
klog.V(1).Infoln("[preflight] Running general checks")
|
||||
if err := preflight.RunJoinNodeChecks(utilsexec.New(), j.Cfg(), j.IgnorePreflightErrors()); err != nil {
|
||||
@ -182,7 +129,9 @@ func runPreflightJoin(c workflow.RunData) error {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("[preflight] Pulling control-plane images")
|
||||
fmt.Println("[preflight] Pulling images required for setting up a Kubernetes cluster")
|
||||
fmt.Println("[preflight] This might take a minute or two, depending on the speed of your internet connection")
|
||||
fmt.Println("[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'")
|
||||
if err := preflight.RunPullImagesCheck(utilsexec.New(), initCfg, j.IgnorePreflightErrors()); err != nil {
|
||||
return err
|
||||
}
|
@ -129,8 +129,8 @@ func NewCmdToken(out io.Writer, errW io.Writer) *cobra.Command {
|
||||
kubeadmutil.CheckErr(err)
|
||||
},
|
||||
}
|
||||
createCmd.Flags().StringVar(&cfgPath,
|
||||
"config", cfgPath, "Path to kubeadm config file (WARNING: Usage of a configuration file is experimental)")
|
||||
|
||||
options.AddConfigFlag(createCmd.Flags(), &cfgPath)
|
||||
createCmd.Flags().BoolVar(&printJoinCommand,
|
||||
"print-join-command", false, "Instead of printing only the token, print the full 'kubeadm join' flag needed to join the cluster using the token.")
|
||||
bto.AddTTLFlagWithName(createCmd.Flags(), "ttl")
|
||||
|
@ -122,7 +122,6 @@ go_library(
|
||||
"//staging/src/k8s.io/apiserver/pkg/server/healthz:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/util/flag:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/dynamic:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes/typed/authentication/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes/typed/authorization/v1beta1:go_default_library",
|
||||
@ -136,6 +135,7 @@ go_library(
|
||||
"//staging/src/k8s.io/cloud-provider:go_default_library",
|
||||
"//staging/src/k8s.io/csi-api/pkg/client/clientset/versioned:go_default_library",
|
||||
"//staging/src/k8s.io/kubelet/config/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/node-api/pkg/client/clientset/versioned:go_default_library",
|
||||
"//vendor/github.com/coreos/go-systemd/daemon:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
|
@ -48,7 +48,6 @@ import (
|
||||
"k8s.io/apiserver/pkg/server/healthz"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/apiserver/pkg/util/flag"
|
||||
"k8s.io/client-go/dynamic"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
certificatesclient "k8s.io/client-go/kubernetes/typed/certificates/v1beta1"
|
||||
v1core "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
@ -95,6 +94,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/util/rlimit"
|
||||
"k8s.io/kubernetes/pkg/version"
|
||||
"k8s.io/kubernetes/pkg/version/verflag"
|
||||
nodeapiclientset "k8s.io/node-api/pkg/client/clientset/versioned"
|
||||
"k8s.io/utils/exec"
|
||||
"k8s.io/utils/nsenter"
|
||||
)
|
||||
@ -545,12 +545,11 @@ func run(s *options.KubeletServer, kubeDeps *kubelet.Dependencies, stopCh <-chan
|
||||
switch {
|
||||
case standaloneMode:
|
||||
kubeDeps.KubeClient = nil
|
||||
kubeDeps.DynamicKubeClient = nil
|
||||
kubeDeps.EventClient = nil
|
||||
kubeDeps.HeartbeatClient = nil
|
||||
klog.Warningf("standalone mode, no API client")
|
||||
|
||||
case kubeDeps.KubeClient == nil, kubeDeps.EventClient == nil, kubeDeps.HeartbeatClient == nil, kubeDeps.DynamicKubeClient == nil:
|
||||
case kubeDeps.KubeClient == nil, kubeDeps.EventClient == nil, kubeDeps.HeartbeatClient == nil:
|
||||
clientConfig, closeAllConns, err := buildKubeletClientConfig(s, nodeName)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -562,11 +561,6 @@ func run(s *options.KubeletServer, kubeDeps *kubelet.Dependencies, stopCh <-chan
|
||||
return fmt.Errorf("failed to initialize kubelet client: %v", err)
|
||||
}
|
||||
|
||||
kubeDeps.DynamicKubeClient, err = dynamic.NewForConfig(clientConfig)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to initialize kubelet dynamic client: %v", err)
|
||||
}
|
||||
|
||||
// make a separate client for events
|
||||
eventClientConfig := *clientConfig
|
||||
eventClientConfig.QPS = float32(s.EventRecordQPS)
|
||||
@ -593,12 +587,17 @@ func run(s *options.KubeletServer, kubeDeps *kubelet.Dependencies, stopCh <-chan
|
||||
}
|
||||
|
||||
// CRDs are JSON only, and client renegotiation for streaming is not correct as per #67803
|
||||
csiClientConfig := restclient.CopyConfig(clientConfig)
|
||||
csiClientConfig.ContentType = "application/json"
|
||||
kubeDeps.CSIClient, err = csiclientset.NewForConfig(csiClientConfig)
|
||||
crdClientConfig := restclient.CopyConfig(clientConfig)
|
||||
crdClientConfig.ContentType = "application/json"
|
||||
kubeDeps.CSIClient, err = csiclientset.NewForConfig(crdClientConfig)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to initialize kubelet storage client: %v", err)
|
||||
}
|
||||
|
||||
kubeDeps.NodeAPIClient, err = nodeapiclientset.NewForConfig(crdClientConfig)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to initialize kubelet node-api client: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// If the kubelet config controller is available, and dynamic config is enabled, start the config and status sync loops
|
||||
|
@ -21,6 +21,21 @@ set -o pipefail
|
||||
KUBE_ROOT=$(dirname "${BASH_SOURCE}")/..
|
||||
source "${KUBE_ROOT}/hack/lib/init.sh"
|
||||
|
||||
kube::util::ensure_clean_working_dir
|
||||
|
||||
_tmpdir="$(kube::realpath $(mktemp -d -t verify-generated-files.XXXXXX))"
|
||||
kube::util::trap_add "rm -rf ${_tmpdir}" EXIT
|
||||
|
||||
_tmp_gopath="${_tmpdir}/go"
|
||||
_tmp_kuberoot="${_tmp_gopath}/src/k8s.io/kubernetes"
|
||||
mkdir -p "${_tmp_kuberoot}/.."
|
||||
cp -a "${KUBE_ROOT}" "${_tmp_kuberoot}/.."
|
||||
|
||||
cd "${_tmp_kuberoot}"
|
||||
|
||||
# clean out anything from the temp dir that's not checked in
|
||||
git clean -ffxd
|
||||
|
||||
# $1 = filename pattern as in "zz_generated.$1.go"
|
||||
function find_genfiles() {
|
||||
find . \
|
||||
|
@ -176,6 +176,11 @@ func collectResourcePaths(t *testing.T, resourcename string, path *field.Path, n
|
||||
case reflect.Ptr:
|
||||
resourcePaths.Insert(collectResourcePaths(t, resourcename, path, name, tp.Elem()).List()...)
|
||||
case reflect.Struct:
|
||||
// ObjectMeta is generic and therefore should never have a field with a specific resource's name;
|
||||
// it contains cycles so it's easiest to just skip it.
|
||||
if name == "ObjectMeta" {
|
||||
break
|
||||
}
|
||||
for i := 0; i < tp.NumField(); i++ {
|
||||
field := tp.Field(i)
|
||||
resourcePaths.Insert(collectResourcePaths(t, resourcename, path.Child(field.Name), field.Name, field.Type).List()...)
|
||||
|
@ -12,7 +12,7 @@ go_library(
|
||||
importpath = "k8s.io/kubernetes/pkg/api/service",
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/util/net/sets:go_default_library",
|
||||
"//vendor/k8s.io/utils/net:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@ -22,7 +22,7 @@ go_test(
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/util/net/sets:go_default_library",
|
||||
"//vendor/k8s.io/utils/net:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -18,17 +18,18 @@ package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
netsets "k8s.io/kubernetes/pkg/util/net/sets"
|
||||
"strings"
|
||||
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
utilnet "k8s.io/utils/net"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultLoadBalancerSourceRanges = "0.0.0.0/0"
|
||||
)
|
||||
|
||||
// IsAllowAll checks whether the netsets.IPNet allows traffic from 0.0.0.0/0
|
||||
func IsAllowAll(ipnets netsets.IPNet) bool {
|
||||
// IsAllowAll checks whether the utilnet.IPNet allows traffic from 0.0.0.0/0
|
||||
func IsAllowAll(ipnets utilnet.IPNetSet) bool {
|
||||
for _, s := range ipnets.StringSlice() {
|
||||
if s == "0.0.0.0/0" {
|
||||
return true
|
||||
@ -40,13 +41,13 @@ func IsAllowAll(ipnets netsets.IPNet) bool {
|
||||
// GetLoadBalancerSourceRanges first try to parse and verify LoadBalancerSourceRanges field from a service.
|
||||
// If the field is not specified, turn to parse and verify the AnnotationLoadBalancerSourceRangesKey annotation from a service,
|
||||
// extracting the source ranges to allow, and if not present returns a default (allow-all) value.
|
||||
func GetLoadBalancerSourceRanges(service *api.Service) (netsets.IPNet, error) {
|
||||
var ipnets netsets.IPNet
|
||||
func GetLoadBalancerSourceRanges(service *api.Service) (utilnet.IPNetSet, error) {
|
||||
var ipnets utilnet.IPNetSet
|
||||
var err error
|
||||
// if SourceRange field is specified, ignore sourceRange annotation
|
||||
if len(service.Spec.LoadBalancerSourceRanges) > 0 {
|
||||
specs := service.Spec.LoadBalancerSourceRanges
|
||||
ipnets, err = netsets.ParseIPNets(specs...)
|
||||
ipnets, err = utilnet.ParseIPNets(specs...)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("service.Spec.LoadBalancerSourceRanges: %v is not valid. Expecting a list of IP ranges. For example, 10.0.0.0/24. Error msg: %v", specs, err)
|
||||
@ -58,7 +59,7 @@ func GetLoadBalancerSourceRanges(service *api.Service) (netsets.IPNet, error) {
|
||||
val = defaultLoadBalancerSourceRanges
|
||||
}
|
||||
specs := strings.Split(val, ",")
|
||||
ipnets, err = netsets.ParseIPNets(specs...)
|
||||
ipnets, err = utilnet.ParseIPNets(specs...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s: %s is not valid. Expecting a comma-separated list of source IP ranges. For example, 10.0.0.0/24,192.168.2.0/24", api.AnnotationLoadBalancerSourceRangesKey, val)
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ import (
|
||||
"testing"
|
||||
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
netsets "k8s.io/kubernetes/pkg/util/net/sets"
|
||||
utilnet "k8s.io/utils/net"
|
||||
)
|
||||
|
||||
func TestGetLoadBalancerSourceRanges(t *testing.T) {
|
||||
@ -48,7 +48,7 @@ func TestGetLoadBalancerSourceRanges(t *testing.T) {
|
||||
checkError("10.0.0.1/32, ")
|
||||
checkError("10.0.0.1")
|
||||
|
||||
checkOK := func(v string) netsets.IPNet {
|
||||
checkOK := func(v string) utilnet.IPNetSet {
|
||||
annotations := make(map[string]string)
|
||||
annotations[api.AnnotationLoadBalancerSourceRangesKey] = v
|
||||
svc := api.Service{}
|
||||
@ -112,7 +112,7 @@ func TestGetLoadBalancerSourceRanges(t *testing.T) {
|
||||
|
||||
func TestAllowAll(t *testing.T) {
|
||||
checkAllowAll := func(allowAll bool, cidrs ...string) {
|
||||
ipnets, err := netsets.ParseIPNets(cidrs...)
|
||||
ipnets, err := utilnet.ParseIPNets(cidrs...)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error parsing cidrs: %v", cidrs)
|
||||
}
|
||||
|
@ -26,7 +26,6 @@ import (
|
||||
"testing"
|
||||
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/apitesting/fuzzer"
|
||||
@ -162,9 +161,10 @@ var nonRoundTrippableTypes = sets.NewString(
|
||||
"DeleteOptions",
|
||||
"CreateOptions",
|
||||
"UpdateOptions",
|
||||
"PatchOptions",
|
||||
)
|
||||
|
||||
var commonKinds = []string{"Status", "ListOptions", "DeleteOptions", "ExportOptions", "GetOptions", "CreateOptions", "UpdateOptions"}
|
||||
var commonKinds = []string{"Status", "ListOptions", "DeleteOptions", "ExportOptions", "GetOptions", "CreateOptions", "UpdateOptions", "PatchOptions"}
|
||||
|
||||
// TestCommonKindsRegistered verifies that all group/versions registered with
|
||||
// the testapi package have the common kinds.
|
||||
|
@ -18,9 +18,8 @@ package persistentvolume
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
@ -248,6 +247,11 @@ func collectSecretPaths(t *testing.T, path *field.Path, name string, tp reflect.
|
||||
case reflect.Ptr:
|
||||
secretPaths.Insert(collectSecretPaths(t, path, name, tp.Elem()).List()...)
|
||||
case reflect.Struct:
|
||||
// ObjectMeta should not have any field with the word "secret" in it;
|
||||
// it contains cycles so it's easiest to just skip it.
|
||||
if name == "ObjectMeta" {
|
||||
break
|
||||
}
|
||||
for i := 0; i < tp.NumField(); i++ {
|
||||
field := tp.Field(i)
|
||||
secretPaths.Insert(collectSecretPaths(t, path.Child(field.Name), field.Name, field.Type).List()...)
|
||||
|
@ -340,6 +340,11 @@ func collectResourcePaths(t *testing.T, resourcename string, path *field.Path, n
|
||||
case reflect.Ptr:
|
||||
resourcePaths.Insert(collectResourcePaths(t, resourcename, path, name, tp.Elem()).List()...)
|
||||
case reflect.Struct:
|
||||
// ObjectMeta is generic and therefore should never have a field with a specific resource's name;
|
||||
// it contains cycles so it's easiest to just skip it.
|
||||
if name == "ObjectMeta" {
|
||||
break
|
||||
}
|
||||
for i := 0; i < tp.NumField(); i++ {
|
||||
field := tp.Field(i)
|
||||
resourcePaths.Insert(collectResourcePaths(t, resourcename, path.Child(field.Name), field.Name, field.Type).List()...)
|
||||
|
@ -11,8 +11,8 @@ go_library(
|
||||
srcs = ["util.go"],
|
||||
importpath = "k8s.io/kubernetes/pkg/api/v1/service",
|
||||
deps = [
|
||||
"//pkg/util/net/sets:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/utils/net:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@ -21,8 +21,8 @@ go_test(
|
||||
srcs = ["util_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/util/net/sets:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/utils/net:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -21,15 +21,15 @@ import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
netsets "k8s.io/kubernetes/pkg/util/net/sets"
|
||||
utilnet "k8s.io/utils/net"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultLoadBalancerSourceRanges = "0.0.0.0/0"
|
||||
)
|
||||
|
||||
// IsAllowAll checks whether the netsets.IPNet allows traffic from 0.0.0.0/0
|
||||
func IsAllowAll(ipnets netsets.IPNet) bool {
|
||||
// IsAllowAll checks whether the utilnet.IPNet allows traffic from 0.0.0.0/0
|
||||
func IsAllowAll(ipnets utilnet.IPNetSet) bool {
|
||||
for _, s := range ipnets.StringSlice() {
|
||||
if s == "0.0.0.0/0" {
|
||||
return true
|
||||
@ -41,13 +41,13 @@ func IsAllowAll(ipnets netsets.IPNet) bool {
|
||||
// GetLoadBalancerSourceRanges first try to parse and verify LoadBalancerSourceRanges field from a service.
|
||||
// If the field is not specified, turn to parse and verify the AnnotationLoadBalancerSourceRangesKey annotation from a service,
|
||||
// extracting the source ranges to allow, and if not present returns a default (allow-all) value.
|
||||
func GetLoadBalancerSourceRanges(service *v1.Service) (netsets.IPNet, error) {
|
||||
var ipnets netsets.IPNet
|
||||
func GetLoadBalancerSourceRanges(service *v1.Service) (utilnet.IPNetSet, error) {
|
||||
var ipnets utilnet.IPNetSet
|
||||
var err error
|
||||
// if SourceRange field is specified, ignore sourceRange annotation
|
||||
if len(service.Spec.LoadBalancerSourceRanges) > 0 {
|
||||
specs := service.Spec.LoadBalancerSourceRanges
|
||||
ipnets, err = netsets.ParseIPNets(specs...)
|
||||
ipnets, err = utilnet.ParseIPNets(specs...)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("service.Spec.LoadBalancerSourceRanges: %v is not valid. Expecting a list of IP ranges. For example, 10.0.0.0/24. Error msg: %v", specs, err)
|
||||
@ -59,7 +59,7 @@ func GetLoadBalancerSourceRanges(service *v1.Service) (netsets.IPNet, error) {
|
||||
val = defaultLoadBalancerSourceRanges
|
||||
}
|
||||
specs := strings.Split(val, ",")
|
||||
ipnets, err = netsets.ParseIPNets(specs...)
|
||||
ipnets, err = utilnet.ParseIPNets(specs...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s: %s is not valid. Expecting a comma-separated list of source IP ranges. For example, 10.0.0.0/24,192.168.2.0/24", v1.AnnotationLoadBalancerSourceRangesKey, val)
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
netsets "k8s.io/kubernetes/pkg/util/net/sets"
|
||||
utilnet "k8s.io/utils/net"
|
||||
)
|
||||
|
||||
func TestGetLoadBalancerSourceRanges(t *testing.T) {
|
||||
@ -48,7 +48,7 @@ func TestGetLoadBalancerSourceRanges(t *testing.T) {
|
||||
checkError("10.0.0.1/32, ")
|
||||
checkError("10.0.0.1")
|
||||
|
||||
checkOK := func(v string) netsets.IPNet {
|
||||
checkOK := func(v string) utilnet.IPNetSet {
|
||||
annotations := make(map[string]string)
|
||||
annotations[v1.AnnotationLoadBalancerSourceRangesKey] = v
|
||||
svc := v1.Service{}
|
||||
@ -112,7 +112,7 @@ func TestGetLoadBalancerSourceRanges(t *testing.T) {
|
||||
|
||||
func TestAllowAll(t *testing.T) {
|
||||
checkAllowAll := func(allowAll bool, cidrs ...string) {
|
||||
ipnets, err := netsets.ParseIPNets(cidrs...)
|
||||
ipnets, err := utilnet.ParseIPNets(cidrs...)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error parsing cidrs: %v", cidrs)
|
||||
}
|
||||
|
@ -56,7 +56,9 @@ func ValidateSelfSubjectRulesReview(review *authorizationapi.SelfSubjectRulesRev
|
||||
|
||||
func ValidateSubjectAccessReview(sar *authorizationapi.SubjectAccessReview) field.ErrorList {
|
||||
allErrs := ValidateSubjectAccessReviewSpec(sar.Spec, field.NewPath("spec"))
|
||||
if !apiequality.Semantic.DeepEqual(metav1.ObjectMeta{}, sar.ObjectMeta) {
|
||||
objectMetaShallowCopy := sar.ObjectMeta
|
||||
objectMetaShallowCopy.ManagedFields = nil
|
||||
if !apiequality.Semantic.DeepEqual(metav1.ObjectMeta{}, objectMetaShallowCopy) {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("metadata"), sar.ObjectMeta, `must be empty`))
|
||||
}
|
||||
return allErrs
|
||||
@ -64,7 +66,9 @@ func ValidateSubjectAccessReview(sar *authorizationapi.SubjectAccessReview) fiel
|
||||
|
||||
func ValidateSelfSubjectAccessReview(sar *authorizationapi.SelfSubjectAccessReview) field.ErrorList {
|
||||
allErrs := ValidateSelfSubjectAccessReviewSpec(sar.Spec, field.NewPath("spec"))
|
||||
if !apiequality.Semantic.DeepEqual(metav1.ObjectMeta{}, sar.ObjectMeta) {
|
||||
objectMetaShallowCopy := sar.ObjectMeta
|
||||
objectMetaShallowCopy.ManagedFields = nil
|
||||
if !apiequality.Semantic.DeepEqual(metav1.ObjectMeta{}, objectMetaShallowCopy) {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("metadata"), sar.ObjectMeta, `must be empty`))
|
||||
}
|
||||
return allErrs
|
||||
@ -75,6 +79,7 @@ func ValidateLocalSubjectAccessReview(sar *authorizationapi.LocalSubjectAccessRe
|
||||
|
||||
objectMetaShallowCopy := sar.ObjectMeta
|
||||
objectMetaShallowCopy.Namespace = ""
|
||||
objectMetaShallowCopy.ManagedFields = nil
|
||||
if !apiequality.Semantic.DeepEqual(metav1.ObjectMeta{}, objectMetaShallowCopy) {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("metadata"), sar.ObjectMeta, `must be empty except for namespace`))
|
||||
}
|
||||
|
@ -918,6 +918,11 @@ type QuobyteVolumeSource struct {
|
||||
// Default is no group
|
||||
// +optional
|
||||
Group string
|
||||
|
||||
// Tenant owning the given Quobyte volume in the Backend
|
||||
// Used with dynamically provisioned Quobyte volumes, value is set by the plugin
|
||||
// +optional
|
||||
Tenant string
|
||||
}
|
||||
|
||||
// Represents a Glusterfs mount that lasts the lifetime of a pod.
|
||||
|
2
pkg/apis/core/v1/zz_generated.conversion.go
generated
2
pkg/apis/core/v1/zz_generated.conversion.go
generated
@ -5989,6 +5989,7 @@ func autoConvert_v1_QuobyteVolumeSource_To_core_QuobyteVolumeSource(in *v1.Quoby
|
||||
out.ReadOnly = in.ReadOnly
|
||||
out.User = in.User
|
||||
out.Group = in.Group
|
||||
out.Tenant = in.Tenant
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -6003,6 +6004,7 @@ func autoConvert_core_QuobyteVolumeSource_To_v1_QuobyteVolumeSource(in *core.Quo
|
||||
out.ReadOnly = in.ReadOnly
|
||||
out.User = in.User
|
||||
out.Group = in.Group
|
||||
out.Tenant = in.Tenant
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -415,9 +415,6 @@ func validateVolumeSource(source *core.VolumeSource, fldPath *field.Path, volNam
|
||||
if source.EmptyDir.SizeLimit != nil && source.EmptyDir.SizeLimit.Cmp(resource.Quantity{}) < 0 {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("emptyDir").Child("sizeLimit"), "SizeLimit field must be a valid resource quantity"))
|
||||
}
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.HugePages) && source.EmptyDir.Medium == core.StorageMediumHugePages {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("emptyDir").Child("medium"), "HugePages medium is disabled by feature-gate for EmptyDir volumes"))
|
||||
}
|
||||
}
|
||||
if source.HostPath != nil {
|
||||
if numVolumes > 0 {
|
||||
@ -873,6 +870,10 @@ func validateQuobyteVolumeSource(quobyte *core.QuobyteVolumeSource, fldPath *fie
|
||||
allErrs := field.ErrorList{}
|
||||
if len(quobyte.Registry) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("registry"), "must be a host:port pair or multiple pairs separated by commas"))
|
||||
} else if len(quobyte.Tenant) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("tenant"), "must be a UUID provided by the configuration and may not be omitted "))
|
||||
} else if len(quobyte.Tenant) >= 65 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("tenant"), "must be a UUID and may not exceed a length of 64 characters"))
|
||||
} else {
|
||||
for _, hostPortPair := range strings.Split(quobyte.Registry, ",") {
|
||||
if _, _, err := net.SplitHostPort(hostPortPair); err != nil {
|
||||
@ -2925,19 +2926,17 @@ func ValidatePod(pod *core.Pod) field.ErrorList {
|
||||
allErrs = append(allErrs, validateContainersOnlyForPod(pod.Spec.Containers, specPath.Child("containers"))...)
|
||||
allErrs = append(allErrs, validateContainersOnlyForPod(pod.Spec.InitContainers, specPath.Child("initContainers"))...)
|
||||
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.HugePages) {
|
||||
hugePageResources := sets.NewString()
|
||||
for i := range pod.Spec.Containers {
|
||||
resourceSet := toContainerResourcesSet(&pod.Spec.Containers[i])
|
||||
for resourceStr := range resourceSet {
|
||||
if v1helper.IsHugePageResourceName(v1.ResourceName(resourceStr)) {
|
||||
hugePageResources.Insert(resourceStr)
|
||||
}
|
||||
hugePageResources := sets.NewString()
|
||||
for i := range pod.Spec.Containers {
|
||||
resourceSet := toContainerResourcesSet(&pod.Spec.Containers[i])
|
||||
for resourceStr := range resourceSet {
|
||||
if v1helper.IsHugePageResourceName(v1.ResourceName(resourceStr)) {
|
||||
hugePageResources.Insert(resourceStr)
|
||||
}
|
||||
}
|
||||
if len(hugePageResources) > 1 {
|
||||
allErrs = append(allErrs, field.Invalid(specPath, hugePageResources, "must use a single hugepage size in a pod spec"))
|
||||
}
|
||||
}
|
||||
if len(hugePageResources) > 1 {
|
||||
allErrs = append(allErrs, field.Invalid(specPath, hugePageResources, "must use a single hugepage size in a pod spec"))
|
||||
}
|
||||
|
||||
return allErrs
|
||||
|
@ -3379,6 +3379,7 @@ func TestValidateVolumes(t *testing.T) {
|
||||
ReadOnly: false,
|
||||
User: "root",
|
||||
Group: "root",
|
||||
Tenant: "ThisIsSomeTenantUUID",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -3390,6 +3391,7 @@ func TestValidateVolumes(t *testing.T) {
|
||||
VolumeSource: core.VolumeSource{
|
||||
Quobyte: &core.QuobyteVolumeSource{
|
||||
Volume: "/test",
|
||||
Tenant: "ThisIsSomeTenantUUID",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -3406,6 +3408,7 @@ func TestValidateVolumes(t *testing.T) {
|
||||
Quobyte: &core.QuobyteVolumeSource{
|
||||
Registry: "registry7861",
|
||||
Volume: "/test",
|
||||
Tenant: "ThisIsSomeTenantUUID",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -3422,6 +3425,7 @@ func TestValidateVolumes(t *testing.T) {
|
||||
Quobyte: &core.QuobyteVolumeSource{
|
||||
Registry: "registry:7861,reg2",
|
||||
Volume: "/test",
|
||||
Tenant: "ThisIsSomeTenantUUID",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -3437,6 +3441,7 @@ func TestValidateVolumes(t *testing.T) {
|
||||
VolumeSource: core.VolumeSource{
|
||||
Quobyte: &core.QuobyteVolumeSource{
|
||||
Registry: "registry:7861",
|
||||
Tenant: "ThisIsSomeTenantUUID",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -3445,6 +3450,40 @@ func TestValidateVolumes(t *testing.T) {
|
||||
field: "quobyte.volume",
|
||||
}},
|
||||
},
|
||||
{
|
||||
name: "empty tenant quobyte",
|
||||
vol: core.Volume{
|
||||
Name: "quobyte",
|
||||
VolumeSource: core.VolumeSource{
|
||||
Quobyte: &core.QuobyteVolumeSource{
|
||||
Registry: "registry:7861,reg2",
|
||||
Volume: "/test",
|
||||
Tenant: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
errs: []verr{{
|
||||
etype: field.ErrorTypeRequired,
|
||||
field: "quobyte.tenant",
|
||||
}},
|
||||
},
|
||||
{
|
||||
name: "too long tenant quobyte",
|
||||
vol: core.Volume{
|
||||
Name: "quobyte",
|
||||
VolumeSource: core.VolumeSource{
|
||||
Quobyte: &core.QuobyteVolumeSource{
|
||||
Registry: "registry:7861,reg2",
|
||||
Volume: "/test",
|
||||
Tenant: "this is too long to be a valid uuid so this test has to fail on the maximum length validation of the tenant.",
|
||||
},
|
||||
},
|
||||
},
|
||||
errs: []verr{{
|
||||
etype: field.ErrorTypeRequired,
|
||||
field: "quobyte.tenant",
|
||||
}},
|
||||
},
|
||||
// AzureDisk
|
||||
{
|
||||
name: "valid AzureDisk",
|
||||
@ -3659,24 +3698,17 @@ func TestValidateVolumes(t *testing.T) {
|
||||
t.Errorf("expected error type %v, got %v", field.ErrorTypeDuplicate, errs[0].Type)
|
||||
}
|
||||
|
||||
// Validate HugePages medium type for EmptyDir when HugePages feature is enabled/disabled
|
||||
// Validate HugePages medium type for EmptyDir
|
||||
hugePagesCase := core.VolumeSource{EmptyDir: &core.EmptyDirVolumeSource{Medium: core.StorageMediumHugePages}}
|
||||
|
||||
// Enable HugePages
|
||||
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HugePages, true)()
|
||||
if errs := validateVolumeSource(&hugePagesCase, field.NewPath("field").Index(0), "working"); len(errs) != 0 {
|
||||
t.Errorf("Unexpected error when HugePages feature is enabled.")
|
||||
}
|
||||
|
||||
// Disable feature HugePages
|
||||
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HugePages, false)()
|
||||
if errs := validateVolumeSource(&hugePagesCase, field.NewPath("field").Index(0), "failing"); len(errs) == 0 {
|
||||
t.Errorf("Expected error when HugePages feature is disabled got nothing.")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestAlphaHugePagesIsolation(t *testing.T) {
|
||||
func TestHugePagesIsolation(t *testing.T) {
|
||||
successCases := []core.Pod{
|
||||
{ // Basic fields.
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "123", Namespace: "ns"},
|
||||
@ -3774,8 +3806,6 @@ func TestAlphaHugePagesIsolation(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
// Enable feature HugePages
|
||||
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HugePages, true)()
|
||||
for i := range successCases {
|
||||
pod := &successCases[i]
|
||||
if errs := ValidatePod(pod); len(errs) != 0 {
|
||||
@ -3788,15 +3818,6 @@ func TestAlphaHugePagesIsolation(t *testing.T) {
|
||||
t.Errorf("Expected error for case[%d], pod: %v", i, pod.Name)
|
||||
}
|
||||
}
|
||||
// Disable feature HugePages
|
||||
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HugePages, false)()
|
||||
// Disable feature HugePages and ensure all success cases fail
|
||||
for i := range successCases {
|
||||
pod := &successCases[i]
|
||||
if errs := ValidatePod(pod); len(errs) == 0 {
|
||||
t.Errorf("Expected error for case[%d], pod: %v", i, pod.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPVCVolumeMode(t *testing.T) {
|
||||
@ -6686,6 +6707,33 @@ func TestValidatePod(t *testing.T) {
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
},
|
||||
},
|
||||
{ // valid serviceaccount token projected volume with serviceaccount name specified
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "valid-extended", Namespace: "ns"},
|
||||
Spec: core.PodSpec{
|
||||
ServiceAccountName: "some-service-account",
|
||||
Containers: []core.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}},
|
||||
RestartPolicy: core.RestartPolicyAlways,
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
Volumes: []core.Volume{
|
||||
{
|
||||
Name: "projected-volume",
|
||||
VolumeSource: core.VolumeSource{
|
||||
Projected: &core.ProjectedVolumeSource{
|
||||
Sources: []core.VolumeProjection{
|
||||
{
|
||||
ServiceAccountToken: &core.ServiceAccountTokenProjection{
|
||||
Audience: "foo-audience",
|
||||
ExpirationSeconds: 6000,
|
||||
Path: "foo-path",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, pod := range successCases {
|
||||
if errs := ValidatePod(&pod); len(errs) != 0 {
|
||||
|
@ -1,27 +1,32 @@
|
||||
{
|
||||
"Rules": [
|
||||
{
|
||||
"SelectorRegexp": "k8s[.]io/kubernetes",
|
||||
"AllowedPrefixes": [
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme",
|
||||
"k8s.io/kubernetes/pkg/api/service",
|
||||
"k8s.io/kubernetes/pkg/api/v1/service",
|
||||
"k8s.io/kubernetes/pkg/apis/core",
|
||||
"k8s.io/kubernetes/pkg/cloudprovider",
|
||||
"k8s.io/kubernetes/pkg/credentialprovider",
|
||||
"k8s.io/kubernetes/pkg/features",
|
||||
"k8s.io/kubernetes/pkg/kubelet/apis",
|
||||
"k8s.io/kubernetes/pkg/master/ports",
|
||||
"k8s.io/kubernetes/pkg/util/mount",
|
||||
"k8s.io/kubernetes/pkg/util/file",
|
||||
"k8s.io/kubernetes/pkg/util/net/sets",
|
||||
"k8s.io/kubernetes/pkg/util/resizefs",
|
||||
"k8s.io/kubernetes/pkg/util/strings",
|
||||
"k8s.io/kubernetes/pkg/version",
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
],
|
||||
"ForbiddenPrefixes": [
|
||||
]
|
||||
}
|
||||
{
|
||||
"SelectorRegexp": "k8s[.]io/utils",
|
||||
"AllowedPrefixes": [
|
||||
"k8s.io/utils/net",
|
||||
"k8s.io/utils/nsenter",
|
||||
"k8s.io/utils/io",
|
||||
"k8s.io/utils/strings",
|
||||
"k8s.io/utils/exec",
|
||||
"k8s.io/utils/path"
|
||||
]
|
||||
},
|
||||
{
|
||||
"SelectorRegexp": "k8s[.]io/kubernetes",
|
||||
"AllowedPrefixes": [
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme",
|
||||
"k8s.io/kubernetes/pkg/apis/core",
|
||||
"k8s.io/kubernetes/pkg/cloudprovider",
|
||||
"k8s.io/kubernetes/pkg/credentialprovider",
|
||||
"k8s.io/kubernetes/pkg/features",
|
||||
"k8s.io/kubernetes/pkg/kubelet/apis",
|
||||
"k8s.io/kubernetes/pkg/master/ports",
|
||||
"k8s.io/kubernetes/pkg/util/mount",
|
||||
"k8s.io/kubernetes/pkg/util/resizefs",
|
||||
"k8s.io/kubernetes/pkg/version",
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
],
|
||||
"ForbiddenPrefixes": []
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ go_library(
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/cloudprovider/providers/aws",
|
||||
deps = [
|
||||
"//pkg/api/v1/service:go_default_library",
|
||||
"//pkg/credentialprovider/aws:go_default_library",
|
||||
"//pkg/kubelet/apis:go_default_library",
|
||||
"//pkg/volume:go_default_library",
|
||||
@ -45,6 +44,7 @@ go_library(
|
||||
"//staging/src/k8s.io/client-go/tools/record:go_default_library",
|
||||
"//staging/src/k8s.io/cloud-provider:go_default_library",
|
||||
"//staging/src/k8s.io/cloud-provider/node/helpers:go_default_library",
|
||||
"//staging/src/k8s.io/cloud-provider/service/helpers:go_default_library",
|
||||
"//vendor/github.com/aws/aws-sdk-go/aws:go_default_library",
|
||||
"//vendor/github.com/aws/aws-sdk-go/aws/awserr:go_default_library",
|
||||
"//vendor/github.com/aws/aws-sdk-go/aws/credentials:go_default_library",
|
||||
|
@ -59,7 +59,7 @@ import (
|
||||
"k8s.io/client-go/tools/record"
|
||||
cloudprovider "k8s.io/cloud-provider"
|
||||
nodehelpers "k8s.io/cloud-provider/node/helpers"
|
||||
"k8s.io/kubernetes/pkg/api/v1/service"
|
||||
servicehelpers "k8s.io/cloud-provider/service/helpers"
|
||||
kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
volumeutil "k8s.io/kubernetes/pkg/volume/util"
|
||||
@ -3434,7 +3434,7 @@ func (c *Cloud) EnsureLoadBalancer(ctx context.Context, clusterName string, apiS
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sourceRanges, err := service.GetLoadBalancerSourceRanges(apiService)
|
||||
sourceRanges, err := servicehelpers.GetLoadBalancerSourceRanges(apiService)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -3450,7 +3450,7 @@ func (c *Cloud) EnsureLoadBalancer(ctx context.Context, clusterName string, apiS
|
||||
|
||||
if isNLB(annotations) {
|
||||
|
||||
if path, healthCheckNodePort := service.GetServiceHealthCheckPathPort(apiService); path != "" {
|
||||
if path, healthCheckNodePort := servicehelpers.GetServiceHealthCheckPathPort(apiService); path != "" {
|
||||
for i := range v2Mappings {
|
||||
v2Mappings[i].HealthCheckPort = int64(healthCheckNodePort)
|
||||
v2Mappings[i].HealthCheckPath = path
|
||||
@ -3708,7 +3708,7 @@ func (c *Cloud) EnsureLoadBalancer(ctx context.Context, clusterName string, apiS
|
||||
}
|
||||
}
|
||||
|
||||
if path, healthCheckNodePort := service.GetServiceHealthCheckPathPort(apiService); path != "" {
|
||||
if path, healthCheckNodePort := servicehelpers.GetServiceHealthCheckPathPort(apiService); path != "" {
|
||||
klog.V(4).Infof("service %v (%v) needs health checks on :%d%s)", apiService.Name, loadBalancerName, healthCheckNodePort, path)
|
||||
err = c.ensureLoadBalancerHealthCheck(loadBalancer, "HTTP", healthCheckNodePort, path, annotations)
|
||||
if err != nil {
|
||||
|
@ -36,7 +36,6 @@ go_library(
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/cloudprovider/providers/azure",
|
||||
deps = [
|
||||
"//pkg/api/v1/service:go_default_library",
|
||||
"//pkg/cloudprovider/providers/azure/auth:go_default_library",
|
||||
"//pkg/kubelet/apis:go_default_library",
|
||||
"//pkg/volume:go_default_library",
|
||||
@ -58,6 +57,7 @@ go_library(
|
||||
"//staging/src/k8s.io/client-go/tools/record:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/util/flowcontrol:go_default_library",
|
||||
"//staging/src/k8s.io/cloud-provider:go_default_library",
|
||||
"//staging/src/k8s.io/cloud-provider/service/helpers:go_default_library",
|
||||
"//vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute:go_default_library",
|
||||
"//vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network:go_default_library",
|
||||
"//vendor/github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2018-07-01/storage:go_default_library",
|
||||
@ -93,7 +93,6 @@ go_test(
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/api/v1/service:go_default_library",
|
||||
"//pkg/cloudprovider/providers/azure/auth:go_default_library",
|
||||
"//pkg/kubelet/apis:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
@ -101,6 +100,7 @@ go_test(
|
||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//staging/src/k8s.io/cloud-provider:go_default_library",
|
||||
"//staging/src/k8s.io/cloud-provider/service/helpers:go_default_library",
|
||||
"//vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute:go_default_library",
|
||||
"//vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network:go_default_library",
|
||||
"//vendor/github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2018-07-01/storage:go_default_library",
|
||||
|
@ -27,8 +27,8 @@ import (
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
cloudprovider "k8s.io/cloud-provider"
|
||||
servicehelpers "k8s.io/cloud-provider/service/helpers"
|
||||
"k8s.io/klog"
|
||||
serviceapi "k8s.io/kubernetes/pkg/api/v1/service"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network"
|
||||
"github.com/Azure/go-autorest/autorest/to"
|
||||
@ -888,8 +888,8 @@ func (az *Cloud) reconcileLoadBalancerRule(
|
||||
return expectedProbes, expectedRules, err
|
||||
}
|
||||
|
||||
if serviceapi.NeedsHealthCheck(service) {
|
||||
podPresencePath, podPresencePort := serviceapi.GetServiceHealthCheckPathPort(service)
|
||||
if servicehelpers.NeedsHealthCheck(service) {
|
||||
podPresencePath, podPresencePort := servicehelpers.GetServiceHealthCheckPathPort(service)
|
||||
|
||||
expectedProbes = append(expectedProbes, network.Probe{
|
||||
Name: &lbRuleName,
|
||||
@ -983,7 +983,7 @@ func (az *Cloud) reconcileSecurityGroup(clusterName string, service *v1.Service,
|
||||
destinationIPAddress = "*"
|
||||
}
|
||||
|
||||
sourceRanges, err := serviceapi.GetLoadBalancerSourceRanges(service)
|
||||
sourceRanges, err := servicehelpers.GetLoadBalancerSourceRanges(service)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -992,7 +992,7 @@ func (az *Cloud) reconcileSecurityGroup(clusterName string, service *v1.Service,
|
||||
return nil, err
|
||||
}
|
||||
var sourceAddressPrefixes []string
|
||||
if (sourceRanges == nil || serviceapi.IsAllowAll(sourceRanges)) && len(serviceTags) == 0 {
|
||||
if (sourceRanges == nil || servicehelpers.IsAllowAll(sourceRanges)) && len(serviceTags) == 0 {
|
||||
if !requiresInternalLoadBalancer(service) {
|
||||
sourceAddressPrefixes = []string{"Internet"}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
serviceapi "k8s.io/kubernetes/pkg/api/v1/service"
|
||||
servicehelpers "k8s.io/cloud-provider/service/helpers"
|
||||
"k8s.io/kubernetes/pkg/cloudprovider/providers/azure/auth"
|
||||
kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
|
||||
|
||||
@ -1231,8 +1231,8 @@ func validateLoadBalancer(t *testing.T, loadBalancer *network.LoadBalancer, serv
|
||||
|
||||
expectedProbeCount++
|
||||
foundProbe := false
|
||||
if serviceapi.NeedsHealthCheck(&svc) {
|
||||
path, port := serviceapi.GetServiceHealthCheckPathPort(&svc)
|
||||
if servicehelpers.NeedsHealthCheck(&svc) {
|
||||
path, port := servicehelpers.GetServiceHealthCheckPathPort(&svc)
|
||||
for _, actualProbe := range *loadBalancer.Probes {
|
||||
if strings.EqualFold(*actualProbe.Name, wantedRuleName) &&
|
||||
*actualProbe.Port == port &&
|
||||
|
@ -46,9 +46,7 @@ go_library(
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/cloudprovider/providers/gce",
|
||||
deps = [
|
||||
"//pkg/api/v1/service:go_default_library",
|
||||
"//pkg/kubelet/apis:go_default_library",
|
||||
"//pkg/util/net/sets:go_default_library",
|
||||
"//pkg/volume:go_default_library",
|
||||
"//pkg/volume/util:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
@ -73,6 +71,7 @@ go_library(
|
||||
"//staging/src/k8s.io/client-go/util/flowcontrol:go_default_library",
|
||||
"//staging/src/k8s.io/cloud-provider:go_default_library",
|
||||
"//staging/src/k8s.io/cloud-provider/features:go_default_library",
|
||||
"//staging/src/k8s.io/cloud-provider/service/helpers:go_default_library",
|
||||
"//vendor/cloud.google.com/go/compute/metadata:go_default_library",
|
||||
"//vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud:go_default_library",
|
||||
"//vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/filter:go_default_library",
|
||||
@ -89,6 +88,7 @@ go_library(
|
||||
"//vendor/google.golang.org/api/tpu/v1:go_default_library",
|
||||
"//vendor/gopkg.in/gcfg.v1:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
"//vendor/k8s.io/utils/net:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@ -109,15 +109,14 @@ go_test(
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/api/v1/service:go_default_library",
|
||||
"//pkg/kubelet/apis:go_default_library",
|
||||
"//pkg/util/net/sets:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/tools/record:go_default_library",
|
||||
"//staging/src/k8s.io/cloud-provider:go_default_library",
|
||||
"//staging/src/k8s.io/cloud-provider/service/helpers:go_default_library",
|
||||
"//vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud:go_default_library",
|
||||
"//vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta:go_default_library",
|
||||
"//vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/mock:go_default_library",
|
||||
@ -128,6 +127,7 @@ go_test(
|
||||
"//vendor/google.golang.org/api/compute/v0.beta:go_default_library",
|
||||
"//vendor/google.golang.org/api/compute/v1:go_default_library",
|
||||
"//vendor/google.golang.org/api/googleapi:go_default_library",
|
||||
"//vendor/k8s.io/utils/net:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -24,16 +24,16 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/klog"
|
||||
|
||||
"github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud"
|
||||
"k8s.io/api/core/v1"
|
||||
cloudprovider "k8s.io/cloud-provider"
|
||||
netsets "k8s.io/kubernetes/pkg/util/net/sets"
|
||||
utilnet "k8s.io/utils/net"
|
||||
)
|
||||
|
||||
type cidrs struct {
|
||||
ipn netsets.IPNet
|
||||
ipn utilnet.IPNetSet
|
||||
isSet bool
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ var (
|
||||
func init() {
|
||||
var err error
|
||||
// LB L7 proxies and all L3/4/7 health checkers have client addresses within these known CIDRs.
|
||||
lbSrcRngsFlag.ipn, err = netsets.ParseIPNets([]string{"130.211.0.0/22", "35.191.0.0/16", "209.85.152.0/22", "209.85.204.0/22"}...)
|
||||
lbSrcRngsFlag.ipn, err = utilnet.ParseIPNets([]string{"130.211.0.0/22", "35.191.0.0/16", "209.85.152.0/22", "209.85.204.0/22"}...)
|
||||
if err != nil {
|
||||
panic("Incorrect default GCE L7 source ranges")
|
||||
}
|
||||
@ -64,7 +64,7 @@ func (c *cidrs) Set(value string) error {
|
||||
// On first Set(), clear the original defaults
|
||||
if !c.isSet {
|
||||
c.isSet = true
|
||||
c.ipn = make(netsets.IPNet)
|
||||
c.ipn = make(utilnet.IPNetSet)
|
||||
} else {
|
||||
return fmt.Errorf("GCE LB CIDRs have already been set")
|
||||
}
|
||||
|
@ -28,8 +28,8 @@ import (
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
apiservice "k8s.io/kubernetes/pkg/api/v1/service"
|
||||
netsets "k8s.io/kubernetes/pkg/util/net/sets"
|
||||
servicehelpers "k8s.io/cloud-provider/service/helpers"
|
||||
utilnet "k8s.io/utils/net"
|
||||
|
||||
computealpha "google.golang.org/api/compute/v0.alpha"
|
||||
compute "google.golang.org/api/compute/v1"
|
||||
@ -162,7 +162,7 @@ func (g *Cloud) ensureExternalLoadBalancer(clusterName string, clusterID string,
|
||||
// is because the forwarding rule is used as the indicator that the load
|
||||
// balancer is fully created - it's what getLoadBalancer checks for.
|
||||
// Check if user specified the allow source range
|
||||
sourceRanges, err := apiservice.GetLoadBalancerSourceRanges(apiService)
|
||||
sourceRanges, err := servicehelpers.GetLoadBalancerSourceRanges(apiService)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -206,7 +206,7 @@ func (g *Cloud) ensureExternalLoadBalancer(clusterName string, clusterID string,
|
||||
if err != nil && !isHTTPErrorCode(err, http.StatusNotFound) {
|
||||
return nil, fmt.Errorf("error checking HTTP health check for load balancer (%s): %v", lbRefStr, err)
|
||||
}
|
||||
if path, healthCheckNodePort := apiservice.GetServiceHealthCheckPathPort(apiService); path != "" {
|
||||
if path, healthCheckNodePort := servicehelpers.GetServiceHealthCheckPathPort(apiService); path != "" {
|
||||
klog.V(4).Infof("ensureExternalLoadBalancer(%s): Service needs local traffic health checks on: %d%s.", lbRefStr, healthCheckNodePort, path)
|
||||
if hcLocalTrafficExisting == nil {
|
||||
// This logic exists to detect a transition for non-OnlyLocal to OnlyLocal service
|
||||
@ -292,7 +292,7 @@ func (g *Cloud) ensureExternalLoadBalancerDeleted(clusterName, clusterID string,
|
||||
lbRefStr := fmt.Sprintf("%v(%v)", loadBalancerName, serviceName)
|
||||
|
||||
var hcNames []string
|
||||
if path, _ := apiservice.GetServiceHealthCheckPathPort(service); path != "" {
|
||||
if path, _ := servicehelpers.GetServiceHealthCheckPathPort(service); path != "" {
|
||||
hcToDelete, err := g.GetHTTPHealthCheck(loadBalancerName)
|
||||
if err != nil && !isHTTPErrorCode(err, http.StatusNotFound) {
|
||||
klog.Infof("ensureExternalLoadBalancerDeleted(%s): Failed to retrieve health check:%v.", lbRefStr, err)
|
||||
@ -819,7 +819,7 @@ func translateAffinityType(affinityType v1.ServiceAffinity) string {
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Cloud) firewallNeedsUpdate(name, serviceName, region, ipAddress string, ports []v1.ServicePort, sourceRanges netsets.IPNet) (exists bool, needsUpdate bool, err error) {
|
||||
func (g *Cloud) firewallNeedsUpdate(name, serviceName, region, ipAddress string, ports []v1.ServicePort, sourceRanges utilnet.IPNetSet) (exists bool, needsUpdate bool, err error) {
|
||||
fw, err := g.GetFirewall(MakeFirewallName(name))
|
||||
if err != nil {
|
||||
if isHTTPErrorCode(err, http.StatusNotFound) {
|
||||
@ -843,7 +843,7 @@ func (g *Cloud) firewallNeedsUpdate(name, serviceName, region, ipAddress string,
|
||||
}
|
||||
// The service controller already verified that the protocol matches on all ports, no need to check.
|
||||
|
||||
actualSourceRanges, err := netsets.ParseIPNets(fw.SourceRanges...)
|
||||
actualSourceRanges, err := utilnet.ParseIPNets(fw.SourceRanges...)
|
||||
if err != nil {
|
||||
// This really shouldn't happen... GCE has returned something unexpected
|
||||
klog.Warningf("Error parsing firewall SourceRanges: %v", fw.SourceRanges)
|
||||
@ -934,7 +934,7 @@ func createForwardingRule(s CloudForwardingRuleService, name, serviceName, regio
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Cloud) createFirewall(svc *v1.Service, name, region, desc string, sourceRanges netsets.IPNet, ports []v1.ServicePort, hosts []*gceInstance) error {
|
||||
func (g *Cloud) createFirewall(svc *v1.Service, name, region, desc string, sourceRanges utilnet.IPNetSet, ports []v1.ServicePort, hosts []*gceInstance) error {
|
||||
firewall, err := g.firewallObject(name, region, desc, sourceRanges, ports, hosts)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -952,7 +952,7 @@ func (g *Cloud) createFirewall(svc *v1.Service, name, region, desc string, sourc
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Cloud) updateFirewall(svc *v1.Service, name, region, desc string, sourceRanges netsets.IPNet, ports []v1.ServicePort, hosts []*gceInstance) error {
|
||||
func (g *Cloud) updateFirewall(svc *v1.Service, name, region, desc string, sourceRanges utilnet.IPNetSet, ports []v1.ServicePort, hosts []*gceInstance) error {
|
||||
firewall, err := g.firewallObject(name, region, desc, sourceRanges, ports, hosts)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -971,7 +971,7 @@ func (g *Cloud) updateFirewall(svc *v1.Service, name, region, desc string, sourc
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Cloud) firewallObject(name, region, desc string, sourceRanges netsets.IPNet, ports []v1.ServicePort, hosts []*gceInstance) (*compute.Firewall, error) {
|
||||
func (g *Cloud) firewallObject(name, region, desc string, sourceRanges utilnet.IPNetSet, ports []v1.ServicePort, hosts []*gceInstance) (*compute.Firewall, error) {
|
||||
allowedPorts := make([]string, len(ports))
|
||||
for ix := range ports {
|
||||
allowedPorts[ix] = strconv.Itoa(int(ports[ix].Port))
|
||||
|
@ -34,7 +34,7 @@ import (
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/tools/record"
|
||||
netsets "k8s.io/kubernetes/pkg/util/net/sets"
|
||||
utilnet "k8s.io/utils/net"
|
||||
)
|
||||
|
||||
func TestEnsureStaticIP(t *testing.T) {
|
||||
@ -620,10 +620,10 @@ func TestFirewallNeedsUpdate(t *testing.T) {
|
||||
ipAddr := status.Ingress[0].IP
|
||||
lbName := gce.GetLoadBalancerName(context.TODO(), "", svc)
|
||||
|
||||
ipnet, err := netsets.ParseIPNets("0.0.0.0/0")
|
||||
ipnet, err := utilnet.ParseIPNets("0.0.0.0/0")
|
||||
require.NoError(t, err)
|
||||
|
||||
wrongIpnet, err := netsets.ParseIPNets("1.0.0.0/10")
|
||||
wrongIpnet, err := utilnet.ParseIPNets("1.0.0.0/10")
|
||||
require.NoError(t, err)
|
||||
|
||||
fw, err := gce.GetFirewall(MakeFirewallName(lbName))
|
||||
@ -633,7 +633,7 @@ func TestFirewallNeedsUpdate(t *testing.T) {
|
||||
lbName string
|
||||
ipAddr string
|
||||
ports []v1.ServicePort
|
||||
ipnet netsets.IPNet
|
||||
ipnet utilnet.IPNetSet
|
||||
fwIPProtocol string
|
||||
getHook func(context.Context, *meta.Key, *cloud.MockFirewalls) (bool, *ga.Firewall, error)
|
||||
sourceRange string
|
||||
@ -864,7 +864,7 @@ func TestCreateAndUpdateFirewallSucceedsOnXPN(t *testing.T) {
|
||||
hostNames := nodeNames(nodes)
|
||||
hosts, err := gce.getInstancesByNames(hostNames)
|
||||
require.NoError(t, err)
|
||||
ipnet, err := netsets.ParseIPNets("10.0.0.0/20")
|
||||
ipnet, err := utilnet.ParseIPNets("10.0.0.0/20")
|
||||
require.NoError(t, err)
|
||||
gce.createFirewall(
|
||||
svc,
|
||||
|
@ -27,8 +27,8 @@ import (
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
servicehelpers "k8s.io/cloud-provider/service/helpers"
|
||||
"k8s.io/klog"
|
||||
v1_service "k8s.io/kubernetes/pkg/api/v1/service"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -69,12 +69,12 @@ func (g *Cloud) ensureInternalLoadBalancer(clusterName, clusterID string, svc *v
|
||||
|
||||
// Ensure health check exists before creating the backend service. The health check is shared
|
||||
// if externalTrafficPolicy=Cluster.
|
||||
sharedHealthCheck := !v1_service.RequestsOnlyLocalTraffic(svc)
|
||||
sharedHealthCheck := !servicehelpers.RequestsOnlyLocalTraffic(svc)
|
||||
hcName := makeHealthCheckName(loadBalancerName, clusterID, sharedHealthCheck)
|
||||
hcPath, hcPort := GetNodesHealthCheckPath(), GetNodesHealthCheckPort()
|
||||
if !sharedHealthCheck {
|
||||
// Service requires a special health check, retrieve the OnlyLocal port & path
|
||||
hcPath, hcPort = v1_service.GetServiceHealthCheckPathPort(svc)
|
||||
hcPath, hcPort = servicehelpers.GetServiceHealthCheckPathPort(svc)
|
||||
}
|
||||
hc, err := g.ensureInternalHealthCheck(hcName, nm, sharedHealthCheck, hcPath, hcPort)
|
||||
if err != nil {
|
||||
@ -224,7 +224,7 @@ func (g *Cloud) ensureInternalLoadBalancerDeleted(clusterName, clusterID string,
|
||||
_, protocol := getPortsAndProtocol(svc.Spec.Ports)
|
||||
scheme := cloud.SchemeInternal
|
||||
sharedBackend := shareBackendService(svc)
|
||||
sharedHealthCheck := !v1_service.RequestsOnlyLocalTraffic(svc)
|
||||
sharedHealthCheck := !servicehelpers.RequestsOnlyLocalTraffic(svc)
|
||||
|
||||
g.sharedResourceLock.Lock()
|
||||
defer g.sharedResourceLock.Unlock()
|
||||
@ -367,7 +367,7 @@ func (g *Cloud) ensureInternalFirewalls(loadBalancerName, ipAddress, clusterID s
|
||||
// First firewall is for ingress traffic
|
||||
fwDesc := makeFirewallDescription(nm.String(), ipAddress)
|
||||
ports, protocol := getPortsAndProtocol(svc.Spec.Ports)
|
||||
sourceRanges, err := v1_service.GetLoadBalancerSourceRanges(svc)
|
||||
sourceRanges, err := servicehelpers.GetLoadBalancerSourceRanges(svc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -581,7 +581,7 @@ func (g *Cloud) ensureInternalBackendServiceGroups(name string, igLinks []string
|
||||
}
|
||||
|
||||
func shareBackendService(svc *v1.Service) bool {
|
||||
return GetLoadBalancerAnnotationBackendShare(svc) && !v1_service.RequestsOnlyLocalTraffic(svc)
|
||||
return GetLoadBalancerAnnotationBackendShare(svc) && !servicehelpers.RequestsOnlyLocalTraffic(svc)
|
||||
}
|
||||
|
||||
func backendsFromGroupLinks(igLinks []string) (backends []*compute.Backend) {
|
||||
|
@ -31,7 +31,7 @@ import (
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/tools/record"
|
||||
v1_service "k8s.io/kubernetes/pkg/api/v1/service"
|
||||
servicehelper "k8s.io/cloud-provider/service/helpers"
|
||||
)
|
||||
|
||||
func createInternalLoadBalancer(gce *Cloud, svc *v1.Service, existingFwdRule *compute.ForwardingRule, nodeNames []string, clusterName, clusterID, zoneName string) (*v1.LoadBalancerStatus, error) {
|
||||
@ -169,7 +169,7 @@ func TestEnsureInternalLoadBalancerWithExistingResources(t *testing.T) {
|
||||
nm := types.NamespacedName{Name: svc.Name, Namespace: svc.Namespace}
|
||||
lbName := gce.GetLoadBalancerName(context.TODO(), "", svc)
|
||||
|
||||
sharedHealthCheck := !v1_service.RequestsOnlyLocalTraffic(svc)
|
||||
sharedHealthCheck := !servicehelper.RequestsOnlyLocalTraffic(svc)
|
||||
hcName := makeHealthCheckName(lbName, vals.ClusterID, sharedHealthCheck)
|
||||
hcPath, hcPort := GetNodesHealthCheckPath(), GetNodesHealthCheckPort()
|
||||
existingHC := newInternalLBHealthCheck(hcName, nm, sharedHealthCheck, hcPath, hcPort)
|
||||
@ -224,7 +224,7 @@ func TestEnsureInternalLoadBalancerClearPreviousResources(t *testing.T) {
|
||||
}
|
||||
gce.CreateFirewall(existingFirewall)
|
||||
|
||||
sharedHealthCheck := !v1_service.RequestsOnlyLocalTraffic(svc)
|
||||
sharedHealthCheck := !servicehelper.RequestsOnlyLocalTraffic(svc)
|
||||
hcName := makeHealthCheckName(lbName, vals.ClusterID, sharedHealthCheck)
|
||||
hcPath, hcPort := GetNodesHealthCheckPath(), GetNodesHealthCheckPort()
|
||||
nm := types.NamespacedName{Name: svc.Name, Namespace: svc.Namespace}
|
||||
@ -278,7 +278,7 @@ func TestEnsureInternalLoadBalancerHealthCheckConfigurable(t *testing.T) {
|
||||
svc := fakeLoadbalancerService(string(LBTypeInternal))
|
||||
lbName := gce.GetLoadBalancerName(context.TODO(), "", svc)
|
||||
|
||||
sharedHealthCheck := !v1_service.RequestsOnlyLocalTraffic(svc)
|
||||
sharedHealthCheck := !servicehelper.RequestsOnlyLocalTraffic(svc)
|
||||
hcName := makeHealthCheckName(lbName, vals.ClusterID, sharedHealthCheck)
|
||||
hcPath, hcPort := GetNodesHealthCheckPath(), GetNodesHealthCheckPort()
|
||||
nm := types.NamespacedName{Name: svc.Name, Namespace: svc.Namespace}
|
||||
|
@ -35,7 +35,7 @@ import (
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/tools/record"
|
||||
v1_service "k8s.io/kubernetes/pkg/api/v1/service"
|
||||
servicehelpers "k8s.io/cloud-provider/service/helpers"
|
||||
kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
|
||||
)
|
||||
|
||||
@ -211,7 +211,7 @@ func assertInternalLbResources(t *testing.T, gce *Cloud, apiService *v1.Service,
|
||||
}
|
||||
|
||||
// Check that HealthCheck is created
|
||||
sharedHealthCheck := !v1_service.RequestsOnlyLocalTraffic(apiService)
|
||||
sharedHealthCheck := !servicehelpers.RequestsOnlyLocalTraffic(apiService)
|
||||
hcName := makeHealthCheckName(lbName, vals.ClusterID, sharedHealthCheck)
|
||||
healthcheck, err := gce.GetHealthCheck(hcName)
|
||||
require.NoError(t, err)
|
||||
@ -243,7 +243,7 @@ func assertInternalLbResources(t *testing.T, gce *Cloud, apiService *v1.Service,
|
||||
|
||||
func assertInternalLbResourcesDeleted(t *testing.T, gce *Cloud, apiService *v1.Service, vals TestClusterValues, firewallsDeleted bool) {
|
||||
lbName := gce.GetLoadBalancerName(context.TODO(), "", apiService)
|
||||
sharedHealthCheck := !v1_service.RequestsOnlyLocalTraffic(apiService)
|
||||
sharedHealthCheck := !servicehelpers.RequestsOnlyLocalTraffic(apiService)
|
||||
hcName := makeHealthCheckName(lbName, vals.ClusterID, sharedHealthCheck)
|
||||
|
||||
// ensureExternalLoadBalancer and ensureInternalLoadBalancer both create
|
||||
|
@ -20,7 +20,6 @@ go_library(
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/cloudprovider/providers/openstack",
|
||||
deps = [
|
||||
"//pkg/api/v1/service:go_default_library",
|
||||
"//pkg/kubelet/apis:go_default_library",
|
||||
"//pkg/util/mount:go_default_library",
|
||||
"//pkg/volume:go_default_library",
|
||||
@ -34,6 +33,7 @@ go_library(
|
||||
"//staging/src/k8s.io/client-go/util/cert:go_default_library",
|
||||
"//staging/src/k8s.io/cloud-provider:go_default_library",
|
||||
"//staging/src/k8s.io/cloud-provider/node/helpers:go_default_library",
|
||||
"//staging/src/k8s.io/cloud-provider/service/helpers:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions:go_default_library",
|
||||
|
@ -44,7 +44,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
cloudprovider "k8s.io/cloud-provider"
|
||||
"k8s.io/kubernetes/pkg/api/v1/service"
|
||||
servicehelpers "k8s.io/cloud-provider/service/helpers"
|
||||
)
|
||||
|
||||
// Note: when creating a new Loadbalancer (VM), it can take some time before it is ready for use,
|
||||
@ -722,12 +722,12 @@ func (lbaas *LbaasV2) EnsureLoadBalancer(ctx context.Context, clusterName string
|
||||
}
|
||||
}
|
||||
|
||||
sourceRanges, err := service.GetLoadBalancerSourceRanges(apiService)
|
||||
sourceRanges, err := servicehelpers.GetLoadBalancerSourceRanges(apiService)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get source ranges for loadbalancer service %s/%s: %v", apiService.Namespace, apiService.Name, err)
|
||||
}
|
||||
|
||||
if !service.IsAllowAll(sourceRanges) && !lbaas.opts.ManageSecurityGroups {
|
||||
if !servicehelpers.IsAllowAll(sourceRanges) && !lbaas.opts.ManageSecurityGroups {
|
||||
return nil, fmt.Errorf("source range restrictions are not supported for openstack load balancers without managing security groups")
|
||||
}
|
||||
|
||||
@ -1030,7 +1030,7 @@ func (lbaas *LbaasV2) ensureSecurityGroup(clusterName string, apiService *v1.Ser
|
||||
}
|
||||
|
||||
// get service source ranges
|
||||
sourceRanges, err := service.GetLoadBalancerSourceRanges(apiService)
|
||||
sourceRanges, err := servicehelpers.GetLoadBalancerSourceRanges(apiService)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get source ranges for loadbalancer service %s/%s: %v", apiService.Namespace, apiService.Name, err)
|
||||
}
|
||||
|
@ -307,7 +307,6 @@
|
||||
"k8s.io/kubernetes/pkg/scheduler/api",
|
||||
"k8s.io/kubernetes/pkg/scheduler/util",
|
||||
"k8s.io/kubernetes/pkg/security/apparmor",
|
||||
"k8s.io/kubernetes/pkg/util/net/sets",
|
||||
"k8s.io/kubernetes/pkg/util/parsers",
|
||||
"k8s.io/kubernetes/pkg/fieldpath",
|
||||
"k8s.io/kubernetes/pkg/scheduler/volumebinder",
|
||||
@ -342,7 +341,8 @@
|
||||
"k8s.io/utils/path",
|
||||
"k8s.io/utils/pointer",
|
||||
"k8s.io/utils/exec",
|
||||
"k8s.io/utils/strings"
|
||||
"k8s.io/utils/strings",
|
||||
"k8s.io/utils/net"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -59,6 +59,9 @@ type cfsslSigner struct {
|
||||
sigAlgo x509.SignatureAlgorithm
|
||||
client clientset.Interface
|
||||
certificateDuration time.Duration
|
||||
|
||||
// nowFn returns the current time. We have here for unit testing
|
||||
nowFn func() time.Time
|
||||
}
|
||||
|
||||
func newCFSSLSigner(caFile, caKeyFile string, client clientset.Interface, certificateDuration time.Duration) (*cfsslSigner, error) {
|
||||
@ -92,6 +95,7 @@ func newCFSSLSigner(caFile, caKeyFile string, client clientset.Interface, certif
|
||||
sigAlgo: signer.DefaultSigAlgo(priv),
|
||||
client: client,
|
||||
certificateDuration: certificateDuration,
|
||||
nowFn: time.Now,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -115,11 +119,21 @@ func (s *cfsslSigner) sign(csr *capi.CertificateSigningRequest) (*capi.Certifica
|
||||
for _, usage := range csr.Spec.Usages {
|
||||
usages = append(usages, string(usage))
|
||||
}
|
||||
|
||||
certExpiryDuration := s.certificateDuration
|
||||
durationUntilExpiry := s.ca.NotAfter.Sub(s.nowFn())
|
||||
if durationUntilExpiry <= 0 {
|
||||
return nil, fmt.Errorf("the signer has expired: %v", s.ca.NotAfter)
|
||||
}
|
||||
if durationUntilExpiry < certExpiryDuration {
|
||||
certExpiryDuration = durationUntilExpiry
|
||||
}
|
||||
|
||||
policy := &config.Signing{
|
||||
Default: &config.SigningProfile{
|
||||
Usage: usages,
|
||||
Expiry: s.certificateDuration,
|
||||
ExpiryString: s.certificateDuration.String(),
|
||||
Expiry: certExpiryDuration,
|
||||
ExpiryString: certExpiryDuration.String(),
|
||||
},
|
||||
}
|
||||
cfs, err := local.NewSigner(s.priv, s.ca, s.sigAlgo, policy)
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
"crypto/x509"
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -28,10 +29,16 @@ import (
|
||||
)
|
||||
|
||||
func TestSigner(t *testing.T) {
|
||||
testNow := time.Now()
|
||||
testNowFn := func() time.Time {
|
||||
return testNow
|
||||
}
|
||||
|
||||
s, err := newCFSSLSigner("./testdata/ca.crt", "./testdata/ca.key", nil, 1*time.Hour)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create signer: %v", err)
|
||||
}
|
||||
s.nowFn = testNowFn
|
||||
|
||||
csrb, err := ioutil.ReadFile("./testdata/kubelet.csr")
|
||||
if err != nil {
|
||||
@ -81,4 +88,108 @@ func TestSigner(t *testing.T) {
|
||||
if !reflect.DeepEqual(crt.ExtKeyUsage, []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth}) {
|
||||
t.Errorf("bad extended key usage")
|
||||
}
|
||||
|
||||
expectedTime := testNow.Add(1 * time.Hour)
|
||||
// there is some jitter that we need to tolerate
|
||||
diff := expectedTime.Sub(crt.NotAfter)
|
||||
if diff > 10*time.Minute || diff < -10*time.Minute {
|
||||
t.Fatal(crt.NotAfter)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSignerExpired(t *testing.T) {
|
||||
hundredYearsFromNowFn := func() time.Time {
|
||||
return time.Now().Add(24 * time.Hour * 365 * 100)
|
||||
}
|
||||
s, err := newCFSSLSigner("./testdata/ca.crt", "./testdata/ca.key", nil, 1*time.Hour)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create signer: %v", err)
|
||||
}
|
||||
s.nowFn = hundredYearsFromNowFn
|
||||
|
||||
csrb, err := ioutil.ReadFile("./testdata/kubelet.csr")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read CSR: %v", err)
|
||||
}
|
||||
|
||||
csr := &capi.CertificateSigningRequest{
|
||||
Spec: capi.CertificateSigningRequestSpec{
|
||||
Request: []byte(csrb),
|
||||
Usages: []capi.KeyUsage{
|
||||
capi.UsageSigning,
|
||||
capi.UsageKeyEncipherment,
|
||||
capi.UsageServerAuth,
|
||||
capi.UsageClientAuth,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
_, err = s.sign(csr)
|
||||
if err == nil {
|
||||
t.Fatal("missing error")
|
||||
}
|
||||
if !strings.HasPrefix(err.Error(), "the signer has expired") {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDurationLongerThanExpiry(t *testing.T) {
|
||||
testNow := time.Now()
|
||||
testNowFn := func() time.Time {
|
||||
return testNow
|
||||
}
|
||||
|
||||
hundredYears := 24 * time.Hour * 365 * 100
|
||||
s, err := newCFSSLSigner("./testdata/ca.crt", "./testdata/ca.key", nil, hundredYears)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create signer: %v", err)
|
||||
}
|
||||
s.nowFn = testNowFn
|
||||
|
||||
csrb, err := ioutil.ReadFile("./testdata/kubelet.csr")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read CSR: %v", err)
|
||||
}
|
||||
|
||||
csr := &capi.CertificateSigningRequest{
|
||||
Spec: capi.CertificateSigningRequestSpec{
|
||||
Request: []byte(csrb),
|
||||
Usages: []capi.KeyUsage{
|
||||
capi.UsageSigning,
|
||||
capi.UsageKeyEncipherment,
|
||||
capi.UsageServerAuth,
|
||||
capi.UsageClientAuth,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
_, err = s.sign(csr)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to sign CSR: %v", err)
|
||||
}
|
||||
|
||||
// now we just need to verify that the expiry is based on the signing cert
|
||||
certData := csr.Status.Certificate
|
||||
if len(certData) == 0 {
|
||||
t.Fatalf("expected a certificate after signing")
|
||||
}
|
||||
|
||||
certs, err := cert.ParseCertsPEM(certData)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to parse certificate: %v", err)
|
||||
}
|
||||
if len(certs) != 1 {
|
||||
t.Fatalf("expected one certificate")
|
||||
}
|
||||
|
||||
crt := certs[0]
|
||||
expected, err := time.Parse("2006-01-02 15:04:05.999999999 -0700 MST", "2044-05-09 00:20:11 +0000 UTC")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// there is some jitter that we need to tolerate
|
||||
diff := expected.Sub(crt.NotAfter)
|
||||
if diff > 10*time.Minute || diff < -10*time.Minute {
|
||||
t.Fatal(crt.NotAfter)
|
||||
}
|
||||
}
|
||||
|
@ -19,8 +19,6 @@ package garbagecollector
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/klog"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@ -28,6 +26,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/util/retry"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
// cluster scoped resources don't have namespaces. Default to the item's namespace, but clear it for cluster scoped resources
|
||||
@ -81,7 +80,7 @@ func (gc *GarbageCollector) patchObject(item objectReference, patch []byte, pt t
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return gc.dynamicClient.Resource(resource).Namespace(resourceDefaultNamespace(namespaced, item.Namespace)).Patch(item.Name, pt, patch, metav1.UpdateOptions{})
|
||||
return gc.dynamicClient.Resource(resource).Namespace(resourceDefaultNamespace(namespaced, item.Namespace)).Patch(item.Name, pt, patch, metav1.PatchOptions{})
|
||||
}
|
||||
|
||||
// TODO: Using Patch when strategicmerge supports deleting an entry from a
|
||||
|
@ -410,7 +410,7 @@ func (a *HorizontalController) computeStatusForResourceMetric(currentReplicas in
|
||||
return 0, time.Time{}, "", fmt.Errorf("failed to get %s utilization: %v", metricSpec.Resource.Name, err)
|
||||
}
|
||||
metricNameProposal := fmt.Sprintf("%s resource", metricSpec.Resource.Name)
|
||||
status = &autoscalingv2.MetricStatus{
|
||||
*status = autoscalingv2.MetricStatus{
|
||||
Type: autoscalingv2.ResourceMetricSourceType,
|
||||
Resource: &autoscalingv2.ResourceMetricStatus{
|
||||
Name: metricSpec.Resource.Name,
|
||||
|
@ -173,7 +173,7 @@ func (g *dockerConfigUrlKeyProvider) Provide() credentialprovider.DockerConfig {
|
||||
return credentialprovider.DockerConfig{}
|
||||
}
|
||||
|
||||
// runcWithBackoff runs input function `f` with an exponential backoff.
|
||||
// runWithBackoff runs input function `f` with an exponential backoff.
|
||||
// Note that this method can block indefinitely.
|
||||
func runWithBackoff(f func() ([]byte, error)) []byte {
|
||||
var backoff = 100 * time.Millisecond
|
||||
|
@ -163,6 +163,7 @@ const (
|
||||
|
||||
// owner: @derekwaynecarr
|
||||
// beta: v1.10
|
||||
// GA: v1.14
|
||||
//
|
||||
// Enable pods to consume pre-allocated huge pages of varying page sizes
|
||||
HugePages utilfeature.Feature = "HugePages"
|
||||
@ -424,7 +425,7 @@ var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureS
|
||||
RotateKubeletClientCertificate: {Default: true, PreRelease: utilfeature.Beta},
|
||||
PersistentLocalVolumes: {Default: true, PreRelease: utilfeature.Beta},
|
||||
LocalStorageCapacityIsolation: {Default: true, PreRelease: utilfeature.Beta},
|
||||
HugePages: {Default: true, PreRelease: utilfeature.Beta},
|
||||
HugePages: {Default: true, PreRelease: utilfeature.GA, LockToDefault: true}, // remove in 1.16
|
||||
Sysctls: {Default: true, PreRelease: utilfeature.Beta},
|
||||
DebugContainers: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
PodShareProcessNamespace: {Default: true, PreRelease: utilfeature.Beta},
|
||||
@ -484,6 +485,7 @@ var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureS
|
||||
genericfeatures.APIResponseCompression: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
genericfeatures.APIListChunking: {Default: true, PreRelease: utilfeature.Beta},
|
||||
genericfeatures.DryRun: {Default: true, PreRelease: utilfeature.Beta},
|
||||
genericfeatures.ServerSideApply: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
|
||||
// inherited features from apiextensions-apiserver, relisted here to get a conflict if it is changed
|
||||
// unintentionally on either side:
|
||||
|
@ -132,7 +132,6 @@
|
||||
"k8s.io/kubernetes/pkg/util/labels",
|
||||
"k8s.io/kubernetes/pkg/util/metrics",
|
||||
"k8s.io/kubernetes/pkg/util/mount",
|
||||
"k8s.io/kubernetes/pkg/util/net/sets",
|
||||
"k8s.io/kubernetes/pkg/util/node",
|
||||
"k8s.io/kubernetes/pkg/util/parsers",
|
||||
"k8s.io/kubernetes/pkg/util/slice",
|
||||
@ -144,7 +143,8 @@
|
||||
"k8s.io/utils/nsenter",
|
||||
"k8s.io/utils/io",
|
||||
"k8s.io/utils/path",
|
||||
"k8s.io/utils/pointer"
|
||||
"k8s.io/utils/pointer",
|
||||
"k8s.io/utils/net"
|
||||
],
|
||||
"ForbiddenPrefixes": []
|
||||
}]
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -65,16 +66,18 @@ type ApplyOptions struct {
|
||||
DeleteFlags *delete.DeleteFlags
|
||||
DeleteOptions *delete.DeleteOptions
|
||||
|
||||
Selector string
|
||||
DryRun bool
|
||||
ServerDryRun bool
|
||||
Prune bool
|
||||
PruneResources []pruneResource
|
||||
cmdBaseName string
|
||||
All bool
|
||||
Overwrite bool
|
||||
OpenAPIPatch bool
|
||||
PruneWhitelist []string
|
||||
ServerSideApply bool
|
||||
ForceConflicts bool
|
||||
Selector string
|
||||
DryRun bool
|
||||
ServerDryRun bool
|
||||
Prune bool
|
||||
PruneResources []pruneResource
|
||||
cmdBaseName string
|
||||
All bool
|
||||
Overwrite bool
|
||||
OpenAPIPatch bool
|
||||
PruneWhitelist []string
|
||||
|
||||
Validator validation.Schema
|
||||
Builder *resource.Builder
|
||||
@ -178,6 +181,7 @@ func NewCmdApply(baseName string, f cmdutil.Factory, ioStreams genericclioptions
|
||||
cmd.Flags().BoolVar(&o.ServerDryRun, "server-dry-run", o.ServerDryRun, "If true, request will be sent to server with dry-run flag, which means the modifications won't be persisted. This is an alpha feature and flag.")
|
||||
cmd.Flags().Bool("dry-run", false, "If true, only print the object that would be sent, without sending it. Warning: --dry-run cannot accurately output the result of merging the local manifest and the server-side data. Use --server-dry-run to get the merged result instead.")
|
||||
cmdutil.AddIncludeUninitializedFlag(cmd)
|
||||
cmdutil.AddServerSideApplyFlags(cmd)
|
||||
|
||||
// apply subcommands
|
||||
cmd.AddCommand(NewCmdApplyViewLastApplied(f, ioStreams))
|
||||
@ -188,8 +192,18 @@ func NewCmdApply(baseName string, f cmdutil.Factory, ioStreams genericclioptions
|
||||
}
|
||||
|
||||
func (o *ApplyOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
|
||||
o.ServerSideApply = cmdutil.GetServerSideApplyFlag(cmd)
|
||||
o.ForceConflicts = cmdutil.GetForceConflictsFlag(cmd)
|
||||
o.DryRun = cmdutil.GetDryRunFlag(cmd)
|
||||
|
||||
if o.ForceConflicts && !o.ServerSideApply {
|
||||
return fmt.Errorf("--force-conflicts only works with --server-side")
|
||||
}
|
||||
|
||||
if o.DryRun && o.ServerSideApply {
|
||||
return fmt.Errorf("--dry-run doesn't work with --server-side")
|
||||
}
|
||||
|
||||
if o.DryRun && o.ServerDryRun {
|
||||
return fmt.Errorf("--dry-run and --server-dry-run can't be used together")
|
||||
}
|
||||
@ -293,6 +307,16 @@ func parsePruneResources(mapper meta.RESTMapper, gvks []string) ([]pruneResource
|
||||
return pruneResources, nil
|
||||
}
|
||||
|
||||
func isIncompatibleServerError(err error) bool {
|
||||
// 415: Unsupported media type means we're talking to a server which doesn't
|
||||
// support server-side apply.
|
||||
if _, ok := err.(*errors.StatusError); !ok {
|
||||
// Non-StatusError means the error isn't because the server is incompatible.
|
||||
return false
|
||||
}
|
||||
return err.(*errors.StatusError).Status().Code == http.StatusUnsupportedMediaType
|
||||
}
|
||||
|
||||
func (o *ApplyOptions) Run() error {
|
||||
var openapiSchema openapi.Resources
|
||||
if o.OpenAPIPatch {
|
||||
@ -356,6 +380,50 @@ func (o *ApplyOptions) Run() error {
|
||||
klog.V(4).Infof("error recording current command: %v", err)
|
||||
}
|
||||
|
||||
if o.ServerSideApply {
|
||||
// Send the full object to be applied on the server side.
|
||||
data, err := runtime.Encode(unstructured.UnstructuredJSONScheme, info.Object)
|
||||
if err != nil {
|
||||
return cmdutil.AddSourceToErr("serverside-apply", info.Source, err)
|
||||
}
|
||||
options := metav1.PatchOptions{
|
||||
Force: &o.ForceConflicts,
|
||||
}
|
||||
if o.ServerDryRun {
|
||||
options.DryRun = []string{metav1.DryRunAll}
|
||||
}
|
||||
obj, err := resource.NewHelper(info.Client, info.Mapping).Patch(
|
||||
info.Namespace,
|
||||
info.Name,
|
||||
types.ApplyPatchType,
|
||||
data,
|
||||
&options,
|
||||
)
|
||||
if err == nil {
|
||||
info.Refresh(obj, true)
|
||||
metadata, err := meta.Accessor(info.Object)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
visitedUids.Insert(string(metadata.GetUID()))
|
||||
count++
|
||||
if len(output) > 0 && !shortOutput {
|
||||
objs = append(objs, info.Object)
|
||||
return nil
|
||||
}
|
||||
printer, err := o.ToPrinter("serverside-applied")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return printer.PrintObj(info.Object, o.Out)
|
||||
} else if !isIncompatibleServerError(err) {
|
||||
return err
|
||||
}
|
||||
// If we're talking to a server which does not implement server-side apply,
|
||||
// continue with the client side apply after this block.
|
||||
klog.Warningf("serverside-apply incompatible server: %v", err)
|
||||
}
|
||||
|
||||
// Get the modified configuration of the object. Embed the result
|
||||
// as an annotation in the modified configuration, so that it will appear
|
||||
// in the patch sent to the server.
|
||||
@ -840,7 +908,7 @@ func (p *Patcher) patchSimple(obj runtime.Object, modified []byte, source, names
|
||||
}
|
||||
}
|
||||
|
||||
options := metav1.UpdateOptions{}
|
||||
options := metav1.PatchOptions{}
|
||||
if p.ServerDryRun {
|
||||
options.DryRun = []string{metav1.DryRunAll}
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ type AttachOptions struct {
|
||||
AttachFunc func(*AttachOptions, *corev1.Container, bool, remotecommand.TerminalSizeQueue) func() error
|
||||
Resources []string
|
||||
Builder func() *resource.Builder
|
||||
AttachablePodFn polymorphichelpers.AttachableLogsForObjectFunc
|
||||
AttachablePodFn polymorphichelpers.AttachablePodForObjectFunc
|
||||
restClientGetter genericclioptions.RESTClientGetter
|
||||
|
||||
Attach RemoteAttach
|
||||
|
@ -51,7 +51,7 @@ func (f *fakeRemoteAttach) Attach(method string, url *url.URL, config *restclien
|
||||
return f.err
|
||||
}
|
||||
|
||||
func fakeAttachablePodFn(pod *corev1.Pod) polymorphichelpers.AttachableLogsForObjectFunc {
|
||||
func fakeAttachablePodFn(pod *corev1.Pod) polymorphichelpers.AttachablePodForObjectFunc {
|
||||
return func(getter genericclioptions.RESTClientGetter, obj runtime.Object, timeout time.Duration) (*corev1.Pod, error) {
|
||||
return pod, nil
|
||||
}
|
||||
|
@ -59,7 +59,15 @@ var (
|
||||
reconcileLong = templates.LongDesc(`
|
||||
Reconciles rules for RBAC Role, RoleBinding, ClusterRole, and ClusterRole binding objects.
|
||||
|
||||
This is preferred to 'apply' for RBAC resources so that proper rule coverage checks are done.`)
|
||||
Missing objects are created, and the containing namespace is created for namespaced objects, if required.
|
||||
|
||||
Existing roles are updated to include the permissions in the input objects,
|
||||
and remove extra permissions if --remove-extra-permissions is specified.
|
||||
|
||||
Existing bindings are updated to include the subjects in the input objects,
|
||||
and remove extra subjects if --remove-extra-subjects is specified.
|
||||
|
||||
This is preferred to 'apply' for RBAC resources so that semantically-aware merging of rules and subjects is done.`)
|
||||
|
||||
reconcileExample = templates.Examples(`
|
||||
# Reconcile rbac resources from a file
|
||||
|
@ -18,8 +18,11 @@ go_library(
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions:go_default_library",
|
||||
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/discovery:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/dynamic:go_default_library",
|
||||
"//vendor/github.com/jonboulle/clockwork:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
|
@ -30,8 +30,11 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions/resource"
|
||||
"k8s.io/client-go/discovery"
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/klog"
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/apply"
|
||||
@ -67,21 +70,38 @@ const maxRetries = 4
|
||||
|
||||
type DiffOptions struct {
|
||||
FilenameOptions resource.FilenameOptions
|
||||
|
||||
ServerSideApply bool
|
||||
ForceConflicts bool
|
||||
|
||||
OpenAPISchema openapi.Resources
|
||||
DiscoveryClient discovery.DiscoveryInterface
|
||||
DynamicClient dynamic.Interface
|
||||
DryRunVerifier *apply.DryRunVerifier
|
||||
CmdNamespace string
|
||||
EnforceNamespace bool
|
||||
Builder *resource.Builder
|
||||
Diff *DiffProgram
|
||||
}
|
||||
|
||||
func checkDiffArgs(cmd *cobra.Command, args []string) error {
|
||||
func validateArgs(cmd *cobra.Command, args []string) error {
|
||||
if len(args) != 0 {
|
||||
return cmdutil.UsageErrorf(cmd, "Unexpected args: %v", args)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewCmdDiff(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||
var options DiffOptions
|
||||
diff := DiffProgram{
|
||||
Exec: exec.New(),
|
||||
IOStreams: streams,
|
||||
func NewDiffOptions(ioStreams genericclioptions.IOStreams) *DiffOptions {
|
||||
return &DiffOptions{
|
||||
Diff: &DiffProgram{
|
||||
Exec: exec.New(),
|
||||
IOStreams: ioStreams,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func NewCmdDiff(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||
options := NewDiffOptions(streams)
|
||||
cmd := &cobra.Command{
|
||||
Use: "diff -f FILENAME",
|
||||
DisableFlagsInUseLine: true,
|
||||
@ -89,13 +109,15 @@ func NewCmdDiff(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.C
|
||||
Long: diffLong,
|
||||
Example: diffExample,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(checkDiffArgs(cmd, args))
|
||||
cmdutil.CheckErr(RunDiff(f, &diff, &options))
|
||||
cmdutil.CheckErr(options.Complete(f, cmd))
|
||||
cmdutil.CheckErr(validateArgs(cmd, args))
|
||||
cmdutil.CheckErr(options.Run())
|
||||
},
|
||||
}
|
||||
|
||||
usage := "contains the configuration to diff"
|
||||
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
|
||||
cmdutil.AddServerSideApplyFlags(cmd)
|
||||
cmd.MarkFlagRequired("filename")
|
||||
|
||||
return cmd
|
||||
@ -229,11 +251,13 @@ type Object interface {
|
||||
// InfoObject is an implementation of the Object interface. It gets all
|
||||
// the information from the Info object.
|
||||
type InfoObject struct {
|
||||
LocalObj runtime.Object
|
||||
Info *resource.Info
|
||||
Encoder runtime.Encoder
|
||||
OpenAPI openapi.Resources
|
||||
Force bool
|
||||
LocalObj runtime.Object
|
||||
Info *resource.Info
|
||||
Encoder runtime.Encoder
|
||||
OpenAPI openapi.Resources
|
||||
Force bool
|
||||
ServerSideApply bool
|
||||
ForceConflicts bool
|
||||
}
|
||||
|
||||
var _ Object = &InfoObject{}
|
||||
@ -246,6 +270,24 @@ func (obj InfoObject) Live() runtime.Object {
|
||||
// Returns the "merged" object, as it would look like if applied or
|
||||
// created.
|
||||
func (obj InfoObject) Merged() (runtime.Object, error) {
|
||||
if obj.ServerSideApply {
|
||||
data, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj.LocalObj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
options := metav1.PatchOptions{
|
||||
Force: &obj.ForceConflicts,
|
||||
DryRun: []string{metav1.DryRunAll},
|
||||
}
|
||||
return resource.NewHelper(obj.Info.Client, obj.Info.Mapping).Patch(
|
||||
obj.Info.Namespace,
|
||||
obj.Info.Name,
|
||||
types.ApplyPatchType,
|
||||
data,
|
||||
&options,
|
||||
)
|
||||
}
|
||||
|
||||
// Build the patcher, and then apply the patch with dry-run, unless the object doesn't exist, in which case we need to create it.
|
||||
if obj.Live() == nil {
|
||||
// Dry-run create if the object doesn't exist.
|
||||
@ -350,30 +392,50 @@ func isConflict(err error) bool {
|
||||
return err != nil && errors.IsConflict(err)
|
||||
}
|
||||
|
||||
func (o *DiffOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
|
||||
var err error
|
||||
|
||||
o.ServerSideApply = cmdutil.GetServerSideApplyFlag(cmd)
|
||||
o.ForceConflicts = cmdutil.GetForceConflictsFlag(cmd)
|
||||
if o.ForceConflicts && !o.ServerSideApply {
|
||||
return fmt.Errorf("--force-conflicts only works with --server-side")
|
||||
}
|
||||
|
||||
if !o.ServerSideApply {
|
||||
o.OpenAPISchema, err = f.OpenAPISchema()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
o.DiscoveryClient, err = f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
o.DynamicClient, err = f.DynamicClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
o.DryRunVerifier = &apply.DryRunVerifier{
|
||||
Finder: cmdutil.NewCRDFinder(cmdutil.CRDFromDynamic(o.DynamicClient)),
|
||||
OpenAPIGetter: o.DiscoveryClient,
|
||||
}
|
||||
|
||||
o.CmdNamespace, o.EnforceNamespace, err = f.ToRawKubeConfigLoader().Namespace()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
o.Builder = f.NewBuilder()
|
||||
return nil
|
||||
}
|
||||
|
||||
// RunDiff uses the factory to parse file arguments, find the version to
|
||||
// diff, and find each Info object for each files, and runs against the
|
||||
// differ.
|
||||
func RunDiff(f cmdutil.Factory, diff *DiffProgram, options *DiffOptions) error {
|
||||
schema, err := f.OpenAPISchema()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
discovery, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dynamic, err := f.DynamicClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dryRunVerifier := &apply.DryRunVerifier{
|
||||
Finder: cmdutil.NewCRDFinder(cmdutil.CRDFromDynamic(dynamic)),
|
||||
OpenAPIGetter: discovery,
|
||||
}
|
||||
|
||||
func (o *DiffOptions) Run() error {
|
||||
differ, err := NewDiffer("LIVE", "MERGED")
|
||||
if err != nil {
|
||||
return err
|
||||
@ -382,15 +444,10 @@ func RunDiff(f cmdutil.Factory, diff *DiffProgram, options *DiffOptions) error {
|
||||
|
||||
printer := Printer{}
|
||||
|
||||
cmdNamespace, enforceNamespace, err := f.ToRawKubeConfigLoader().Namespace()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r := f.NewBuilder().
|
||||
r := o.Builder.
|
||||
Unstructured().
|
||||
NamespaceParam(cmdNamespace).DefaultNamespace().
|
||||
FilenameParam(enforceNamespace, &options.FilenameOptions).
|
||||
NamespaceParam(o.CmdNamespace).DefaultNamespace().
|
||||
FilenameParam(o.EnforceNamespace, &o.FilenameOptions).
|
||||
Flatten().
|
||||
Do()
|
||||
if err := r.Err(); err != nil {
|
||||
@ -402,7 +459,7 @@ func RunDiff(f cmdutil.Factory, diff *DiffProgram, options *DiffOptions) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := dryRunVerifier.HasSupport(info.Mapping.GroupVersionKind); err != nil {
|
||||
if err := o.DryRunVerifier.HasSupport(info.Mapping.GroupVersionKind); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -424,11 +481,13 @@ func RunDiff(f cmdutil.Factory, diff *DiffProgram, options *DiffOptions) error {
|
||||
)
|
||||
}
|
||||
obj := InfoObject{
|
||||
LocalObj: local,
|
||||
Info: info,
|
||||
Encoder: scheme.DefaultJSONEncoder(),
|
||||
OpenAPI: schema,
|
||||
Force: force,
|
||||
LocalObj: local,
|
||||
Info: info,
|
||||
Encoder: scheme.DefaultJSONEncoder(),
|
||||
OpenAPI: o.OpenAPISchema,
|
||||
Force: force,
|
||||
ServerSideApply: o.ServerSideApply,
|
||||
ForceConflicts: o.ForceConflicts,
|
||||
}
|
||||
|
||||
err = differ.Diff(obj, printer)
|
||||
@ -442,5 +501,5 @@ func RunDiff(f cmdutil.Factory, diff *DiffProgram, options *DiffOptions) error {
|
||||
return err
|
||||
}
|
||||
|
||||
return differ.Run(diff)
|
||||
return differ.Run(o.Diff)
|
||||
}
|
||||
|
@ -29,8 +29,6 @@ import (
|
||||
"github.com/evanphx/json-patch"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
"k8s.io/klog"
|
||||
|
||||
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@ -44,6 +42,7 @@ import (
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/scale"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"k8s.io/klog"
|
||||
utilexec "k8s.io/utils/exec"
|
||||
)
|
||||
|
||||
@ -400,6 +399,11 @@ func AddDryRunFlag(cmd *cobra.Command) {
|
||||
cmd.Flags().Bool("dry-run", false, "If true, only print the object that would be sent, without sending it.")
|
||||
}
|
||||
|
||||
func AddServerSideApplyFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().Bool("server-side", false, "If true, apply runs in the server instead of the client. This is an alpha feature and flag.")
|
||||
cmd.Flags().Bool("force-conflicts", false, "If true, server-side apply will force the changes against conflicts. This is an alpha feature and flag.")
|
||||
}
|
||||
|
||||
func AddIncludeUninitializedFlag(cmd *cobra.Command) {
|
||||
cmd.Flags().Bool("include-uninitialized", false, `If true, the kubectl command applies to uninitialized objects. If explicitly set to false, this flag overrides other flags that make the kubectl commands apply to uninitialized objects, e.g., "--all". Objects with empty metadata.initializers are regarded as initialized.`)
|
||||
cmd.Flags().MarkDeprecated("include-uninitialized", "The Initializers feature has been removed. This flag is now a no-op, and will be removed in v1.15")
|
||||
@ -473,6 +477,14 @@ func DumpReaderToFile(reader io.Reader, filename string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetServerSideApplyFlag(cmd *cobra.Command) bool {
|
||||
return GetFlagBool(cmd, "server-side")
|
||||
}
|
||||
|
||||
func GetForceConflictsFlag(cmd *cobra.Command) bool {
|
||||
return GetFlagBool(cmd, "force-conflicts")
|
||||
}
|
||||
|
||||
func GetDryRunFlag(cmd *cobra.Command) bool {
|
||||
return GetFlagBool(cmd, "dry-run")
|
||||
}
|
||||
|
@ -90,6 +90,8 @@ func NewWaitFlags(restClientGetter genericclioptions.RESTClientGetter, streams g
|
||||
PrintFlags: genericclioptions.NewPrintFlags("condition met"),
|
||||
ResourceBuilderFlags: genericclioptions.NewResourceBuilderFlags().
|
||||
WithLabelSelector("").
|
||||
WithFieldSelector("").
|
||||
WithAll(false).
|
||||
WithAllNamespaces(false).
|
||||
WithAll(false).
|
||||
WithLatest(),
|
||||
@ -105,11 +107,12 @@ func NewCmdWait(restClientGetter genericclioptions.RESTClientGetter, streams gen
|
||||
flags := NewWaitFlags(restClientGetter, streams)
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "wait resource.group/name [--for=delete|--for condition=available]",
|
||||
Use: "wait ([-f FILENAME] | resource.group/resource.name | resource.group [(-l label | --all)]) [--for=delete|--for condition=available]",
|
||||
Short: "Experimental: Wait for a specific condition on one or many resources.",
|
||||
Long: waitLong,
|
||||
Example: waitExample,
|
||||
|
||||
DisableFlagsInUseLine: true,
|
||||
Short: "Experimental: Wait for a specific condition on one or many resources.",
|
||||
Long: waitLong,
|
||||
Example: waitExample,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
o, err := flags.ToOptions(args)
|
||||
cmdutil.CheckErr(err)
|
||||
|
@ -310,6 +310,58 @@ func TestWaitForDeletion(t *testing.T) {
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "handles watch delete multiple",
|
||||
infos: []*resource.Info{
|
||||
{
|
||||
Mapping: &meta.RESTMapping{
|
||||
Resource: schema.GroupVersionResource{Group: "group", Version: "version", Resource: "theresource-1"},
|
||||
},
|
||||
Name: "name-foo-1",
|
||||
Namespace: "ns-foo",
|
||||
},
|
||||
{
|
||||
Mapping: &meta.RESTMapping{
|
||||
Resource: schema.GroupVersionResource{Group: "group", Version: "version", Resource: "theresource-2"},
|
||||
},
|
||||
Name: "name-foo-2",
|
||||
Namespace: "ns-foo",
|
||||
},
|
||||
},
|
||||
fakeClient: func() *dynamicfakeclient.FakeDynamicClient {
|
||||
fakeClient := dynamicfakeclient.NewSimpleDynamicClient(scheme)
|
||||
fakeClient.PrependReactor("get", "theresource-1", func(action clienttesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, newUnstructured("group/version", "TheKind", "ns-foo", "name-foo-1"), nil
|
||||
})
|
||||
fakeClient.PrependReactor("get", "theresource-2", func(action clienttesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, newUnstructured("group/version", "TheKind", "ns-foo", "name-foo-2"), nil
|
||||
})
|
||||
fakeClient.PrependWatchReactor("theresource-1", func(action clienttesting.Action) (handled bool, ret watch.Interface, err error) {
|
||||
fakeWatch := watch.NewRaceFreeFake()
|
||||
fakeWatch.Action(watch.Deleted, newUnstructured("group/version", "TheKind", "ns-foo", "name-foo-1"))
|
||||
return true, fakeWatch, nil
|
||||
})
|
||||
fakeClient.PrependWatchReactor("theresource-2", func(action clienttesting.Action) (handled bool, ret watch.Interface, err error) {
|
||||
fakeWatch := watch.NewRaceFreeFake()
|
||||
fakeWatch.Action(watch.Deleted, newUnstructured("group/version", "TheKind", "ns-foo", "name-foo-2"))
|
||||
return true, fakeWatch, nil
|
||||
})
|
||||
return fakeClient
|
||||
},
|
||||
timeout: 10 * time.Second,
|
||||
|
||||
validateActions: func(t *testing.T, actions []clienttesting.Action) {
|
||||
if len(actions) != 2 {
|
||||
t.Fatal(spew.Sdump(actions))
|
||||
}
|
||||
if !actions[0].Matches("list", "theresource-1") {
|
||||
t.Error(spew.Sdump(actions))
|
||||
}
|
||||
if !actions[1].Matches("list", "theresource-2") {
|
||||
t.Error(spew.Sdump(actions))
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ignores watch error",
|
||||
infos: []*resource.Info{
|
||||
|
@ -34,11 +34,11 @@ type LogsForObjectFunc func(restClientGetter genericclioptions.RESTClientGetter,
|
||||
// LogsForObjectFn gives a way to easily override the function for unit testing if needed.
|
||||
var LogsForObjectFn LogsForObjectFunc = logsForObject
|
||||
|
||||
// AttachableLogsForObjectFunc is a function type that can tell you how to get the pod for which to attach a given object
|
||||
type AttachableLogsForObjectFunc func(restClientGetter genericclioptions.RESTClientGetter, object runtime.Object, timeout time.Duration) (*v1.Pod, error)
|
||||
// AttachablePodForObjectFunc is a function type that can tell you how to get the pod for which to attach a given object
|
||||
type AttachablePodForObjectFunc func(restClientGetter genericclioptions.RESTClientGetter, object runtime.Object, timeout time.Duration) (*v1.Pod, error)
|
||||
|
||||
// AttachablePodForObjectFn gives a way to easily override the function for unit testing if needed.
|
||||
var AttachablePodForObjectFn AttachableLogsForObjectFunc = attachablePodForObject
|
||||
var AttachablePodForObjectFn AttachablePodForObjectFunc = attachablePodForObject
|
||||
|
||||
// HistoryViewerFunc is a function type that can tell you how to view change history
|
||||
type HistoryViewerFunc func(restClientGetter genericclioptions.RESTClientGetter, mapping *meta.RESTMapping) (kubectl.HistoryViewer, error)
|
||||
|
@ -131,7 +131,6 @@ go_library(
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/dynamic:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
|
||||
@ -141,6 +140,7 @@ go_library(
|
||||
"//staging/src/k8s.io/client-go/util/flowcontrol:go_default_library",
|
||||
"//staging/src/k8s.io/cloud-provider:go_default_library",
|
||||
"//staging/src/k8s.io/csi-api/pkg/client/clientset/versioned:go_default_library",
|
||||
"//staging/src/k8s.io/node-api/pkg/client/clientset/versioned:go_default_library",
|
||||
"//third_party/forked/golang/expansion:go_default_library",
|
||||
"//vendor/github.com/golang/groupcache/lru:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/events:go_default_library",
|
||||
|
@ -135,7 +135,7 @@ func (*Empty) ProtoMessage() {}
|
||||
func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{2} }
|
||||
|
||||
// ListAndWatch returns a stream of List of Devices
|
||||
// Whenever a Device state change or a Device disapears, ListAndWatch
|
||||
// Whenever a Device state change or a Device disappears, ListAndWatch
|
||||
// returns the new list
|
||||
type ListAndWatchResponse struct {
|
||||
Devices []*Device `protobuf:"bytes,1,rep,name=devices" json:"devices,omitempty"`
|
||||
@ -482,7 +482,7 @@ type DevicePluginClient interface {
|
||||
// Manager
|
||||
GetDevicePluginOptions(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*DevicePluginOptions, error)
|
||||
// ListAndWatch returns a stream of List of Devices
|
||||
// Whenever a Device state change or a Device disapears, ListAndWatch
|
||||
// Whenever a Device state change or a Device disappears, ListAndWatch
|
||||
// returns the new list
|
||||
ListAndWatch(ctx context.Context, in *Empty, opts ...grpc.CallOption) (DevicePlugin_ListAndWatchClient, error)
|
||||
// Allocate is called during container creation so that the Device
|
||||
@ -569,7 +569,7 @@ type DevicePluginServer interface {
|
||||
// Manager
|
||||
GetDevicePluginOptions(context.Context, *Empty) (*DevicePluginOptions, error)
|
||||
// ListAndWatch returns a stream of List of Devices
|
||||
// Whenever a Device state change or a Device disapears, ListAndWatch
|
||||
// Whenever a Device state change or a Device disappears, ListAndWatch
|
||||
// returns the new list
|
||||
ListAndWatch(*Empty, DevicePlugin_ListAndWatchServer) error
|
||||
// Allocate is called during container creation so that the Device
|
||||
|
@ -51,7 +51,7 @@ service DevicePlugin {
|
||||
rpc GetDevicePluginOptions(Empty) returns (DevicePluginOptions) {}
|
||||
|
||||
// ListAndWatch returns a stream of List of Devices
|
||||
// Whenever a Device state change or a Device disapears, ListAndWatch
|
||||
// Whenever a Device state change or a Device disappears, ListAndWatch
|
||||
// returns the new list
|
||||
rpc ListAndWatch(Empty) returns (stream ListAndWatchResponse) {}
|
||||
|
||||
@ -67,7 +67,7 @@ service DevicePlugin {
|
||||
}
|
||||
|
||||
// ListAndWatch returns a stream of List of Devices
|
||||
// Whenever a Device state change or a Device disapears, ListAndWatch
|
||||
// Whenever a Device state change or a Device disappears, ListAndWatch
|
||||
// returns the new list
|
||||
message ListAndWatchResponse {
|
||||
repeated Device devices = 1;
|
||||
|
@ -21,11 +21,9 @@ go_library(
|
||||
importpath = "k8s.io/kubernetes/pkg/kubelet/cadvisor",
|
||||
deps = [
|
||||
"//pkg/apis/core/v1/helper:go_default_library",
|
||||
"//pkg/features:go_default_library",
|
||||
"//pkg/kubelet/types:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/events:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/info/v1:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/info/v2:go_default_library",
|
||||
@ -51,11 +49,8 @@ go_test(
|
||||
embed = [":go_default_library"],
|
||||
deps = select({
|
||||
"@io_bazel_rules_go//go/platform:linux": [
|
||||
"//pkg/features:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/util/feature/testing:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/container/crio:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/info/v1:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
|
@ -23,9 +23,7 @@ import (
|
||||
cadvisorapi2 "github.com/google/cadvisor/info/v2"
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
|
||||
)
|
||||
|
||||
@ -46,13 +44,11 @@ func CapacityFromMachineInfo(info *cadvisorapi.MachineInfo) v1.ResourceList {
|
||||
}
|
||||
|
||||
// if huge pages are enabled, we report them as a schedulable resource on the node
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.HugePages) {
|
||||
for _, hugepagesInfo := range info.HugePages {
|
||||
pageSizeBytes := int64(hugepagesInfo.PageSize * 1024)
|
||||
hugePagesBytes := pageSizeBytes * int64(hugepagesInfo.NumPages)
|
||||
pageSizeQuantity := resource.NewQuantity(pageSizeBytes, resource.BinarySI)
|
||||
c[v1helper.HugePageResourceName(*pageSizeQuantity)] = *resource.NewQuantity(hugePagesBytes, resource.BinarySI)
|
||||
}
|
||||
for _, hugepagesInfo := range info.HugePages {
|
||||
pageSizeBytes := int64(hugepagesInfo.PageSize * 1024)
|
||||
hugePagesBytes := pageSizeBytes * int64(hugepagesInfo.NumPages)
|
||||
pageSizeQuantity := resource.NewQuantity(pageSizeBytes, resource.BinarySI)
|
||||
c[v1helper.HugePageResourceName(*pageSizeQuantity)] = *resource.NewQuantity(hugePagesBytes, resource.BinarySI)
|
||||
}
|
||||
|
||||
return c
|
||||
|
@ -27,9 +27,6 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
)
|
||||
|
||||
func TestCapacityFromMachineInfoWithHugePagesEnable(t *testing.T) {
|
||||
@ -49,36 +46,12 @@ func TestCapacityFromMachineInfoWithHugePagesEnable(t *testing.T) {
|
||||
v1.ResourceMemory: *resource.NewQuantity(int64(2048), resource.BinarySI),
|
||||
"hugepages-5Ki": *resource.NewQuantity(int64(51200), resource.BinarySI),
|
||||
}
|
||||
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HugePages, true)()
|
||||
actual := CapacityFromMachineInfo(machineInfo)
|
||||
if !reflect.DeepEqual(actual, expected) {
|
||||
t.Errorf("when set hugepages true, got resource list %v, want %v", actual, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapacityFromMachineInfoWithHugePagesDisable(t *testing.T) {
|
||||
machineInfo := &info.MachineInfo{
|
||||
NumCores: 2,
|
||||
MemoryCapacity: 2048,
|
||||
HugePages: []info.HugePagesInfo{
|
||||
{
|
||||
PageSize: 5,
|
||||
NumPages: 10,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
expected := v1.ResourceList{
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(int64(2000), resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(int64(2048), resource.BinarySI),
|
||||
}
|
||||
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HugePages, false)()
|
||||
actual := CapacityFromMachineInfo(machineInfo)
|
||||
if !reflect.DeepEqual(actual, expected) {
|
||||
t.Errorf("when set hugepages false, got resource list %v, want %v", actual, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCrioSocket(t *testing.T) {
|
||||
assert.EqualValues(t, CrioSocket, crio.CrioSocket, "CrioSocket in this package must equal the one in github.com/google/cadvisor/container/crio/client.go")
|
||||
}
|
||||
|
@ -327,9 +327,7 @@ func getSupportedSubsystems() map[subsystem]bool {
|
||||
&cgroupfs.CpuGroup{}: true,
|
||||
}
|
||||
// not all hosts support hugetlb cgroup, and in the absent of hugetlb, we will fail silently by reporting no capacity.
|
||||
if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.HugePages) {
|
||||
supportedSubsystems[&cgroupfs.HugetlbGroup{}] = false
|
||||
}
|
||||
supportedSubsystems[&cgroupfs.HugetlbGroup{}] = false
|
||||
if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.SupportPodPidsLimit) {
|
||||
supportedSubsystems[&cgroupfs.PidsGroup{}] = true
|
||||
}
|
||||
@ -385,27 +383,25 @@ func (m *cgroupManagerImpl) toResources(resourceConfig *ResourceConfig) *libcont
|
||||
}
|
||||
}
|
||||
// if huge pages are enabled, we set them in libcontainer
|
||||
if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.HugePages) {
|
||||
// for each page size enumerated, set that value
|
||||
pageSizes := sets.NewString()
|
||||
for pageSize, limit := range resourceConfig.HugePageLimit {
|
||||
sizeString := units.CustomSize("%g%s", float64(pageSize), 1024.0, hugePageSizeList)
|
||||
resources.HugetlbLimit = append(resources.HugetlbLimit, &libcontainerconfigs.HugepageLimit{
|
||||
Pagesize: sizeString,
|
||||
Limit: uint64(limit),
|
||||
})
|
||||
pageSizes.Insert(sizeString)
|
||||
}
|
||||
// for each page size omitted, limit to 0
|
||||
for _, pageSize := range cgroupfs.HugePageSizes {
|
||||
if pageSizes.Has(pageSize) {
|
||||
continue
|
||||
}
|
||||
resources.HugetlbLimit = append(resources.HugetlbLimit, &libcontainerconfigs.HugepageLimit{
|
||||
Pagesize: pageSize,
|
||||
Limit: uint64(0),
|
||||
})
|
||||
// for each page size enumerated, set that value
|
||||
pageSizes := sets.NewString()
|
||||
for pageSize, limit := range resourceConfig.HugePageLimit {
|
||||
sizeString := units.CustomSize("%g%s", float64(pageSize), 1024.0, hugePageSizeList)
|
||||
resources.HugetlbLimit = append(resources.HugetlbLimit, &libcontainerconfigs.HugepageLimit{
|
||||
Pagesize: sizeString,
|
||||
Limit: uint64(limit),
|
||||
})
|
||||
pageSizes.Insert(sizeString)
|
||||
}
|
||||
// for each page size omitted, limit to 0
|
||||
for _, pageSize := range cgroupfs.HugePageSizes {
|
||||
if pageSizes.Has(pageSize) {
|
||||
continue
|
||||
}
|
||||
resources.HugetlbLimit = append(resources.HugetlbLimit, &libcontainerconfigs.HugepageLimit{
|
||||
Pagesize: pageSize,
|
||||
Limit: uint64(0),
|
||||
})
|
||||
}
|
||||
return resources
|
||||
}
|
||||
|
@ -612,7 +612,7 @@ func (m *ManagerImpl) devicesToAllocate(podUID, contName, resource string, requi
|
||||
devicesInUse := m.allocatedDevices[resource]
|
||||
// Gets a list of available devices.
|
||||
available := m.healthyDevices[resource].Difference(devicesInUse)
|
||||
if int(available.Len()) < needed {
|
||||
if available.Len() < needed {
|
||||
return nil, fmt.Errorf("requested number of devices unavailable for %s. Requested: %d, Available: %d", resource, needed, available.Len())
|
||||
}
|
||||
allocated := available.UnsortedList()[:needed]
|
||||
|
@ -26,9 +26,7 @@ import (
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/klog"
|
||||
kubefeatures "k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/kubelet/events"
|
||||
kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
|
||||
)
|
||||
@ -159,9 +157,7 @@ func getCgroupConfig(rl v1.ResourceList) *ResourceConfig {
|
||||
val := MilliCPUToShares(q.MilliValue())
|
||||
rc.CpuShares = &val
|
||||
}
|
||||
if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.HugePages) {
|
||||
rc.HugePageLimit = HugePageLimits(rl)
|
||||
}
|
||||
rc.HugePageLimit = HugePageLimits(rl)
|
||||
|
||||
return &rc
|
||||
}
|
||||
|
@ -108,9 +108,7 @@ func (m *qosContainerManagerImpl) Start(getNodeAllocatable func() v1.ResourceLis
|
||||
}
|
||||
|
||||
// for each enumerated huge page size, the qos tiers are unbounded
|
||||
if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.HugePages) {
|
||||
m.setHugePagesUnbounded(containerConfig)
|
||||
}
|
||||
m.setHugePagesUnbounded(containerConfig)
|
||||
|
||||
// check if it exists
|
||||
if !cm.Exists(containerName) {
|
||||
@ -290,10 +288,8 @@ func (m *qosContainerManagerImpl) UpdateCgroups() error {
|
||||
}
|
||||
|
||||
// update the qos level cgroup settings for huge pages (ensure they remain unbounded)
|
||||
if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.HugePages) {
|
||||
if err := m.setHugePagesConfig(qosConfigs); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := m.setHugePagesConfig(qosConfigs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.QOSReserved) {
|
||||
|
@ -19,12 +19,12 @@ go_library(
|
||||
"//pkg/proxy/iptables:go_default_library",
|
||||
"//pkg/util/conntrack:go_default_library",
|
||||
"//pkg/util/iptables:go_default_library",
|
||||
"//pkg/util/net:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||
"//vendor/k8s.io/utils/net:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -31,8 +31,8 @@ import (
|
||||
iptablesproxy "k8s.io/kubernetes/pkg/proxy/iptables"
|
||||
"k8s.io/kubernetes/pkg/util/conntrack"
|
||||
utiliptables "k8s.io/kubernetes/pkg/util/iptables"
|
||||
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||
"k8s.io/utils/exec"
|
||||
utilnet "k8s.io/utils/net"
|
||||
)
|
||||
|
||||
// HostPortManager is an interface for adding and removing hostport for a given pod sandbox.
|
||||
|
@ -43,7 +43,6 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/client-go/dynamic"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
v1core "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
corelisters "k8s.io/client-go/listers/core/v1"
|
||||
@ -114,6 +113,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/util/oom"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
"k8s.io/kubernetes/pkg/volume/csi"
|
||||
nodeapiclientset "k8s.io/node-api/pkg/client/clientset/versioned"
|
||||
utilexec "k8s.io/utils/exec"
|
||||
"k8s.io/utils/integer"
|
||||
)
|
||||
@ -249,7 +249,7 @@ type Dependencies struct {
|
||||
OnHeartbeatFailure func()
|
||||
KubeClient clientset.Interface
|
||||
CSIClient csiclientset.Interface
|
||||
DynamicKubeClient dynamic.Interface
|
||||
NodeAPIClient nodeapiclientset.Interface
|
||||
Mounter mount.Interface
|
||||
OOMAdjuster *oom.OOMAdjuster
|
||||
OSInterface kubecontainer.OSInterface
|
||||
@ -658,8 +658,8 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
|
||||
}
|
||||
klet.runtimeService = runtimeService
|
||||
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.RuntimeClass) && kubeDeps.DynamicKubeClient != nil {
|
||||
klet.runtimeClassManager = runtimeclass.NewManager(kubeDeps.DynamicKubeClient)
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.RuntimeClass) && kubeDeps.NodeAPIClient != nil {
|
||||
klet.runtimeClassManager = runtimeclass.NewManager(kubeDeps.NodeAPIClient)
|
||||
}
|
||||
|
||||
runtime, err := kuberuntime.NewKubeGenericRuntimeManager(
|
||||
@ -1303,6 +1303,7 @@ func (kl *Kubelet) initializeModules() error {
|
||||
collectors.NewVolumeStatsCollector(kl),
|
||||
collectors.NewLogMetricsCollector(kl.StatsProvider.ListPodStats),
|
||||
)
|
||||
metrics.SetNodeName(kl.nodeName)
|
||||
|
||||
// Setup filesystem directories.
|
||||
if err := kl.setupDataDirs(); err != nil {
|
||||
@ -1426,7 +1427,7 @@ func (kl *Kubelet) Run(updates <-chan kubetypes.PodUpdate) {
|
||||
|
||||
// Start syncing RuntimeClasses if enabled.
|
||||
if kl.runtimeClassManager != nil {
|
||||
go kl.runtimeClassManager.Run(wait.NeverStop)
|
||||
kl.runtimeClassManager.Start(wait.NeverStop)
|
||||
}
|
||||
|
||||
// Start the pod lifecycle event generator.
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user