Merge remote-tracking branch 'upstream/master' into test-cmd-what

This commit is contained in:
Thomas Runyon 2019-02-05 19:23:21 -05:00
commit 4fc5be8d5a
470 changed files with 41764 additions and 6284 deletions

189
Godeps/Godeps.json generated
View File

@ -201,178 +201,193 @@
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws", "ImportPath": "github.com/aws/aws-sdk-go/aws",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/awserr", "ImportPath": "github.com/aws/aws-sdk-go/aws/awserr",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/awsutil", "ImportPath": "github.com/aws/aws-sdk-go/aws/awsutil",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/client", "ImportPath": "github.com/aws/aws-sdk-go/aws/client",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/client/metadata", "ImportPath": "github.com/aws/aws-sdk-go/aws/client/metadata",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/corehandlers", "ImportPath": "github.com/aws/aws-sdk-go/aws/corehandlers",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials", "ImportPath": "github.com/aws/aws-sdk-go/aws/credentials",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds", "ImportPath": "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials/endpointcreds", "ImportPath": "github.com/aws/aws-sdk-go/aws/credentials/endpointcreds",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "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", "ImportPath": "github.com/aws/aws-sdk-go/aws/credentials/stscreds",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/csm", "ImportPath": "github.com/aws/aws-sdk-go/aws/csm",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/defaults", "ImportPath": "github.com/aws/aws-sdk-go/aws/defaults",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/ec2metadata", "ImportPath": "github.com/aws/aws-sdk-go/aws/ec2metadata",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/endpoints", "ImportPath": "github.com/aws/aws-sdk-go/aws/endpoints",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/request", "ImportPath": "github.com/aws/aws-sdk-go/aws/request",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/session", "ImportPath": "github.com/aws/aws-sdk-go/aws/session",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/signer/v4", "ImportPath": "github.com/aws/aws-sdk-go/aws/signer/v4",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "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", "ImportPath": "github.com/aws/aws-sdk-go/internal/sdkio",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/internal/sdkrand", "ImportPath": "github.com/aws/aws-sdk-go/internal/sdkrand",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "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", "ImportPath": "github.com/aws/aws-sdk-go/internal/shareddefaults",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol", "ImportPath": "github.com/aws/aws-sdk-go/private/protocol",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/ec2query", "ImportPath": "github.com/aws/aws-sdk-go/private/protocol/ec2query",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil", "ImportPath": "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/jsonrpc", "ImportPath": "github.com/aws/aws-sdk-go/private/protocol/jsonrpc",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/query", "ImportPath": "github.com/aws/aws-sdk-go/private/protocol/query",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/query/queryutil", "ImportPath": "github.com/aws/aws-sdk-go/private/protocol/query/queryutil",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/rest", "ImportPath": "github.com/aws/aws-sdk-go/private/protocol/rest",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil", "ImportPath": "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/service/autoscaling", "ImportPath": "github.com/aws/aws-sdk-go/service/autoscaling",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/service/ec2", "ImportPath": "github.com/aws/aws-sdk-go/service/ec2",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/service/ecr", "ImportPath": "github.com/aws/aws-sdk-go/service/ecr",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/service/elb", "ImportPath": "github.com/aws/aws-sdk-go/service/elb",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/service/elbv2", "ImportPath": "github.com/aws/aws-sdk-go/service/elbv2",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/service/kms", "ImportPath": "github.com/aws/aws-sdk-go/service/kms",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/service/sts", "ImportPath": "github.com/aws/aws-sdk-go/service/sts",
"Comment": "v1.14.12", "Comment": "v1.16.26",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4" "Rev": "81f3829f5a9d041041bdf56e55926691309d7699"
}, },
{ {
"ImportPath": "github.com/bazelbuild/bazel-gazelle/cmd/gazelle", "ImportPath": "github.com/bazelbuild/bazel-gazelle/cmd/gazelle",
@ -2080,7 +2095,7 @@
}, },
{ {
"ImportPath": "github.com/google/gofuzz", "ImportPath": "github.com/google/gofuzz",
"Rev": "44d81051d367757e1c7c6a5a86423ece9afcf63c" "Rev": "24818f796faf91cd76ec7bddd72458fbced7a6c1"
}, },
{ {
"ImportPath": "github.com/google/uuid", "ImportPath": "github.com/google/uuid",
@ -2998,8 +3013,8 @@
}, },
{ {
"ImportPath": "github.com/quobyte/api", "ImportPath": "github.com/quobyte/api",
"Comment": "v0.1.1-4-g206ef832283c1a", "Comment": "v0.1.2",
"Rev": "206ef832283c1a0144bbc762be2634d49987b5ff" "Rev": "9cfd29338dd9fdaaf956b7082e5550aab5fe3841"
}, },
{ {
"ImportPath": "github.com/rancher/go-rancher/client", "ImportPath": "github.com/rancher/go-rancher/client",
@ -4068,6 +4083,10 @@
"ImportPath": "k8s.io/kube-openapi/pkg/handler", "ImportPath": "k8s.io/kube-openapi/pkg/handler",
"Rev": "ced9eb3070a5f1c548ef46e8dfe2a97c208d9f03" "Rev": "ced9eb3070a5f1c548ef46e8dfe2a97c208d9f03"
}, },
{
"ImportPath": "k8s.io/kube-openapi/pkg/schemaconv",
"Rev": "ced9eb3070a5f1c548ef46e8dfe2a97c208d9f03"
},
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/util", "ImportPath": "k8s.io/kube-openapi/pkg/util",
"Rev": "ced9eb3070a5f1c548ef46e8dfe2a97c208d9f03" "Rev": "ced9eb3070a5f1c548ef46e8dfe2a97c208d9f03"
@ -4120,6 +4139,10 @@
"ImportPath": "k8s.io/utils/keymutex", "ImportPath": "k8s.io/utils/keymutex",
"Rev": "ed37f7428a91fc2a81070808937195dcd46d320e" "Rev": "ed37f7428a91fc2a81070808937195dcd46d320e"
}, },
{
"ImportPath": "k8s.io/utils/net",
"Rev": "ed37f7428a91fc2a81070808937195dcd46d320e"
},
{ {
"ImportPath": "k8s.io/utils/nsenter", "ImportPath": "k8s.io/utils/nsenter",
"Rev": "ed37f7428a91fc2a81070808937195dcd46d320e" "Rev": "ed37f7428a91fc2a81070808937195dcd46d320e"
@ -4140,6 +4163,26 @@
"ImportPath": "k8s.io/utils/trace", "ImportPath": "k8s.io/utils/trace",
"Rev": "ed37f7428a91fc2a81070808937195dcd46d320e" "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", "ImportPath": "sigs.k8s.io/yaml",
"Comment": "v1.1.0", "Comment": "v1.1.0",

2095
Godeps/LICENSES generated

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1343,6 +1343,11 @@ EOF
if [ -n "${ADDON_MANAGER_LEADER_ELECTION:-}" ]; then if [ -n "${ADDON_MANAGER_LEADER_ELECTION:-}" ]; then
cat >>$file <<EOF cat >>$file <<EOF
ADDON_MANAGER_LEADER_ELECTION: $(yaml-quote ${ADDON_MANAGER_LEADER_ELECTION}) 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 EOF
fi fi

View File

@ -51,6 +51,7 @@ readonly kern_logfile="kern.log"
readonly initd_logfiles="docker/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 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 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 # Limit the number of concurrent node connections so that we don't run out of
# file descriptors for large clusters. # file descriptors for large clusters.
@ -164,6 +165,10 @@ function save-logs() {
for svc in "${services[@]}"; do for svc in "${services[@]}"; do
log-dump-ssh "${node_name}" "sudo journalctl --output=cat -u ${svc}.service" > "${dir}/${svc}.log" || true log-dump-ssh "${node_name}" "sudo journalctl --output=cat -u ${svc}.service" > "${dir}/${svc}.log" || true
done done
if [[ "$dump_systemd_journal" == "true" ]]; then
log-dump-ssh "${node_name}" "sudo journalctl --output=short-precise" > "${dir}/systemd.log" || true
fi
else else
files="${kern_logfile} ${files} ${initd_logfiles} ${supervisord_logfiles}" files="${kern_logfile} ${files} ${initd_logfiles} ${supervisord_logfiles}"
fi fi

View File

@ -212,11 +212,6 @@ func (s *ServerRunOptions) Flags() (fss apiserverflag.NamedFlagSets) {
fs.StringVar(&s.KubeletConfig.CAFile, "kubelet-certificate-authority", s.KubeletConfig.CAFile, fs.StringVar(&s.KubeletConfig.CAFile, "kubelet-certificate-authority", s.KubeletConfig.CAFile,
"Path to a cert file for the certificate authority.") "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, ""+ fs.StringVar(&s.ProxyClientCertFile, "proxy-client-cert-file", s.ProxyClientCertFile, ""+
"Client certificate used to prove the identity of the aggregator or kube-apiserver "+ "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 "+ "when it must call out during a request. This includes proxying requests to a user "+

View File

@ -36,6 +36,7 @@ import (
cacheddiscovery "k8s.io/client-go/discovery/cached" cacheddiscovery "k8s.io/client-go/discovery/cached"
"k8s.io/client-go/dynamic" "k8s.io/client-go/dynamic"
clientset "k8s.io/client-go/kubernetes" clientset "k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest"
csiclientset "k8s.io/csi-api/pkg/client/clientset/versioned" csiclientset "k8s.io/csi-api/pkg/client/clientset/versioned"
"k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/controller"
cloudcontroller "k8s.io/kubernetes/pkg/controller/cloud" cloudcontroller "k8s.io/kubernetes/pkg/controller/cloud"
@ -331,6 +332,10 @@ func startNamespaceController(ctx ControllerContext) (http.Handler, bool, error)
nsKubeconfig.QPS *= 20 nsKubeconfig.QPS *= 20
nsKubeconfig.Burst *= 100 nsKubeconfig.Burst *= 100
namespaceKubeClient := clientset.NewForConfigOrDie(nsKubeconfig) 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) dynamicClient, err := dynamic.NewForConfig(nsKubeconfig)
if err != nil { if err != nil {

View File

@ -17,6 +17,7 @@ limitations under the License.
package app package app
import ( import (
"net/http"
"testing" "testing"
"time" "time"
@ -34,8 +35,11 @@ type TestClientBuilder struct {
clientset clientset.Interface clientset clientset.Interface
} }
func (TestClientBuilder) Config(name string) (*restclient.Config, error) { return nil, nil } func (TestClientBuilder) Config(name string) (*restclient.Config, error) { return nil, nil }
func (TestClientBuilder) ConfigOrDie(name string) *restclient.Config { return nil } func (TestClientBuilder) ConfigOrDie(name string) *restclient.Config {
return &restclient.Config{}
}
func (TestClientBuilder) Client(name string) (clientset.Interface, error) { return nil, nil } func (TestClientBuilder) Client(name string) (clientset.Interface, error) { return nil, nil }
func (m TestClientBuilder) ClientOrDie(name string) clientset.Interface { func (m TestClientBuilder) ClientOrDie(name string) clientset.Interface {
return m.clientset return m.clientset
@ -62,6 +66,10 @@ func (c *FakeClientSet) Discovery() discovery.DiscoveryInterface {
return c.DiscoveryObj return c.DiscoveryObj
} }
func (c *FakeClientSet) GetPossibleResources() []*metav1.APIResourceList {
return c.DiscoveryObj.PossibleResources
}
// Create a fake Clientset with its Discovery method overridden. // Create a fake Clientset with its Discovery method overridden.
func NewFakeClientset(fakeDiscovery FakeDiscoveryWithError) *FakeClientSet { func NewFakeClientset(fakeDiscovery FakeDiscoveryWithError) *FakeClientSet {
cs := &FakeClientSet{} cs := &FakeClientSet{}
@ -69,7 +77,30 @@ func NewFakeClientset(fakeDiscovery FakeDiscoveryWithError) *FakeClientSet {
return cs 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 { tcs := map[string]struct {
discoveryError error discoveryError error
expectedErr bool expectedErr bool
@ -77,25 +108,13 @@ func TestStartResourceQuotaController_DiscoveryError(t *testing.T) {
}{ }{
"No Discovery Error": { "No Discovery Error": {
discoveryError: nil, discoveryError: nil,
possibleResources: nil, possibleResources: possibleDiscoveryResource(),
expectedErr: false, expectedErr: false,
}, },
"Discovery Calls Partially Failed": { "Discovery Calls Partially Failed": {
discoveryError: new(discovery.ErrGroupDiscoveryFailed), discoveryError: new(discovery.ErrGroupDiscoveryFailed),
possibleResources: []*metav1.APIResourceList{ possibleResources: possibleDiscoveryResource(),
{ expectedErr: false,
GroupVersion: "create/v1",
APIResources: []metav1.APIResource{
{
Name: "jobs",
Verbs: []string{"create", "list", "watch", "delete"},
ShortNames: []string{"jz"},
Categories: []string{"all"},
},
},
},
},
expectedErr: false,
}, },
} }
for name, test := range tcs { for name, test := range tcs {
@ -107,9 +126,16 @@ func TestStartResourceQuotaController_DiscoveryError(t *testing.T) {
InformerFactory: informers.NewSharedInformerFactoryWithOptions(testClientset, time.Duration(1)), InformerFactory: informers.NewSharedInformerFactoryWithOptions(testClientset, time.Duration(1)),
InformersStarted: make(chan struct{}), 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) { 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)
} }
} }
} }

View File

@ -42,7 +42,8 @@
"k8s.io/utils/exec", "k8s.io/utils/exec",
"k8s.io/utils/integer", "k8s.io/utils/integer",
"k8s.io/utils/path", "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/initsystem",
"k8s.io/kubernetes/pkg/util/ipvs", "k8s.io/kubernetes/pkg/util/ipvs",
"k8s.io/kubernetes/pkg/util/metrics", "k8s.io/kubernetes/pkg/util/metrics",
"k8s.io/kubernetes/pkg/util/net/sets",
"k8s.io/kubernetes/pkg/util/node", "k8s.io/kubernetes/pkg/util/node",
"k8s.io/kubernetes/pkg/util/normalizer", "k8s.io/kubernetes/pkg/util/normalizer",
"k8s.io/kubernetes/pkg/util/parsers", "k8s.io/kubernetes/pkg/util/parsers",

View File

@ -28,6 +28,8 @@ go_library(
"//cmd/kubeadm/app/cmd/alpha:go_default_library", "//cmd/kubeadm/app/cmd/alpha:go_default_library",
"//cmd/kubeadm/app/cmd/options:go_default_library", "//cmd/kubeadm/app/cmd/options:go_default_library",
"//cmd/kubeadm/app/cmd/phases: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/phases/workflow:go_default_library",
"//cmd/kubeadm/app/cmd/upgrade:go_default_library", "//cmd/kubeadm/app/cmd/upgrade:go_default_library",
"//cmd/kubeadm/app/cmd/util: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/images:go_default_library",
"//cmd/kubeadm/app/phases/bootstraptoken/node:go_default_library", "//cmd/kubeadm/app/phases/bootstraptoken/node:go_default_library",
"//cmd/kubeadm/app/phases/certs: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/etcd:go_default_library",
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library", "//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
"//cmd/kubeadm/app/phases/kubelet:go_default_library", "//cmd/kubeadm/app/phases/kubelet:go_default_library",

View File

@ -7,7 +7,6 @@ go_library(
"certs.go", "certs.go",
"kubeconfig.go", "kubeconfig.go",
"kubelet.go", "kubelet.go",
"preflight.go",
"selfhosting.go", "selfhosting.go",
], ],
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/cmd/alpha", importpath = "k8s.io/kubernetes/cmd/kubeadm/app/cmd/alpha",

View File

@ -33,7 +33,6 @@ func NewCmdAlpha(in io.Reader, out io.Writer) *cobra.Command {
cmd.AddCommand(newCmdCertsUtility()) cmd.AddCommand(newCmdCertsUtility())
cmd.AddCommand(newCmdKubeletUtility()) cmd.AddCommand(newCmdKubeletUtility())
cmd.AddCommand(newCmdKubeConfigUtility(out)) cmd.AddCommand(newCmdKubeConfigUtility(out))
cmd.AddCommand(newCmdPreFlightUtility())
cmd.AddCommand(NewCmdSelfhosting(in)) cmd.AddCommand(NewCmdSelfhosting(in))
// TODO: This command should be removed as soon as the kubeadm init phase refactoring is completed. // TODO: This command should be removed as soon as the kubeadm init phase refactoring is completed.

View File

@ -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
}

View File

@ -141,7 +141,7 @@ func getSelfhostingSubCommand(in io.Reader) *cobra.Command {
// Add flags to the command // Add flags to the command
// flags bound to the configuration object // flags bound to the configuration object
cmd.Flags().StringVar(&cfg.CertificatesDir, "cert-dir", cfg.CertificatesDir, `The path where certificates are stored`) 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( cmd.Flags().BoolVarP(
&certsInSecrets, "store-certs-in-secrets", "s", &certsInSecrets, "store-certs-in-secrets", "s",

View File

@ -329,7 +329,7 @@ func NewCmdConfigUploadFromFile(out io.Writer, kubeConfigFile *string) *cobra.Co
kubeadmutil.CheckErr(err) 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 return cmd
} }

View File

@ -36,7 +36,7 @@ import (
kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" 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/apis/kubeadm/validation"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" "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" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow"
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" 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 // initialize the workflow runner with the list of phases
initRunner.AppendPhase(phases.NewPreflightMasterPhase()) initRunner.AppendPhase(phases.NewPreflightPhase())
initRunner.AppendPhase(phases.NewKubeletStartPhase()) initRunner.AppendPhase(phases.NewKubeletStartPhase())
initRunner.AppendPhase(phases.NewCertsPhase()) initRunner.AppendPhase(phases.NewCertsPhase())
initRunner.AppendPhase(phases.NewKubeConfigPhase()) 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 // 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) { func AddInitOtherFlags(flagSet *flag.FlagSet, cfgPath *string, skipTokenPrint, dryRun *bool, ignorePreflightErrors *[]string) {
flagSet.StringVar( options.AddConfigFlag(flagSet, cfgPath)
cfgPath, options.CfgPath, *cfgPath,
"Path to kubeadm config file. WARNING: Usage of a configuration file is experimental.",
)
flagSet.StringSliceVar( flagSet.StringSliceVar(
ignorePreflightErrors, options.IgnorePreflightErrors, *ignorePreflightErrors, 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.", "A list of checks whose errors will be shown as warnings. Example: 'IsPrivilegedUser,Swap'. Value 'all' ignores errors from all checks.",

View File

@ -29,6 +29,7 @@ import (
flag "github.com/spf13/pflag" flag "github.com/spf13/pflag"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
clientset "k8s.io/client-go/kubernetes"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api" clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
certutil "k8s.io/client-go/util/cert" certutil "k8s.io/client-go/util/cert"
"k8s.io/klog" "k8s.io/klog"
@ -37,15 +38,12 @@ import (
kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" 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/apis/kubeadm/validation"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" "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" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow"
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/discovery" "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" 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" kubeletphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubelet"
markcontrolplanephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/markcontrolplane" markcontrolplanephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/markcontrolplane"
patchnodephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/patchnode" patchnodephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/patchnode"
@ -161,6 +159,7 @@ type joinData struct {
cfg *kubeadmapi.JoinConfiguration cfg *kubeadmapi.JoinConfiguration
initCfg *kubeadmapi.InitConfiguration initCfg *kubeadmapi.InitConfiguration
tlsBootstrapCfg *clientcmdapi.Config tlsBootstrapCfg *clientcmdapi.Config
clientSets map[string]*clientset.Clientset
ignorePreflightErrors sets.String ignorePreflightErrors sets.String
outputWriter io.Writer outputWriter io.Writer
} }
@ -199,7 +198,9 @@ func NewCmdJoin(out io.Writer, joinOptions *joinOptions) *cobra.Command {
addJoinConfigFlags(cmd.Flags(), joinOptions.externalcfg) addJoinConfigFlags(cmd.Flags(), joinOptions.externalcfg)
addJoinOtherFlags(cmd.Flags(), &joinOptions.cfgPath, &joinOptions.ignorePreflightErrors, &joinOptions.controlPlane, &joinOptions.token) 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 // sets the data builder function, that will be used by the runner
// both when running the entire workflow or single phases // 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{ return &joinData{
cfg: cfg, cfg: cfg,
clientSets: map[string]*clientset.Clientset{},
ignorePreflightErrors: ignorePreflightErrorsSet, ignorePreflightErrors: ignorePreflightErrorsSet,
outputWriter: out, outputWriter: out,
}, nil }, nil
@ -408,6 +410,18 @@ func (j *joinData) InitCfg() (*kubeadmapi.InitConfiguration, error) {
return initCfg, err 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. // IgnorePreflightErrors returns the list of preflight errors to ignore.
func (j *joinData) IgnorePreflightErrors() sets.String { func (j *joinData) IgnorePreflightErrors() sets.String {
return j.ignorePreflightErrors return j.ignorePreflightErrors
@ -432,13 +446,6 @@ func (j *joinData) Run() error {
if err != nil { if err != nil {
return err 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 // Executes the kubelet TLS bootstrap process, that completes with the node
// joining the cluster with a dedicates set of credentials as required by // joining the cluster with a dedicates set of credentials as required by
@ -478,47 +485,6 @@ func (j *joinData) Run() error {
return nil 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. // BootstrapKubelet executes the kubelet TLS bootstrap process.
// This process is executed by the kubelet and completes with the node joining the cluster // 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 // with a dedicates set of credentials as required by the node authorizer

View File

@ -2,77 +2,22 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library( go_library(
name = "go_default_library", name = "go_default_library",
srcs = [ srcs = ["util.go"],
"addons.go",
"bootstraptoken.go",
"certs.go",
"controlplane.go",
"etcd.go",
"kubeconfig.go",
"kubelet.go",
"markcontrolplane.go",
"preflight.go",
"uploadconfig.go",
"util.go",
"waitcontrolplane.go",
],
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases", importpath = "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ 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/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", "//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( go_test(
name = "go_default_test", name = "go_default_test",
srcs = [ srcs = ["util_test.go"],
"certs_test.go",
"util_test.go",
],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//cmd/kubeadm/app/apis/kubeadm/v1beta1: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", "//pkg/version:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library",
], ],
) )
@ -87,6 +32,8 @@ filegroup(
name = "all-srcs", name = "all-srcs",
srcs = [ srcs = [
":package-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", "//cmd/kubeadm/app/cmd/phases/workflow:all-srcs",
], ],
tags = ["automanaged"], tags = ["automanaged"],

View 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"],
)

View File

@ -32,7 +32,7 @@ import (
var ( var (
controlPlaneExample = normalizer.Examples(` 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. # functionally equivalent to what is generated by kubeadm init.
kubeadm init phase control-plane all kubeadm init phase control-plane all
@ -83,20 +83,20 @@ func NewControlPlanePhase() workflow.Phase {
Example: controlPlaneExample, Example: controlPlaneExample,
RunAllSiblings: true, RunAllSiblings: true,
}, },
newControlPlaneSubPhase(kubeadmconstants.KubeAPIServer), newControlPlaneSubphase(kubeadmconstants.KubeAPIServer),
newControlPlaneSubPhase(kubeadmconstants.KubeControllerManager), newControlPlaneSubphase(kubeadmconstants.KubeControllerManager),
newControlPlaneSubPhase(kubeadmconstants.KubeScheduler), newControlPlaneSubphase(kubeadmconstants.KubeScheduler),
}, },
Run: runControlPlanePhase, Run: runControlPlanePhase,
} }
return phase return phase
} }
func newControlPlaneSubPhase(component string) workflow.Phase { func newControlPlaneSubphase(component string) workflow.Phase {
phase := workflow.Phase{ phase := workflow.Phase{
Name: controlPlanePhaseProperties[component].name, Name: controlPlanePhaseProperties[component].name,
Short: controlPlanePhaseProperties[component].short, Short: controlPlanePhaseProperties[component].short,
Run: runControlPlaneSubPhase(component), Run: runControlPlaneSubphase(component),
InheritFlags: getControlPlanePhaseFlags(component), InheritFlags: getControlPlanePhaseFlags(component),
} }
return phase return phase
@ -142,7 +142,7 @@ func runControlPlanePhase(c workflow.RunData) error {
return nil 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 { return func(c workflow.RunData) error {
data, ok := c.(controlPlaneData) data, ok := c.(controlPlaneData)
if !ok { if !ok {

View 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
}

View 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"],
)

View 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)
}

View 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)
}
}

View File

@ -35,11 +35,7 @@ import (
) )
var ( var (
initPreflightExample = normalizer.Examples(` preflightExample = normalizer.Examples(`
# Run master pre-flight checks using a config file.
kubeadm init phase preflight --config kubeadm-config.yml
`)
joinPreflightExample = normalizer.Examples(`
# Run join pre-flight checks using a config file. # Run join pre-flight checks using a config file.
kubeadm join phase preflight --config kubeadm-config.yml 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 type preflightData interface {
// 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 {
Cfg() *kubeadmapi.JoinConfiguration Cfg() *kubeadmapi.JoinConfiguration
InitCfg() (*kubeadmapi.InitConfiguration, error) InitCfg() (*kubeadmapi.InitConfiguration, error)
IgnorePreflightErrors() sets.String IgnorePreflightErrors() sets.String
} }
// NewPreflightMasterPhase creates a kubeadm workflow phase that implements preflight checks for a new master node. // NewPreflightPhase creates a kubeadm workflow phase that implements preflight checks for a new node join
func NewPreflightMasterPhase() workflow.Phase { func NewPreflightPhase() 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 {
return workflow.Phase{ return workflow.Phase{
Name: "preflight", Name: "preflight",
Short: "Run join pre-flight checks", Short: "Run join pre-flight checks",
Long: "Run join pre-flight checks, functionally equivalent to what is implemented by kubeadm join.", Long: "Run pre-flight checks for kubeadm join.",
Example: joinPreflightExample, Example: preflightExample,
Run: runPreflightJoin, Run: runPreflight,
InheritFlags: []string{ InheritFlags: []string{
options.CfgPath, options.CfgPath,
options.IgnorePreflightErrors, options.IgnorePreflightErrors,
@ -139,12 +84,14 @@ func NewPreflightJoinPhase() workflow.Phase {
} }
} }
// runPreflightJoin executes preflight checks logic. // runPreflight executes preflight checks logic.
func runPreflightJoin(c workflow.RunData) error { func runPreflight(c workflow.RunData) error {
j, ok := c.(preflightJoinData) j, ok := c.(preflightData)
if !ok { if !ok {
return errors.New("preflight phase invoked with an invalid data struct") return errors.New("preflight phase invoked with an invalid data struct")
} }
fmt.Println("[preflight] Running pre-flight checks")
// Start with general checks // Start with general checks
klog.V(1).Infoln("[preflight] Running general checks") klog.V(1).Infoln("[preflight] Running general checks")
if err := preflight.RunJoinNodeChecks(utilsexec.New(), j.Cfg(), j.IgnorePreflightErrors()); err != nil { if err := preflight.RunJoinNodeChecks(utilsexec.New(), j.Cfg(), j.IgnorePreflightErrors()); err != nil {
@ -182,7 +129,9 @@ func runPreflightJoin(c workflow.RunData) error {
return err 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 { if err := preflight.RunPullImagesCheck(utilsexec.New(), initCfg, j.IgnorePreflightErrors()); err != nil {
return err return err
} }

View File

@ -129,8 +129,8 @@ func NewCmdToken(out io.Writer, errW io.Writer) *cobra.Command {
kubeadmutil.CheckErr(err) 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, 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.") "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") bto.AddTTLFlagWithName(createCmd.Flags(), "ttl")

View File

@ -122,7 +122,6 @@ go_library(
"//staging/src/k8s.io/apiserver/pkg/server/healthz:go_default_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/feature:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/flag: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:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/typed/authentication/v1beta1: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", "//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/cloud-provider:go_default_library",
"//staging/src/k8s.io/csi-api/pkg/client/clientset/versioned: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/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/coreos/go-systemd/daemon:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library", "//vendor/github.com/spf13/cobra:go_default_library",
"//vendor/github.com/spf13/pflag:go_default_library", "//vendor/github.com/spf13/pflag:go_default_library",

View File

@ -48,7 +48,6 @@ import (
"k8s.io/apiserver/pkg/server/healthz" "k8s.io/apiserver/pkg/server/healthz"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/apiserver/pkg/util/flag" "k8s.io/apiserver/pkg/util/flag"
"k8s.io/client-go/dynamic"
clientset "k8s.io/client-go/kubernetes" clientset "k8s.io/client-go/kubernetes"
certificatesclient "k8s.io/client-go/kubernetes/typed/certificates/v1beta1" certificatesclient "k8s.io/client-go/kubernetes/typed/certificates/v1beta1"
v1core "k8s.io/client-go/kubernetes/typed/core/v1" v1core "k8s.io/client-go/kubernetes/typed/core/v1"
@ -95,6 +94,7 @@ import (
"k8s.io/kubernetes/pkg/util/rlimit" "k8s.io/kubernetes/pkg/util/rlimit"
"k8s.io/kubernetes/pkg/version" "k8s.io/kubernetes/pkg/version"
"k8s.io/kubernetes/pkg/version/verflag" "k8s.io/kubernetes/pkg/version/verflag"
nodeapiclientset "k8s.io/node-api/pkg/client/clientset/versioned"
"k8s.io/utils/exec" "k8s.io/utils/exec"
"k8s.io/utils/nsenter" "k8s.io/utils/nsenter"
) )
@ -545,12 +545,11 @@ func run(s *options.KubeletServer, kubeDeps *kubelet.Dependencies, stopCh <-chan
switch { switch {
case standaloneMode: case standaloneMode:
kubeDeps.KubeClient = nil kubeDeps.KubeClient = nil
kubeDeps.DynamicKubeClient = nil
kubeDeps.EventClient = nil kubeDeps.EventClient = nil
kubeDeps.HeartbeatClient = nil kubeDeps.HeartbeatClient = nil
klog.Warningf("standalone mode, no API client") 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) clientConfig, closeAllConns, err := buildKubeletClientConfig(s, nodeName)
if err != nil { if err != nil {
return err 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) 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 // make a separate client for events
eventClientConfig := *clientConfig eventClientConfig := *clientConfig
eventClientConfig.QPS = float32(s.EventRecordQPS) 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 // CRDs are JSON only, and client renegotiation for streaming is not correct as per #67803
csiClientConfig := restclient.CopyConfig(clientConfig) crdClientConfig := restclient.CopyConfig(clientConfig)
csiClientConfig.ContentType = "application/json" crdClientConfig.ContentType = "application/json"
kubeDeps.CSIClient, err = csiclientset.NewForConfig(csiClientConfig) kubeDeps.CSIClient, err = csiclientset.NewForConfig(crdClientConfig)
if err != nil { if err != nil {
return fmt.Errorf("failed to initialize kubelet storage client: %v", err) 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 // If the kubelet config controller is available, and dynamic config is enabled, start the config and status sync loops

View File

@ -21,6 +21,21 @@ set -o pipefail
KUBE_ROOT=$(dirname "${BASH_SOURCE}")/.. KUBE_ROOT=$(dirname "${BASH_SOURCE}")/..
source "${KUBE_ROOT}/hack/lib/init.sh" 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" # $1 = filename pattern as in "zz_generated.$1.go"
function find_genfiles() { function find_genfiles() {
find . \ find . \

View File

@ -176,6 +176,11 @@ func collectResourcePaths(t *testing.T, resourcename string, path *field.Path, n
case reflect.Ptr: case reflect.Ptr:
resourcePaths.Insert(collectResourcePaths(t, resourcename, path, name, tp.Elem()).List()...) resourcePaths.Insert(collectResourcePaths(t, resourcename, path, name, tp.Elem()).List()...)
case reflect.Struct: 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++ { for i := 0; i < tp.NumField(); i++ {
field := tp.Field(i) field := tp.Field(i)
resourcePaths.Insert(collectResourcePaths(t, resourcename, path.Child(field.Name), field.Name, field.Type).List()...) resourcePaths.Insert(collectResourcePaths(t, resourcename, path.Child(field.Name), field.Name, field.Type).List()...)

View File

@ -12,7 +12,7 @@ go_library(
importpath = "k8s.io/kubernetes/pkg/api/service", importpath = "k8s.io/kubernetes/pkg/api/service",
deps = [ deps = [
"//pkg/apis/core:go_default_library", "//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"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/util/net/sets:go_default_library", "//vendor/k8s.io/utils/net:go_default_library",
], ],
) )

View File

@ -18,17 +18,18 @@ package service
import ( import (
"fmt" "fmt"
api "k8s.io/kubernetes/pkg/apis/core"
netsets "k8s.io/kubernetes/pkg/util/net/sets"
"strings" "strings"
api "k8s.io/kubernetes/pkg/apis/core"
utilnet "k8s.io/utils/net"
) )
const ( const (
defaultLoadBalancerSourceRanges = "0.0.0.0/0" defaultLoadBalancerSourceRanges = "0.0.0.0/0"
) )
// IsAllowAll checks whether the netsets.IPNet allows traffic from 0.0.0.0/0 // IsAllowAll checks whether the utilnet.IPNet allows traffic from 0.0.0.0/0
func IsAllowAll(ipnets netsets.IPNet) bool { func IsAllowAll(ipnets utilnet.IPNetSet) bool {
for _, s := range ipnets.StringSlice() { for _, s := range ipnets.StringSlice() {
if s == "0.0.0.0/0" { if s == "0.0.0.0/0" {
return true return true
@ -40,13 +41,13 @@ func IsAllowAll(ipnets netsets.IPNet) bool {
// GetLoadBalancerSourceRanges first try to parse and verify LoadBalancerSourceRanges field from a service. // 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, // 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. // extracting the source ranges to allow, and if not present returns a default (allow-all) value.
func GetLoadBalancerSourceRanges(service *api.Service) (netsets.IPNet, error) { func GetLoadBalancerSourceRanges(service *api.Service) (utilnet.IPNetSet, error) {
var ipnets netsets.IPNet var ipnets utilnet.IPNetSet
var err error var err error
// if SourceRange field is specified, ignore sourceRange annotation // if SourceRange field is specified, ignore sourceRange annotation
if len(service.Spec.LoadBalancerSourceRanges) > 0 { if len(service.Spec.LoadBalancerSourceRanges) > 0 {
specs := service.Spec.LoadBalancerSourceRanges specs := service.Spec.LoadBalancerSourceRanges
ipnets, err = netsets.ParseIPNets(specs...) ipnets, err = utilnet.ParseIPNets(specs...)
if err != nil { 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) 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 val = defaultLoadBalancerSourceRanges
} }
specs := strings.Split(val, ",") specs := strings.Split(val, ",")
ipnets, err = netsets.ParseIPNets(specs...) ipnets, err = utilnet.ParseIPNets(specs...)
if err != nil { 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) 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)
} }

View File

@ -21,7 +21,7 @@ import (
"testing" "testing"
api "k8s.io/kubernetes/pkg/apis/core" 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) { 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/32, ")
checkError("10.0.0.1") checkError("10.0.0.1")
checkOK := func(v string) netsets.IPNet { checkOK := func(v string) utilnet.IPNetSet {
annotations := make(map[string]string) annotations := make(map[string]string)
annotations[api.AnnotationLoadBalancerSourceRangesKey] = v annotations[api.AnnotationLoadBalancerSourceRangesKey] = v
svc := api.Service{} svc := api.Service{}
@ -112,7 +112,7 @@ func TestGetLoadBalancerSourceRanges(t *testing.T) {
func TestAllowAll(t *testing.T) { func TestAllowAll(t *testing.T) {
checkAllowAll := func(allowAll bool, cidrs ...string) { checkAllowAll := func(allowAll bool, cidrs ...string) {
ipnets, err := netsets.ParseIPNets(cidrs...) ipnets, err := utilnet.ParseIPNets(cidrs...)
if err != nil { if err != nil {
t.Errorf("Unexpected error parsing cidrs: %v", cidrs) t.Errorf("Unexpected error parsing cidrs: %v", cidrs)
} }

View File

@ -26,7 +26,6 @@ import (
"testing" "testing"
jsoniter "github.com/json-iterator/go" jsoniter "github.com/json-iterator/go"
appsv1 "k8s.io/api/apps/v1" appsv1 "k8s.io/api/apps/v1"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/apitesting/fuzzer" "k8s.io/apimachinery/pkg/api/apitesting/fuzzer"
@ -162,9 +161,10 @@ var nonRoundTrippableTypes = sets.NewString(
"DeleteOptions", "DeleteOptions",
"CreateOptions", "CreateOptions",
"UpdateOptions", "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 // TestCommonKindsRegistered verifies that all group/versions registered with
// the testapi package have the common kinds. // the testapi package have the common kinds.

View File

@ -18,9 +18,8 @@ package persistentvolume
import ( import (
"reflect" "reflect"
"testing"
"strings" "strings"
"testing"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/sets" "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: case reflect.Ptr:
secretPaths.Insert(collectSecretPaths(t, path, name, tp.Elem()).List()...) secretPaths.Insert(collectSecretPaths(t, path, name, tp.Elem()).List()...)
case reflect.Struct: 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++ { for i := 0; i < tp.NumField(); i++ {
field := tp.Field(i) field := tp.Field(i)
secretPaths.Insert(collectSecretPaths(t, path.Child(field.Name), field.Name, field.Type).List()...) secretPaths.Insert(collectSecretPaths(t, path.Child(field.Name), field.Name, field.Type).List()...)

View File

@ -340,6 +340,11 @@ func collectResourcePaths(t *testing.T, resourcename string, path *field.Path, n
case reflect.Ptr: case reflect.Ptr:
resourcePaths.Insert(collectResourcePaths(t, resourcename, path, name, tp.Elem()).List()...) resourcePaths.Insert(collectResourcePaths(t, resourcename, path, name, tp.Elem()).List()...)
case reflect.Struct: 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++ { for i := 0; i < tp.NumField(); i++ {
field := tp.Field(i) field := tp.Field(i)
resourcePaths.Insert(collectResourcePaths(t, resourcename, path.Child(field.Name), field.Name, field.Type).List()...) resourcePaths.Insert(collectResourcePaths(t, resourcename, path.Child(field.Name), field.Name, field.Type).List()...)

View File

@ -11,8 +11,8 @@ go_library(
srcs = ["util.go"], srcs = ["util.go"],
importpath = "k8s.io/kubernetes/pkg/api/v1/service", importpath = "k8s.io/kubernetes/pkg/api/v1/service",
deps = [ deps = [
"//pkg/util/net/sets:go_default_library",
"//staging/src/k8s.io/api/core/v1: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"], srcs = ["util_test.go"],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/util/net/sets:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/utils/net:go_default_library",
], ],
) )

View File

@ -21,15 +21,15 @@ import (
"strings" "strings"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
netsets "k8s.io/kubernetes/pkg/util/net/sets" utilnet "k8s.io/utils/net"
) )
const ( const (
defaultLoadBalancerSourceRanges = "0.0.0.0/0" defaultLoadBalancerSourceRanges = "0.0.0.0/0"
) )
// IsAllowAll checks whether the netsets.IPNet allows traffic from 0.0.0.0/0 // IsAllowAll checks whether the utilnet.IPNet allows traffic from 0.0.0.0/0
func IsAllowAll(ipnets netsets.IPNet) bool { func IsAllowAll(ipnets utilnet.IPNetSet) bool {
for _, s := range ipnets.StringSlice() { for _, s := range ipnets.StringSlice() {
if s == "0.0.0.0/0" { if s == "0.0.0.0/0" {
return true return true
@ -41,13 +41,13 @@ func IsAllowAll(ipnets netsets.IPNet) bool {
// GetLoadBalancerSourceRanges first try to parse and verify LoadBalancerSourceRanges field from a service. // 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, // 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. // extracting the source ranges to allow, and if not present returns a default (allow-all) value.
func GetLoadBalancerSourceRanges(service *v1.Service) (netsets.IPNet, error) { func GetLoadBalancerSourceRanges(service *v1.Service) (utilnet.IPNetSet, error) {
var ipnets netsets.IPNet var ipnets utilnet.IPNetSet
var err error var err error
// if SourceRange field is specified, ignore sourceRange annotation // if SourceRange field is specified, ignore sourceRange annotation
if len(service.Spec.LoadBalancerSourceRanges) > 0 { if len(service.Spec.LoadBalancerSourceRanges) > 0 {
specs := service.Spec.LoadBalancerSourceRanges specs := service.Spec.LoadBalancerSourceRanges
ipnets, err = netsets.ParseIPNets(specs...) ipnets, err = utilnet.ParseIPNets(specs...)
if err != nil { 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) 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 val = defaultLoadBalancerSourceRanges
} }
specs := strings.Split(val, ",") specs := strings.Split(val, ",")
ipnets, err = netsets.ParseIPNets(specs...) ipnets, err = utilnet.ParseIPNets(specs...)
if err != nil { 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) 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)
} }

View File

@ -21,7 +21,7 @@ import (
"testing" "testing"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
netsets "k8s.io/kubernetes/pkg/util/net/sets" utilnet "k8s.io/utils/net"
) )
func TestGetLoadBalancerSourceRanges(t *testing.T) { 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/32, ")
checkError("10.0.0.1") checkError("10.0.0.1")
checkOK := func(v string) netsets.IPNet { checkOK := func(v string) utilnet.IPNetSet {
annotations := make(map[string]string) annotations := make(map[string]string)
annotations[v1.AnnotationLoadBalancerSourceRangesKey] = v annotations[v1.AnnotationLoadBalancerSourceRangesKey] = v
svc := v1.Service{} svc := v1.Service{}
@ -112,7 +112,7 @@ func TestGetLoadBalancerSourceRanges(t *testing.T) {
func TestAllowAll(t *testing.T) { func TestAllowAll(t *testing.T) {
checkAllowAll := func(allowAll bool, cidrs ...string) { checkAllowAll := func(allowAll bool, cidrs ...string) {
ipnets, err := netsets.ParseIPNets(cidrs...) ipnets, err := utilnet.ParseIPNets(cidrs...)
if err != nil { if err != nil {
t.Errorf("Unexpected error parsing cidrs: %v", cidrs) t.Errorf("Unexpected error parsing cidrs: %v", cidrs)
} }

View File

@ -56,7 +56,9 @@ func ValidateSelfSubjectRulesReview(review *authorizationapi.SelfSubjectRulesRev
func ValidateSubjectAccessReview(sar *authorizationapi.SubjectAccessReview) field.ErrorList { func ValidateSubjectAccessReview(sar *authorizationapi.SubjectAccessReview) field.ErrorList {
allErrs := ValidateSubjectAccessReviewSpec(sar.Spec, field.NewPath("spec")) 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`)) allErrs = append(allErrs, field.Invalid(field.NewPath("metadata"), sar.ObjectMeta, `must be empty`))
} }
return allErrs return allErrs
@ -64,7 +66,9 @@ func ValidateSubjectAccessReview(sar *authorizationapi.SubjectAccessReview) fiel
func ValidateSelfSubjectAccessReview(sar *authorizationapi.SelfSubjectAccessReview) field.ErrorList { func ValidateSelfSubjectAccessReview(sar *authorizationapi.SelfSubjectAccessReview) field.ErrorList {
allErrs := ValidateSelfSubjectAccessReviewSpec(sar.Spec, field.NewPath("spec")) 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`)) allErrs = append(allErrs, field.Invalid(field.NewPath("metadata"), sar.ObjectMeta, `must be empty`))
} }
return allErrs return allErrs
@ -75,6 +79,7 @@ func ValidateLocalSubjectAccessReview(sar *authorizationapi.LocalSubjectAccessRe
objectMetaShallowCopy := sar.ObjectMeta objectMetaShallowCopy := sar.ObjectMeta
objectMetaShallowCopy.Namespace = "" objectMetaShallowCopy.Namespace = ""
objectMetaShallowCopy.ManagedFields = nil
if !apiequality.Semantic.DeepEqual(metav1.ObjectMeta{}, objectMetaShallowCopy) { if !apiequality.Semantic.DeepEqual(metav1.ObjectMeta{}, objectMetaShallowCopy) {
allErrs = append(allErrs, field.Invalid(field.NewPath("metadata"), sar.ObjectMeta, `must be empty except for namespace`)) allErrs = append(allErrs, field.Invalid(field.NewPath("metadata"), sar.ObjectMeta, `must be empty except for namespace`))
} }

View File

@ -918,6 +918,11 @@ type QuobyteVolumeSource struct {
// Default is no group // Default is no group
// +optional // +optional
Group string 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. // Represents a Glusterfs mount that lasts the lifetime of a pod.

View File

@ -5989,6 +5989,7 @@ func autoConvert_v1_QuobyteVolumeSource_To_core_QuobyteVolumeSource(in *v1.Quoby
out.ReadOnly = in.ReadOnly out.ReadOnly = in.ReadOnly
out.User = in.User out.User = in.User
out.Group = in.Group out.Group = in.Group
out.Tenant = in.Tenant
return nil return nil
} }
@ -6003,6 +6004,7 @@ func autoConvert_core_QuobyteVolumeSource_To_v1_QuobyteVolumeSource(in *core.Quo
out.ReadOnly = in.ReadOnly out.ReadOnly = in.ReadOnly
out.User = in.User out.User = in.User
out.Group = in.Group out.Group = in.Group
out.Tenant = in.Tenant
return nil return nil
} }

View File

@ -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 { 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")) 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 source.HostPath != nil {
if numVolumes > 0 { if numVolumes > 0 {
@ -873,6 +870,10 @@ func validateQuobyteVolumeSource(quobyte *core.QuobyteVolumeSource, fldPath *fie
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
if len(quobyte.Registry) == 0 { 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")) 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 { } else {
for _, hostPortPair := range strings.Split(quobyte.Registry, ",") { for _, hostPortPair := range strings.Split(quobyte.Registry, ",") {
if _, _, err := net.SplitHostPort(hostPortPair); err != nil { 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.Containers, specPath.Child("containers"))...)
allErrs = append(allErrs, validateContainersOnlyForPod(pod.Spec.InitContainers, specPath.Child("initContainers"))...) allErrs = append(allErrs, validateContainersOnlyForPod(pod.Spec.InitContainers, specPath.Child("initContainers"))...)
if utilfeature.DefaultFeatureGate.Enabled(features.HugePages) { hugePageResources := sets.NewString()
hugePageResources := sets.NewString() for i := range pod.Spec.Containers {
for i := range pod.Spec.Containers { resourceSet := toContainerResourcesSet(&pod.Spec.Containers[i])
resourceSet := toContainerResourcesSet(&pod.Spec.Containers[i]) for resourceStr := range resourceSet {
for resourceStr := range resourceSet { if v1helper.IsHugePageResourceName(v1.ResourceName(resourceStr)) {
if v1helper.IsHugePageResourceName(v1.ResourceName(resourceStr)) { hugePageResources.Insert(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 return allErrs

View File

@ -3379,6 +3379,7 @@ func TestValidateVolumes(t *testing.T) {
ReadOnly: false, ReadOnly: false,
User: "root", User: "root",
Group: "root", Group: "root",
Tenant: "ThisIsSomeTenantUUID",
}, },
}, },
}, },
@ -3390,6 +3391,7 @@ func TestValidateVolumes(t *testing.T) {
VolumeSource: core.VolumeSource{ VolumeSource: core.VolumeSource{
Quobyte: &core.QuobyteVolumeSource{ Quobyte: &core.QuobyteVolumeSource{
Volume: "/test", Volume: "/test",
Tenant: "ThisIsSomeTenantUUID",
}, },
}, },
}, },
@ -3406,6 +3408,7 @@ func TestValidateVolumes(t *testing.T) {
Quobyte: &core.QuobyteVolumeSource{ Quobyte: &core.QuobyteVolumeSource{
Registry: "registry7861", Registry: "registry7861",
Volume: "/test", Volume: "/test",
Tenant: "ThisIsSomeTenantUUID",
}, },
}, },
}, },
@ -3422,6 +3425,7 @@ func TestValidateVolumes(t *testing.T) {
Quobyte: &core.QuobyteVolumeSource{ Quobyte: &core.QuobyteVolumeSource{
Registry: "registry:7861,reg2", Registry: "registry:7861,reg2",
Volume: "/test", Volume: "/test",
Tenant: "ThisIsSomeTenantUUID",
}, },
}, },
}, },
@ -3437,6 +3441,7 @@ func TestValidateVolumes(t *testing.T) {
VolumeSource: core.VolumeSource{ VolumeSource: core.VolumeSource{
Quobyte: &core.QuobyteVolumeSource{ Quobyte: &core.QuobyteVolumeSource{
Registry: "registry:7861", Registry: "registry:7861",
Tenant: "ThisIsSomeTenantUUID",
}, },
}, },
}, },
@ -3445,6 +3450,40 @@ func TestValidateVolumes(t *testing.T) {
field: "quobyte.volume", 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 // AzureDisk
{ {
name: "valid 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) 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}} hugePagesCase := core.VolumeSource{EmptyDir: &core.EmptyDirVolumeSource{Medium: core.StorageMediumHugePages}}
// Enable HugePages // Enable HugePages
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HugePages, true)()
if errs := validateVolumeSource(&hugePagesCase, field.NewPath("field").Index(0), "working"); len(errs) != 0 { if errs := validateVolumeSource(&hugePagesCase, field.NewPath("field").Index(0), "working"); len(errs) != 0 {
t.Errorf("Unexpected error when HugePages feature is enabled.") 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{ successCases := []core.Pod{
{ // Basic fields. { // Basic fields.
ObjectMeta: metav1.ObjectMeta{Name: "123", Namespace: "ns"}, 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 { for i := range successCases {
pod := &successCases[i] pod := &successCases[i]
if errs := ValidatePod(pod); len(errs) != 0 { 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) 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) { func TestPVCVolumeMode(t *testing.T) {
@ -6686,6 +6707,33 @@ func TestValidatePod(t *testing.T) {
DNSPolicy: core.DNSClusterFirst, 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 { for _, pod := range successCases {
if errs := ValidatePod(&pod); len(errs) != 0 { if errs := ValidatePod(&pod); len(errs) != 0 {

View File

@ -1,27 +1,32 @@
{ {
"Rules": [ "Rules": [
{ {
"SelectorRegexp": "k8s[.]io/kubernetes", "SelectorRegexp": "k8s[.]io/utils",
"AllowedPrefixes": [ "AllowedPrefixes": [
"k8s.io/kubernetes/pkg/api/legacyscheme", "k8s.io/utils/net",
"k8s.io/kubernetes/pkg/api/service", "k8s.io/utils/nsenter",
"k8s.io/kubernetes/pkg/api/v1/service", "k8s.io/utils/io",
"k8s.io/kubernetes/pkg/apis/core", "k8s.io/utils/strings",
"k8s.io/kubernetes/pkg/cloudprovider", "k8s.io/utils/exec",
"k8s.io/kubernetes/pkg/credentialprovider", "k8s.io/utils/path"
"k8s.io/kubernetes/pkg/features", ]
"k8s.io/kubernetes/pkg/kubelet/apis", },
"k8s.io/kubernetes/pkg/master/ports", {
"k8s.io/kubernetes/pkg/util/mount", "SelectorRegexp": "k8s[.]io/kubernetes",
"k8s.io/kubernetes/pkg/util/file", "AllowedPrefixes": [
"k8s.io/kubernetes/pkg/util/net/sets", "k8s.io/kubernetes/pkg/api/legacyscheme",
"k8s.io/kubernetes/pkg/util/resizefs", "k8s.io/kubernetes/pkg/apis/core",
"k8s.io/kubernetes/pkg/util/strings", "k8s.io/kubernetes/pkg/cloudprovider",
"k8s.io/kubernetes/pkg/version", "k8s.io/kubernetes/pkg/credentialprovider",
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/features",
], "k8s.io/kubernetes/pkg/kubelet/apis",
"ForbiddenPrefixes": [ "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": []
}
] ]
} }

View File

@ -27,7 +27,6 @@ go_library(
], ],
importpath = "k8s.io/kubernetes/pkg/cloudprovider/providers/aws", importpath = "k8s.io/kubernetes/pkg/cloudprovider/providers/aws",
deps = [ deps = [
"//pkg/api/v1/service:go_default_library",
"//pkg/credentialprovider/aws:go_default_library", "//pkg/credentialprovider/aws:go_default_library",
"//pkg/kubelet/apis:go_default_library", "//pkg/kubelet/apis:go_default_library",
"//pkg/volume: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/client-go/tools/record:go_default_library",
"//staging/src/k8s.io/cloud-provider: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/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:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/awserr: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", "//vendor/github.com/aws/aws-sdk-go/aws/credentials:go_default_library",

View File

@ -59,7 +59,7 @@ import (
"k8s.io/client-go/tools/record" "k8s.io/client-go/tools/record"
cloudprovider "k8s.io/cloud-provider" cloudprovider "k8s.io/cloud-provider"
nodehelpers "k8s.io/cloud-provider/node/helpers" 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" kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
@ -3434,7 +3434,7 @@ func (c *Cloud) EnsureLoadBalancer(ctx context.Context, clusterName string, apiS
return nil, err return nil, err
} }
sourceRanges, err := service.GetLoadBalancerSourceRanges(apiService) sourceRanges, err := servicehelpers.GetLoadBalancerSourceRanges(apiService)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -3450,7 +3450,7 @@ func (c *Cloud) EnsureLoadBalancer(ctx context.Context, clusterName string, apiS
if isNLB(annotations) { if isNLB(annotations) {
if path, healthCheckNodePort := service.GetServiceHealthCheckPathPort(apiService); path != "" { if path, healthCheckNodePort := servicehelpers.GetServiceHealthCheckPathPort(apiService); path != "" {
for i := range v2Mappings { for i := range v2Mappings {
v2Mappings[i].HealthCheckPort = int64(healthCheckNodePort) v2Mappings[i].HealthCheckPort = int64(healthCheckNodePort)
v2Mappings[i].HealthCheckPath = path 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) 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) err = c.ensureLoadBalancerHealthCheck(loadBalancer, "HTTP", healthCheckNodePort, path, annotations)
if err != nil { if err != nil {

View File

@ -36,7 +36,6 @@ go_library(
], ],
importpath = "k8s.io/kubernetes/pkg/cloudprovider/providers/azure", importpath = "k8s.io/kubernetes/pkg/cloudprovider/providers/azure",
deps = [ deps = [
"//pkg/api/v1/service:go_default_library",
"//pkg/cloudprovider/providers/azure/auth:go_default_library", "//pkg/cloudprovider/providers/azure/auth:go_default_library",
"//pkg/kubelet/apis:go_default_library", "//pkg/kubelet/apis:go_default_library",
"//pkg/volume: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/tools/record:go_default_library",
"//staging/src/k8s.io/client-go/util/flowcontrol: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: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/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/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", "//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"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/api/v1/service:go_default_library",
"//pkg/cloudprovider/providers/azure/auth:go_default_library", "//pkg/cloudprovider/providers/azure/auth:go_default_library",
"//pkg/kubelet/apis:go_default_library", "//pkg/kubelet/apis:go_default_library",
"//staging/src/k8s.io/api/core/v1: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/types:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets: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: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/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/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", "//vendor/github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2018-07-01/storage:go_default_library",

View File

@ -27,8 +27,8 @@ import (
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
cloudprovider "k8s.io/cloud-provider" cloudprovider "k8s.io/cloud-provider"
servicehelpers "k8s.io/cloud-provider/service/helpers"
"k8s.io/klog" "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/azure-sdk-for-go/services/network/mgmt/2017-09-01/network"
"github.com/Azure/go-autorest/autorest/to" "github.com/Azure/go-autorest/autorest/to"
@ -888,8 +888,8 @@ func (az *Cloud) reconcileLoadBalancerRule(
return expectedProbes, expectedRules, err return expectedProbes, expectedRules, err
} }
if serviceapi.NeedsHealthCheck(service) { if servicehelpers.NeedsHealthCheck(service) {
podPresencePath, podPresencePort := serviceapi.GetServiceHealthCheckPathPort(service) podPresencePath, podPresencePort := servicehelpers.GetServiceHealthCheckPathPort(service)
expectedProbes = append(expectedProbes, network.Probe{ expectedProbes = append(expectedProbes, network.Probe{
Name: &lbRuleName, Name: &lbRuleName,
@ -983,7 +983,7 @@ func (az *Cloud) reconcileSecurityGroup(clusterName string, service *v1.Service,
destinationIPAddress = "*" destinationIPAddress = "*"
} }
sourceRanges, err := serviceapi.GetLoadBalancerSourceRanges(service) sourceRanges, err := servicehelpers.GetLoadBalancerSourceRanges(service)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -992,7 +992,7 @@ func (az *Cloud) reconcileSecurityGroup(clusterName string, service *v1.Service,
return nil, err return nil, err
} }
var sourceAddressPrefixes []string var sourceAddressPrefixes []string
if (sourceRanges == nil || serviceapi.IsAllowAll(sourceRanges)) && len(serviceTags) == 0 { if (sourceRanges == nil || servicehelpers.IsAllowAll(sourceRanges)) && len(serviceTags) == 0 {
if !requiresInternalLoadBalancer(service) { if !requiresInternalLoadBalancer(service) {
sourceAddressPrefixes = []string{"Internet"} sourceAddressPrefixes = []string{"Internet"}
} }

View File

@ -30,7 +30,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets" "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" "k8s.io/kubernetes/pkg/cloudprovider/providers/azure/auth"
kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis" kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
@ -1231,8 +1231,8 @@ func validateLoadBalancer(t *testing.T, loadBalancer *network.LoadBalancer, serv
expectedProbeCount++ expectedProbeCount++
foundProbe := false foundProbe := false
if serviceapi.NeedsHealthCheck(&svc) { if servicehelpers.NeedsHealthCheck(&svc) {
path, port := serviceapi.GetServiceHealthCheckPathPort(&svc) path, port := servicehelpers.GetServiceHealthCheckPathPort(&svc)
for _, actualProbe := range *loadBalancer.Probes { for _, actualProbe := range *loadBalancer.Probes {
if strings.EqualFold(*actualProbe.Name, wantedRuleName) && if strings.EqualFold(*actualProbe.Name, wantedRuleName) &&
*actualProbe.Port == port && *actualProbe.Port == port &&

View File

@ -46,9 +46,7 @@ go_library(
], ],
importpath = "k8s.io/kubernetes/pkg/cloudprovider/providers/gce", importpath = "k8s.io/kubernetes/pkg/cloudprovider/providers/gce",
deps = [ deps = [
"//pkg/api/v1/service:go_default_library",
"//pkg/kubelet/apis:go_default_library", "//pkg/kubelet/apis:go_default_library",
"//pkg/util/net/sets:go_default_library",
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//staging/src/k8s.io/api/core/v1: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/client-go/util/flowcontrol:go_default_library",
"//staging/src/k8s.io/cloud-provider: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/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/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:go_default_library",
"//vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/filter: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/google.golang.org/api/tpu/v1:go_default_library",
"//vendor/gopkg.in/gcfg.v1:go_default_library", "//vendor/gopkg.in/gcfg.v1:go_default_library",
"//vendor/k8s.io/klog: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"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/api/v1/service:go_default_library",
"//pkg/kubelet/apis: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/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/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/types:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets: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/client-go/tools/record:go_default_library",
"//staging/src/k8s.io/cloud-provider: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: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/meta:go_default_library",
"//vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/mock: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/v0.beta:go_default_library",
"//vendor/google.golang.org/api/compute/v1:go_default_library", "//vendor/google.golang.org/api/compute/v1:go_default_library",
"//vendor/google.golang.org/api/googleapi:go_default_library", "//vendor/google.golang.org/api/googleapi:go_default_library",
"//vendor/k8s.io/utils/net:go_default_library",
], ],
) )

View File

@ -24,16 +24,16 @@ import (
"sort" "sort"
"strings" "strings"
"k8s.io/api/core/v1"
"k8s.io/klog" "k8s.io/klog"
"github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud" "github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud"
"k8s.io/api/core/v1"
cloudprovider "k8s.io/cloud-provider" cloudprovider "k8s.io/cloud-provider"
netsets "k8s.io/kubernetes/pkg/util/net/sets" utilnet "k8s.io/utils/net"
) )
type cidrs struct { type cidrs struct {
ipn netsets.IPNet ipn utilnet.IPNetSet
isSet bool isSet bool
} }
@ -44,7 +44,7 @@ var (
func init() { func init() {
var err error var err error
// LB L7 proxies and all L3/4/7 health checkers have client addresses within these known CIDRs. // 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 { if err != nil {
panic("Incorrect default GCE L7 source ranges") 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 // On first Set(), clear the original defaults
if !c.isSet { if !c.isSet {
c.isSet = true c.isSet = true
c.ipn = make(netsets.IPNet) c.ipn = make(utilnet.IPNetSet)
} else { } else {
return fmt.Errorf("GCE LB CIDRs have already been set") return fmt.Errorf("GCE LB CIDRs have already been set")
} }

View File

@ -28,8 +28,8 @@ import (
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
utilerrors "k8s.io/apimachinery/pkg/util/errors" utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
apiservice "k8s.io/kubernetes/pkg/api/v1/service" servicehelpers "k8s.io/cloud-provider/service/helpers"
netsets "k8s.io/kubernetes/pkg/util/net/sets" utilnet "k8s.io/utils/net"
computealpha "google.golang.org/api/compute/v0.alpha" computealpha "google.golang.org/api/compute/v0.alpha"
compute "google.golang.org/api/compute/v1" 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 // is because the forwarding rule is used as the indicator that the load
// balancer is fully created - it's what getLoadBalancer checks for. // balancer is fully created - it's what getLoadBalancer checks for.
// Check if user specified the allow source range // Check if user specified the allow source range
sourceRanges, err := apiservice.GetLoadBalancerSourceRanges(apiService) sourceRanges, err := servicehelpers.GetLoadBalancerSourceRanges(apiService)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -206,7 +206,7 @@ func (g *Cloud) ensureExternalLoadBalancer(clusterName string, clusterID string,
if err != nil && !isHTTPErrorCode(err, http.StatusNotFound) { if err != nil && !isHTTPErrorCode(err, http.StatusNotFound) {
return nil, fmt.Errorf("error checking HTTP health check for load balancer (%s): %v", lbRefStr, err) 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) klog.V(4).Infof("ensureExternalLoadBalancer(%s): Service needs local traffic health checks on: %d%s.", lbRefStr, healthCheckNodePort, path)
if hcLocalTrafficExisting == nil { if hcLocalTrafficExisting == nil {
// This logic exists to detect a transition for non-OnlyLocal to OnlyLocal service // 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) lbRefStr := fmt.Sprintf("%v(%v)", loadBalancerName, serviceName)
var hcNames []string var hcNames []string
if path, _ := apiservice.GetServiceHealthCheckPathPort(service); path != "" { if path, _ := servicehelpers.GetServiceHealthCheckPathPort(service); path != "" {
hcToDelete, err := g.GetHTTPHealthCheck(loadBalancerName) hcToDelete, err := g.GetHTTPHealthCheck(loadBalancerName)
if err != nil && !isHTTPErrorCode(err, http.StatusNotFound) { if err != nil && !isHTTPErrorCode(err, http.StatusNotFound) {
klog.Infof("ensureExternalLoadBalancerDeleted(%s): Failed to retrieve health check:%v.", lbRefStr, err) 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)) fw, err := g.GetFirewall(MakeFirewallName(name))
if err != nil { if err != nil {
if isHTTPErrorCode(err, http.StatusNotFound) { 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. // 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 { if err != nil {
// This really shouldn't happen... GCE has returned something unexpected // This really shouldn't happen... GCE has returned something unexpected
klog.Warningf("Error parsing firewall SourceRanges: %v", fw.SourceRanges) klog.Warningf("Error parsing firewall SourceRanges: %v", fw.SourceRanges)
@ -934,7 +934,7 @@ func createForwardingRule(s CloudForwardingRuleService, name, serviceName, regio
return nil 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) firewall, err := g.firewallObject(name, region, desc, sourceRanges, ports, hosts)
if err != nil { if err != nil {
return err return err
@ -952,7 +952,7 @@ func (g *Cloud) createFirewall(svc *v1.Service, name, region, desc string, sourc
return nil 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) firewall, err := g.firewallObject(name, region, desc, sourceRanges, ports, hosts)
if err != nil { if err != nil {
return err return err
@ -971,7 +971,7 @@ func (g *Cloud) updateFirewall(svc *v1.Service, name, region, desc string, sourc
return nil 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)) allowedPorts := make([]string, len(ports))
for ix := range ports { for ix := range ports {
allowedPorts[ix] = strconv.Itoa(int(ports[ix].Port)) allowedPorts[ix] = strconv.Itoa(int(ports[ix].Port))

View File

@ -34,7 +34,7 @@ import (
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/tools/record" "k8s.io/client-go/tools/record"
netsets "k8s.io/kubernetes/pkg/util/net/sets" utilnet "k8s.io/utils/net"
) )
func TestEnsureStaticIP(t *testing.T) { func TestEnsureStaticIP(t *testing.T) {
@ -620,10 +620,10 @@ func TestFirewallNeedsUpdate(t *testing.T) {
ipAddr := status.Ingress[0].IP ipAddr := status.Ingress[0].IP
lbName := gce.GetLoadBalancerName(context.TODO(), "", svc) 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) 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) require.NoError(t, err)
fw, err := gce.GetFirewall(MakeFirewallName(lbName)) fw, err := gce.GetFirewall(MakeFirewallName(lbName))
@ -633,7 +633,7 @@ func TestFirewallNeedsUpdate(t *testing.T) {
lbName string lbName string
ipAddr string ipAddr string
ports []v1.ServicePort ports []v1.ServicePort
ipnet netsets.IPNet ipnet utilnet.IPNetSet
fwIPProtocol string fwIPProtocol string
getHook func(context.Context, *meta.Key, *cloud.MockFirewalls) (bool, *ga.Firewall, error) getHook func(context.Context, *meta.Key, *cloud.MockFirewalls) (bool, *ga.Firewall, error)
sourceRange string sourceRange string
@ -864,7 +864,7 @@ func TestCreateAndUpdateFirewallSucceedsOnXPN(t *testing.T) {
hostNames := nodeNames(nodes) hostNames := nodeNames(nodes)
hosts, err := gce.getInstancesByNames(hostNames) hosts, err := gce.getInstancesByNames(hostNames)
require.NoError(t, err) 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) require.NoError(t, err)
gce.createFirewall( gce.createFirewall(
svc, svc,

View File

@ -27,8 +27,8 @@ import (
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
servicehelpers "k8s.io/cloud-provider/service/helpers"
"k8s.io/klog" "k8s.io/klog"
v1_service "k8s.io/kubernetes/pkg/api/v1/service"
) )
const ( 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 // Ensure health check exists before creating the backend service. The health check is shared
// if externalTrafficPolicy=Cluster. // if externalTrafficPolicy=Cluster.
sharedHealthCheck := !v1_service.RequestsOnlyLocalTraffic(svc) sharedHealthCheck := !servicehelpers.RequestsOnlyLocalTraffic(svc)
hcName := makeHealthCheckName(loadBalancerName, clusterID, sharedHealthCheck) hcName := makeHealthCheckName(loadBalancerName, clusterID, sharedHealthCheck)
hcPath, hcPort := GetNodesHealthCheckPath(), GetNodesHealthCheckPort() hcPath, hcPort := GetNodesHealthCheckPath(), GetNodesHealthCheckPort()
if !sharedHealthCheck { if !sharedHealthCheck {
// Service requires a special health check, retrieve the OnlyLocal port & path // 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) hc, err := g.ensureInternalHealthCheck(hcName, nm, sharedHealthCheck, hcPath, hcPort)
if err != nil { if err != nil {
@ -224,7 +224,7 @@ func (g *Cloud) ensureInternalLoadBalancerDeleted(clusterName, clusterID string,
_, protocol := getPortsAndProtocol(svc.Spec.Ports) _, protocol := getPortsAndProtocol(svc.Spec.Ports)
scheme := cloud.SchemeInternal scheme := cloud.SchemeInternal
sharedBackend := shareBackendService(svc) sharedBackend := shareBackendService(svc)
sharedHealthCheck := !v1_service.RequestsOnlyLocalTraffic(svc) sharedHealthCheck := !servicehelpers.RequestsOnlyLocalTraffic(svc)
g.sharedResourceLock.Lock() g.sharedResourceLock.Lock()
defer g.sharedResourceLock.Unlock() defer g.sharedResourceLock.Unlock()
@ -367,7 +367,7 @@ func (g *Cloud) ensureInternalFirewalls(loadBalancerName, ipAddress, clusterID s
// First firewall is for ingress traffic // First firewall is for ingress traffic
fwDesc := makeFirewallDescription(nm.String(), ipAddress) fwDesc := makeFirewallDescription(nm.String(), ipAddress)
ports, protocol := getPortsAndProtocol(svc.Spec.Ports) ports, protocol := getPortsAndProtocol(svc.Spec.Ports)
sourceRanges, err := v1_service.GetLoadBalancerSourceRanges(svc) sourceRanges, err := servicehelpers.GetLoadBalancerSourceRanges(svc)
if err != nil { if err != nil {
return err return err
} }
@ -581,7 +581,7 @@ func (g *Cloud) ensureInternalBackendServiceGroups(name string, igLinks []string
} }
func shareBackendService(svc *v1.Service) bool { 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) { func backendsFromGroupLinks(igLinks []string) (backends []*compute.Backend) {

View File

@ -31,7 +31,7 @@ import (
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/tools/record" "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) { 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} nm := types.NamespacedName{Name: svc.Name, Namespace: svc.Namespace}
lbName := gce.GetLoadBalancerName(context.TODO(), "", svc) lbName := gce.GetLoadBalancerName(context.TODO(), "", svc)
sharedHealthCheck := !v1_service.RequestsOnlyLocalTraffic(svc) sharedHealthCheck := !servicehelper.RequestsOnlyLocalTraffic(svc)
hcName := makeHealthCheckName(lbName, vals.ClusterID, sharedHealthCheck) hcName := makeHealthCheckName(lbName, vals.ClusterID, sharedHealthCheck)
hcPath, hcPort := GetNodesHealthCheckPath(), GetNodesHealthCheckPort() hcPath, hcPort := GetNodesHealthCheckPath(), GetNodesHealthCheckPort()
existingHC := newInternalLBHealthCheck(hcName, nm, sharedHealthCheck, hcPath, hcPort) existingHC := newInternalLBHealthCheck(hcName, nm, sharedHealthCheck, hcPath, hcPort)
@ -224,7 +224,7 @@ func TestEnsureInternalLoadBalancerClearPreviousResources(t *testing.T) {
} }
gce.CreateFirewall(existingFirewall) gce.CreateFirewall(existingFirewall)
sharedHealthCheck := !v1_service.RequestsOnlyLocalTraffic(svc) sharedHealthCheck := !servicehelper.RequestsOnlyLocalTraffic(svc)
hcName := makeHealthCheckName(lbName, vals.ClusterID, sharedHealthCheck) hcName := makeHealthCheckName(lbName, vals.ClusterID, sharedHealthCheck)
hcPath, hcPort := GetNodesHealthCheckPath(), GetNodesHealthCheckPort() hcPath, hcPort := GetNodesHealthCheckPath(), GetNodesHealthCheckPort()
nm := types.NamespacedName{Name: svc.Name, Namespace: svc.Namespace} nm := types.NamespacedName{Name: svc.Name, Namespace: svc.Namespace}
@ -278,7 +278,7 @@ func TestEnsureInternalLoadBalancerHealthCheckConfigurable(t *testing.T) {
svc := fakeLoadbalancerService(string(LBTypeInternal)) svc := fakeLoadbalancerService(string(LBTypeInternal))
lbName := gce.GetLoadBalancerName(context.TODO(), "", svc) lbName := gce.GetLoadBalancerName(context.TODO(), "", svc)
sharedHealthCheck := !v1_service.RequestsOnlyLocalTraffic(svc) sharedHealthCheck := !servicehelper.RequestsOnlyLocalTraffic(svc)
hcName := makeHealthCheckName(lbName, vals.ClusterID, sharedHealthCheck) hcName := makeHealthCheckName(lbName, vals.ClusterID, sharedHealthCheck)
hcPath, hcPort := GetNodesHealthCheckPath(), GetNodesHealthCheckPort() hcPath, hcPort := GetNodesHealthCheckPath(), GetNodesHealthCheckPort()
nm := types.NamespacedName{Name: svc.Name, Namespace: svc.Namespace} nm := types.NamespacedName{Name: svc.Name, Namespace: svc.Namespace}

View File

@ -35,7 +35,7 @@ import (
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/tools/record" "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" 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 // Check that HealthCheck is created
sharedHealthCheck := !v1_service.RequestsOnlyLocalTraffic(apiService) sharedHealthCheck := !servicehelpers.RequestsOnlyLocalTraffic(apiService)
hcName := makeHealthCheckName(lbName, vals.ClusterID, sharedHealthCheck) hcName := makeHealthCheckName(lbName, vals.ClusterID, sharedHealthCheck)
healthcheck, err := gce.GetHealthCheck(hcName) healthcheck, err := gce.GetHealthCheck(hcName)
require.NoError(t, err) 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) { func assertInternalLbResourcesDeleted(t *testing.T, gce *Cloud, apiService *v1.Service, vals TestClusterValues, firewallsDeleted bool) {
lbName := gce.GetLoadBalancerName(context.TODO(), "", apiService) lbName := gce.GetLoadBalancerName(context.TODO(), "", apiService)
sharedHealthCheck := !v1_service.RequestsOnlyLocalTraffic(apiService) sharedHealthCheck := !servicehelpers.RequestsOnlyLocalTraffic(apiService)
hcName := makeHealthCheckName(lbName, vals.ClusterID, sharedHealthCheck) hcName := makeHealthCheckName(lbName, vals.ClusterID, sharedHealthCheck)
// ensureExternalLoadBalancer and ensureInternalLoadBalancer both create // ensureExternalLoadBalancer and ensureInternalLoadBalancer both create

View File

@ -20,7 +20,6 @@ go_library(
], ],
importpath = "k8s.io/kubernetes/pkg/cloudprovider/providers/openstack", importpath = "k8s.io/kubernetes/pkg/cloudprovider/providers/openstack",
deps = [ deps = [
"//pkg/api/v1/service:go_default_library",
"//pkg/kubelet/apis:go_default_library", "//pkg/kubelet/apis:go_default_library",
"//pkg/util/mount:go_default_library", "//pkg/util/mount:go_default_library",
"//pkg/volume: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/client-go/util/cert:go_default_library",
"//staging/src/k8s.io/cloud-provider: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/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:go_default_library",
"//vendor/github.com/gophercloud/gophercloud/openstack:go_default_library", "//vendor/github.com/gophercloud/gophercloud/openstack:go_default_library",
"//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions:go_default_library", "//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions:go_default_library",

View File

@ -44,7 +44,7 @@ import (
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
cloudprovider "k8s.io/cloud-provider" 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, // 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 { if err != nil {
return nil, fmt.Errorf("failed to get source ranges for loadbalancer service %s/%s: %v", apiService.Namespace, apiService.Name, err) 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") 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 // get service source ranges
sourceRanges, err := service.GetLoadBalancerSourceRanges(apiService) sourceRanges, err := servicehelpers.GetLoadBalancerSourceRanges(apiService)
if err != nil { if err != nil {
return fmt.Errorf("failed to get source ranges for loadbalancer service %s/%s: %v", apiService.Namespace, apiService.Name, err) return fmt.Errorf("failed to get source ranges for loadbalancer service %s/%s: %v", apiService.Namespace, apiService.Name, err)
} }

View File

@ -307,7 +307,6 @@
"k8s.io/kubernetes/pkg/scheduler/api", "k8s.io/kubernetes/pkg/scheduler/api",
"k8s.io/kubernetes/pkg/scheduler/util", "k8s.io/kubernetes/pkg/scheduler/util",
"k8s.io/kubernetes/pkg/security/apparmor", "k8s.io/kubernetes/pkg/security/apparmor",
"k8s.io/kubernetes/pkg/util/net/sets",
"k8s.io/kubernetes/pkg/util/parsers", "k8s.io/kubernetes/pkg/util/parsers",
"k8s.io/kubernetes/pkg/fieldpath", "k8s.io/kubernetes/pkg/fieldpath",
"k8s.io/kubernetes/pkg/scheduler/volumebinder", "k8s.io/kubernetes/pkg/scheduler/volumebinder",
@ -342,7 +341,8 @@
"k8s.io/utils/path", "k8s.io/utils/path",
"k8s.io/utils/pointer", "k8s.io/utils/pointer",
"k8s.io/utils/exec", "k8s.io/utils/exec",
"k8s.io/utils/strings" "k8s.io/utils/strings",
"k8s.io/utils/net"
] ]
}, },
{ {

View File

@ -59,6 +59,9 @@ type cfsslSigner struct {
sigAlgo x509.SignatureAlgorithm sigAlgo x509.SignatureAlgorithm
client clientset.Interface client clientset.Interface
certificateDuration time.Duration 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) { 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), sigAlgo: signer.DefaultSigAlgo(priv),
client: client, client: client,
certificateDuration: certificateDuration, certificateDuration: certificateDuration,
nowFn: time.Now,
}, nil }, nil
} }
@ -115,11 +119,21 @@ func (s *cfsslSigner) sign(csr *capi.CertificateSigningRequest) (*capi.Certifica
for _, usage := range csr.Spec.Usages { for _, usage := range csr.Spec.Usages {
usages = append(usages, string(usage)) 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{ policy := &config.Signing{
Default: &config.SigningProfile{ Default: &config.SigningProfile{
Usage: usages, Usage: usages,
Expiry: s.certificateDuration, Expiry: certExpiryDuration,
ExpiryString: s.certificateDuration.String(), ExpiryString: certExpiryDuration.String(),
}, },
} }
cfs, err := local.NewSigner(s.priv, s.ca, s.sigAlgo, policy) cfs, err := local.NewSigner(s.priv, s.ca, s.sigAlgo, policy)

View File

@ -20,6 +20,7 @@ import (
"crypto/x509" "crypto/x509"
"io/ioutil" "io/ioutil"
"reflect" "reflect"
"strings"
"testing" "testing"
"time" "time"
@ -28,10 +29,16 @@ import (
) )
func TestSigner(t *testing.T) { 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) s, err := newCFSSLSigner("./testdata/ca.crt", "./testdata/ca.key", nil, 1*time.Hour)
if err != nil { if err != nil {
t.Fatalf("failed to create signer: %v", err) t.Fatalf("failed to create signer: %v", err)
} }
s.nowFn = testNowFn
csrb, err := ioutil.ReadFile("./testdata/kubelet.csr") csrb, err := ioutil.ReadFile("./testdata/kubelet.csr")
if err != nil { if err != nil {
@ -81,4 +88,108 @@ func TestSigner(t *testing.T) {
if !reflect.DeepEqual(crt.ExtKeyUsage, []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth}) { if !reflect.DeepEqual(crt.ExtKeyUsage, []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth}) {
t.Errorf("bad extended key usage") 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)
}
} }

View File

@ -19,8 +19,6 @@ package garbagecollector
import ( import (
"fmt" "fmt"
"k8s.io/klog"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -28,6 +26,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/util/retry" "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 // 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 { if err != nil {
return nil, err 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 // TODO: Using Patch when strategicmerge supports deleting an entry from a

View File

@ -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) return 0, time.Time{}, "", fmt.Errorf("failed to get %s utilization: %v", metricSpec.Resource.Name, err)
} }
metricNameProposal := fmt.Sprintf("%s resource", metricSpec.Resource.Name) metricNameProposal := fmt.Sprintf("%s resource", metricSpec.Resource.Name)
status = &autoscalingv2.MetricStatus{ *status = autoscalingv2.MetricStatus{
Type: autoscalingv2.ResourceMetricSourceType, Type: autoscalingv2.ResourceMetricSourceType,
Resource: &autoscalingv2.ResourceMetricStatus{ Resource: &autoscalingv2.ResourceMetricStatus{
Name: metricSpec.Resource.Name, Name: metricSpec.Resource.Name,

View File

@ -173,7 +173,7 @@ func (g *dockerConfigUrlKeyProvider) Provide() credentialprovider.DockerConfig {
return 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. // Note that this method can block indefinitely.
func runWithBackoff(f func() ([]byte, error)) []byte { func runWithBackoff(f func() ([]byte, error)) []byte {
var backoff = 100 * time.Millisecond var backoff = 100 * time.Millisecond

View File

@ -163,6 +163,7 @@ const (
// owner: @derekwaynecarr // owner: @derekwaynecarr
// beta: v1.10 // beta: v1.10
// GA: v1.14
// //
// Enable pods to consume pre-allocated huge pages of varying page sizes // Enable pods to consume pre-allocated huge pages of varying page sizes
HugePages utilfeature.Feature = "HugePages" HugePages utilfeature.Feature = "HugePages"
@ -424,7 +425,7 @@ var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureS
RotateKubeletClientCertificate: {Default: true, PreRelease: utilfeature.Beta}, RotateKubeletClientCertificate: {Default: true, PreRelease: utilfeature.Beta},
PersistentLocalVolumes: {Default: true, PreRelease: utilfeature.Beta}, PersistentLocalVolumes: {Default: true, PreRelease: utilfeature.Beta},
LocalStorageCapacityIsolation: {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}, Sysctls: {Default: true, PreRelease: utilfeature.Beta},
DebugContainers: {Default: false, PreRelease: utilfeature.Alpha}, DebugContainers: {Default: false, PreRelease: utilfeature.Alpha},
PodShareProcessNamespace: {Default: true, PreRelease: utilfeature.Beta}, 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.APIResponseCompression: {Default: false, PreRelease: utilfeature.Alpha},
genericfeatures.APIListChunking: {Default: true, PreRelease: utilfeature.Beta}, genericfeatures.APIListChunking: {Default: true, PreRelease: utilfeature.Beta},
genericfeatures.DryRun: {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 // inherited features from apiextensions-apiserver, relisted here to get a conflict if it is changed
// unintentionally on either side: // unintentionally on either side:

View File

@ -132,7 +132,6 @@
"k8s.io/kubernetes/pkg/util/labels", "k8s.io/kubernetes/pkg/util/labels",
"k8s.io/kubernetes/pkg/util/metrics", "k8s.io/kubernetes/pkg/util/metrics",
"k8s.io/kubernetes/pkg/util/mount", "k8s.io/kubernetes/pkg/util/mount",
"k8s.io/kubernetes/pkg/util/net/sets",
"k8s.io/kubernetes/pkg/util/node", "k8s.io/kubernetes/pkg/util/node",
"k8s.io/kubernetes/pkg/util/parsers", "k8s.io/kubernetes/pkg/util/parsers",
"k8s.io/kubernetes/pkg/util/slice", "k8s.io/kubernetes/pkg/util/slice",
@ -144,7 +143,8 @@
"k8s.io/utils/nsenter", "k8s.io/utils/nsenter",
"k8s.io/utils/io", "k8s.io/utils/io",
"k8s.io/utils/path", "k8s.io/utils/path",
"k8s.io/utils/pointer" "k8s.io/utils/pointer",
"k8s.io/utils/net"
], ],
"ForbiddenPrefixes": [] "ForbiddenPrefixes": []
}] }]

View File

@ -20,6 +20,7 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
"net/http"
"strings" "strings"
"time" "time"
@ -65,16 +66,18 @@ type ApplyOptions struct {
DeleteFlags *delete.DeleteFlags DeleteFlags *delete.DeleteFlags
DeleteOptions *delete.DeleteOptions DeleteOptions *delete.DeleteOptions
Selector string ServerSideApply bool
DryRun bool ForceConflicts bool
ServerDryRun bool Selector string
Prune bool DryRun bool
PruneResources []pruneResource ServerDryRun bool
cmdBaseName string Prune bool
All bool PruneResources []pruneResource
Overwrite bool cmdBaseName string
OpenAPIPatch bool All bool
PruneWhitelist []string Overwrite bool
OpenAPIPatch bool
PruneWhitelist []string
Validator validation.Schema Validator validation.Schema
Builder *resource.Builder 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().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.") 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.AddIncludeUninitializedFlag(cmd)
cmdutil.AddServerSideApplyFlags(cmd)
// apply subcommands // apply subcommands
cmd.AddCommand(NewCmdApplyViewLastApplied(f, ioStreams)) 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 { 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) 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 { if o.DryRun && o.ServerDryRun {
return fmt.Errorf("--dry-run and --server-dry-run can't be used together") 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 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 { func (o *ApplyOptions) Run() error {
var openapiSchema openapi.Resources var openapiSchema openapi.Resources
if o.OpenAPIPatch { if o.OpenAPIPatch {
@ -356,6 +380,50 @@ func (o *ApplyOptions) Run() error {
klog.V(4).Infof("error recording current command: %v", err) 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 // Get the modified configuration of the object. Embed the result
// as an annotation in the modified configuration, so that it will appear // as an annotation in the modified configuration, so that it will appear
// in the patch sent to the server. // 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 { if p.ServerDryRun {
options.DryRun = []string{metav1.DryRunAll} options.DryRun = []string{metav1.DryRunAll}
} }

View File

@ -76,7 +76,7 @@ type AttachOptions struct {
AttachFunc func(*AttachOptions, *corev1.Container, bool, remotecommand.TerminalSizeQueue) func() error AttachFunc func(*AttachOptions, *corev1.Container, bool, remotecommand.TerminalSizeQueue) func() error
Resources []string Resources []string
Builder func() *resource.Builder Builder func() *resource.Builder
AttachablePodFn polymorphichelpers.AttachableLogsForObjectFunc AttachablePodFn polymorphichelpers.AttachablePodForObjectFunc
restClientGetter genericclioptions.RESTClientGetter restClientGetter genericclioptions.RESTClientGetter
Attach RemoteAttach Attach RemoteAttach

View File

@ -51,7 +51,7 @@ func (f *fakeRemoteAttach) Attach(method string, url *url.URL, config *restclien
return f.err 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 func(getter genericclioptions.RESTClientGetter, obj runtime.Object, timeout time.Duration) (*corev1.Pod, error) {
return pod, nil return pod, nil
} }

View File

@ -59,7 +59,15 @@ var (
reconcileLong = templates.LongDesc(` reconcileLong = templates.LongDesc(`
Reconciles rules for RBAC Role, RoleBinding, ClusterRole, and ClusterRole binding objects. 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(` reconcileExample = templates.Examples(`
# Reconcile rbac resources from a file # Reconcile rbac resources from a file

View 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:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured: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/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:go_default_library",
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource: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/jonboulle/clockwork:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library", "//vendor/github.com/spf13/cobra:go_default_library",
"//vendor/k8s.io/klog:go_default_library", "//vendor/k8s.io/klog:go_default_library",

View File

@ -30,8 +30,11 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/genericclioptions/resource" "k8s.io/cli-runtime/pkg/genericclioptions/resource"
"k8s.io/client-go/discovery"
"k8s.io/client-go/dynamic"
"k8s.io/klog" "k8s.io/klog"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/apply" "k8s.io/kubernetes/pkg/kubectl/cmd/apply"
@ -67,21 +70,38 @@ const maxRetries = 4
type DiffOptions struct { type DiffOptions struct {
FilenameOptions resource.FilenameOptions 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 { if len(args) != 0 {
return cmdutil.UsageErrorf(cmd, "Unexpected args: %v", args) return cmdutil.UsageErrorf(cmd, "Unexpected args: %v", args)
} }
return nil return nil
} }
func NewCmdDiff(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command { func NewDiffOptions(ioStreams genericclioptions.IOStreams) *DiffOptions {
var options DiffOptions return &DiffOptions{
diff := DiffProgram{ Diff: &DiffProgram{
Exec: exec.New(), Exec: exec.New(),
IOStreams: streams, IOStreams: ioStreams,
},
} }
}
func NewCmdDiff(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
options := NewDiffOptions(streams)
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "diff -f FILENAME", Use: "diff -f FILENAME",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
@ -89,13 +109,15 @@ func NewCmdDiff(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.C
Long: diffLong, Long: diffLong,
Example: diffExample, Example: diffExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(checkDiffArgs(cmd, args)) cmdutil.CheckErr(options.Complete(f, cmd))
cmdutil.CheckErr(RunDiff(f, &diff, &options)) cmdutil.CheckErr(validateArgs(cmd, args))
cmdutil.CheckErr(options.Run())
}, },
} }
usage := "contains the configuration to diff" usage := "contains the configuration to diff"
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage) cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
cmdutil.AddServerSideApplyFlags(cmd)
cmd.MarkFlagRequired("filename") cmd.MarkFlagRequired("filename")
return cmd return cmd
@ -229,11 +251,13 @@ type Object interface {
// InfoObject is an implementation of the Object interface. It gets all // InfoObject is an implementation of the Object interface. It gets all
// the information from the Info object. // the information from the Info object.
type InfoObject struct { type InfoObject struct {
LocalObj runtime.Object LocalObj runtime.Object
Info *resource.Info Info *resource.Info
Encoder runtime.Encoder Encoder runtime.Encoder
OpenAPI openapi.Resources OpenAPI openapi.Resources
Force bool Force bool
ServerSideApply bool
ForceConflicts bool
} }
var _ Object = &InfoObject{} 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 // Returns the "merged" object, as it would look like if applied or
// created. // created.
func (obj InfoObject) Merged() (runtime.Object, error) { 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. // 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 { if obj.Live() == nil {
// Dry-run create if the object doesn't exist. // Dry-run create if the object doesn't exist.
@ -350,30 +392,50 @@ func isConflict(err error) bool {
return err != nil && errors.IsConflict(err) 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 // 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 // diff, and find each Info object for each files, and runs against the
// differ. // differ.
func RunDiff(f cmdutil.Factory, diff *DiffProgram, options *DiffOptions) error { func (o *DiffOptions) Run() 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,
}
differ, err := NewDiffer("LIVE", "MERGED") differ, err := NewDiffer("LIVE", "MERGED")
if err != nil { if err != nil {
return err return err
@ -382,15 +444,10 @@ func RunDiff(f cmdutil.Factory, diff *DiffProgram, options *DiffOptions) error {
printer := Printer{} printer := Printer{}
cmdNamespace, enforceNamespace, err := f.ToRawKubeConfigLoader().Namespace() r := o.Builder.
if err != nil {
return err
}
r := f.NewBuilder().
Unstructured(). Unstructured().
NamespaceParam(cmdNamespace).DefaultNamespace(). NamespaceParam(o.CmdNamespace).DefaultNamespace().
FilenameParam(enforceNamespace, &options.FilenameOptions). FilenameParam(o.EnforceNamespace, &o.FilenameOptions).
Flatten(). Flatten().
Do() Do()
if err := r.Err(); err != nil { if err := r.Err(); err != nil {
@ -402,7 +459,7 @@ func RunDiff(f cmdutil.Factory, diff *DiffProgram, options *DiffOptions) error {
return err return err
} }
if err := dryRunVerifier.HasSupport(info.Mapping.GroupVersionKind); err != nil { if err := o.DryRunVerifier.HasSupport(info.Mapping.GroupVersionKind); err != nil {
return err return err
} }
@ -424,11 +481,13 @@ func RunDiff(f cmdutil.Factory, diff *DiffProgram, options *DiffOptions) error {
) )
} }
obj := InfoObject{ obj := InfoObject{
LocalObj: local, LocalObj: local,
Info: info, Info: info,
Encoder: scheme.DefaultJSONEncoder(), Encoder: scheme.DefaultJSONEncoder(),
OpenAPI: schema, OpenAPI: o.OpenAPISchema,
Force: force, Force: force,
ServerSideApply: o.ServerSideApply,
ForceConflicts: o.ForceConflicts,
} }
err = differ.Diff(obj, printer) err = differ.Diff(obj, printer)
@ -442,5 +501,5 @@ func RunDiff(f cmdutil.Factory, diff *DiffProgram, options *DiffOptions) error {
return err return err
} }
return differ.Run(diff) return differ.Run(o.Diff)
} }

View File

@ -29,8 +29,6 @@ import (
"github.com/evanphx/json-patch" "github.com/evanphx/json-patch"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/pflag" "github.com/spf13/pflag"
"k8s.io/klog"
kerrors "k8s.io/apimachinery/pkg/api/errors" kerrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -44,6 +42,7 @@ import (
"k8s.io/client-go/rest" "k8s.io/client-go/rest"
"k8s.io/client-go/scale" "k8s.io/client-go/scale"
"k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/clientcmd"
"k8s.io/klog"
utilexec "k8s.io/utils/exec" 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.") 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) { 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().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") 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 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 { func GetDryRunFlag(cmd *cobra.Command) bool {
return GetFlagBool(cmd, "dry-run") return GetFlagBool(cmd, "dry-run")
} }

View File

@ -90,6 +90,8 @@ func NewWaitFlags(restClientGetter genericclioptions.RESTClientGetter, streams g
PrintFlags: genericclioptions.NewPrintFlags("condition met"), PrintFlags: genericclioptions.NewPrintFlags("condition met"),
ResourceBuilderFlags: genericclioptions.NewResourceBuilderFlags(). ResourceBuilderFlags: genericclioptions.NewResourceBuilderFlags().
WithLabelSelector(""). WithLabelSelector("").
WithFieldSelector("").
WithAll(false).
WithAllNamespaces(false). WithAllNamespaces(false).
WithAll(false). WithAll(false).
WithLatest(), WithLatest(),
@ -105,11 +107,12 @@ func NewCmdWait(restClientGetter genericclioptions.RESTClientGetter, streams gen
flags := NewWaitFlags(restClientGetter, streams) flags := NewWaitFlags(restClientGetter, streams)
cmd := &cobra.Command{ 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, 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) { Run: func(cmd *cobra.Command, args []string) {
o, err := flags.ToOptions(args) o, err := flags.ToOptions(args)
cmdutil.CheckErr(err) cmdutil.CheckErr(err)

View File

@ -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", name: "ignores watch error",
infos: []*resource.Info{ infos: []*resource.Info{

View File

@ -34,11 +34,11 @@ type LogsForObjectFunc func(restClientGetter genericclioptions.RESTClientGetter,
// LogsForObjectFn gives a way to easily override the function for unit testing if needed. // LogsForObjectFn gives a way to easily override the function for unit testing if needed.
var LogsForObjectFn LogsForObjectFunc = logsForObject 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 // AttachablePodForObjectFunc 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) 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. // 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 // 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) type HistoryViewerFunc func(restClientGetter genericclioptions.RESTClientGetter, mapping *meta.RESTMapping) (kubectl.HistoryViewer, error)

View File

@ -131,7 +131,6 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_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/apimachinery/pkg/util/wait:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature: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:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/typed/core/v1: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", "//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/client-go/util/flowcontrol:go_default_library",
"//staging/src/k8s.io/cloud-provider: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/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", "//third_party/forked/golang/expansion:go_default_library",
"//vendor/github.com/golang/groupcache/lru:go_default_library", "//vendor/github.com/golang/groupcache/lru:go_default_library",
"//vendor/github.com/google/cadvisor/events:go_default_library", "//vendor/github.com/google/cadvisor/events:go_default_library",

View File

@ -135,7 +135,7 @@ func (*Empty) ProtoMessage() {}
func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{2} } func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{2} }
// ListAndWatch returns a stream of List of Devices // 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 // returns the new list
type ListAndWatchResponse struct { type ListAndWatchResponse struct {
Devices []*Device `protobuf:"bytes,1,rep,name=devices" json:"devices,omitempty"` Devices []*Device `protobuf:"bytes,1,rep,name=devices" json:"devices,omitempty"`
@ -482,7 +482,7 @@ type DevicePluginClient interface {
// Manager // Manager
GetDevicePluginOptions(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*DevicePluginOptions, error) GetDevicePluginOptions(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*DevicePluginOptions, error)
// ListAndWatch returns a stream of List of Devices // 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 // returns the new list
ListAndWatch(ctx context.Context, in *Empty, opts ...grpc.CallOption) (DevicePlugin_ListAndWatchClient, error) ListAndWatch(ctx context.Context, in *Empty, opts ...grpc.CallOption) (DevicePlugin_ListAndWatchClient, error)
// Allocate is called during container creation so that the Device // Allocate is called during container creation so that the Device
@ -569,7 +569,7 @@ type DevicePluginServer interface {
// Manager // Manager
GetDevicePluginOptions(context.Context, *Empty) (*DevicePluginOptions, error) GetDevicePluginOptions(context.Context, *Empty) (*DevicePluginOptions, error)
// ListAndWatch returns a stream of List of Devices // 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 // returns the new list
ListAndWatch(*Empty, DevicePlugin_ListAndWatchServer) error ListAndWatch(*Empty, DevicePlugin_ListAndWatchServer) error
// Allocate is called during container creation so that the Device // Allocate is called during container creation so that the Device

View File

@ -51,7 +51,7 @@ service DevicePlugin {
rpc GetDevicePluginOptions(Empty) returns (DevicePluginOptions) {} rpc GetDevicePluginOptions(Empty) returns (DevicePluginOptions) {}
// ListAndWatch returns a stream of List of Devices // 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 // returns the new list
rpc ListAndWatch(Empty) returns (stream ListAndWatchResponse) {} rpc ListAndWatch(Empty) returns (stream ListAndWatchResponse) {}
@ -67,7 +67,7 @@ service DevicePlugin {
} }
// ListAndWatch returns a stream of List of Devices // 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 // returns the new list
message ListAndWatchResponse { message ListAndWatchResponse {
repeated Device devices = 1; repeated Device devices = 1;

View File

@ -21,11 +21,9 @@ go_library(
importpath = "k8s.io/kubernetes/pkg/kubelet/cadvisor", importpath = "k8s.io/kubernetes/pkg/kubelet/cadvisor",
deps = [ deps = [
"//pkg/apis/core/v1/helper:go_default_library", "//pkg/apis/core/v1/helper:go_default_library",
"//pkg/features:go_default_library",
"//pkg/kubelet/types:go_default_library", "//pkg/kubelet/types:go_default_library",
"//staging/src/k8s.io/api/core/v1: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/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/events:go_default_library",
"//vendor/github.com/google/cadvisor/info/v1:go_default_library", "//vendor/github.com/google/cadvisor/info/v1:go_default_library",
"//vendor/github.com/google/cadvisor/info/v2:go_default_library", "//vendor/github.com/google/cadvisor/info/v2:go_default_library",
@ -51,11 +49,8 @@ go_test(
embed = [":go_default_library"], embed = [":go_default_library"],
deps = select({ deps = select({
"@io_bazel_rules_go//go/platform:linux": [ "@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/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/resource: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/container/crio:go_default_library",
"//vendor/github.com/google/cadvisor/info/v1:go_default_library", "//vendor/github.com/google/cadvisor/info/v1:go_default_library",
"//vendor/github.com/stretchr/testify/assert:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library",

View File

@ -23,9 +23,7 @@ import (
cadvisorapi2 "github.com/google/cadvisor/info/v2" cadvisorapi2 "github.com/google/cadvisor/info/v2"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
utilfeature "k8s.io/apiserver/pkg/util/feature"
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper" v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
"k8s.io/kubernetes/pkg/features"
kubetypes "k8s.io/kubernetes/pkg/kubelet/types" 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 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 {
for _, hugepagesInfo := range info.HugePages { pageSizeBytes := int64(hugepagesInfo.PageSize * 1024)
pageSizeBytes := int64(hugepagesInfo.PageSize * 1024) hugePagesBytes := pageSizeBytes * int64(hugepagesInfo.NumPages)
hugePagesBytes := pageSizeBytes * int64(hugepagesInfo.NumPages) pageSizeQuantity := resource.NewQuantity(pageSizeBytes, resource.BinarySI)
pageSizeQuantity := resource.NewQuantity(pageSizeBytes, resource.BinarySI) c[v1helper.HugePageResourceName(*pageSizeQuantity)] = *resource.NewQuantity(hugePagesBytes, resource.BinarySI)
c[v1helper.HugePageResourceName(*pageSizeQuantity)] = *resource.NewQuantity(hugePagesBytes, resource.BinarySI)
}
} }
return c return c

View File

@ -27,9 +27,6 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource" "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) { func TestCapacityFromMachineInfoWithHugePagesEnable(t *testing.T) {
@ -49,36 +46,12 @@ func TestCapacityFromMachineInfoWithHugePagesEnable(t *testing.T) {
v1.ResourceMemory: *resource.NewQuantity(int64(2048), resource.BinarySI), v1.ResourceMemory: *resource.NewQuantity(int64(2048), resource.BinarySI),
"hugepages-5Ki": *resource.NewQuantity(int64(51200), resource.BinarySI), "hugepages-5Ki": *resource.NewQuantity(int64(51200), resource.BinarySI),
} }
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HugePages, true)()
actual := CapacityFromMachineInfo(machineInfo) actual := CapacityFromMachineInfo(machineInfo)
if !reflect.DeepEqual(actual, expected) { if !reflect.DeepEqual(actual, expected) {
t.Errorf("when set hugepages true, got resource list %v, want %v", 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) { 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") assert.EqualValues(t, CrioSocket, crio.CrioSocket, "CrioSocket in this package must equal the one in github.com/google/cadvisor/container/crio/client.go")
} }

View File

@ -327,9 +327,7 @@ func getSupportedSubsystems() map[subsystem]bool {
&cgroupfs.CpuGroup{}: true, &cgroupfs.CpuGroup{}: true,
} }
// not all hosts support hugetlb cgroup, and in the absent of hugetlb, we will fail silently by reporting no capacity. // 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) { if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.SupportPodPidsLimit) {
supportedSubsystems[&cgroupfs.PidsGroup{}] = true 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 huge pages are enabled, we set them in libcontainer
if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.HugePages) { // for each page size enumerated, set that value
// for each page size enumerated, set that value pageSizes := sets.NewString()
pageSizes := sets.NewString() for pageSize, limit := range resourceConfig.HugePageLimit {
for pageSize, limit := range resourceConfig.HugePageLimit { sizeString := units.CustomSize("%g%s", float64(pageSize), 1024.0, hugePageSizeList)
sizeString := units.CustomSize("%g%s", float64(pageSize), 1024.0, hugePageSizeList) resources.HugetlbLimit = append(resources.HugetlbLimit, &libcontainerconfigs.HugepageLimit{
resources.HugetlbLimit = append(resources.HugetlbLimit, &libcontainerconfigs.HugepageLimit{ Pagesize: sizeString,
Pagesize: sizeString, Limit: uint64(limit),
Limit: uint64(limit), })
}) pageSizes.Insert(sizeString)
pageSizes.Insert(sizeString) }
} // for each page size omitted, limit to 0
// for each page size omitted, limit to 0 for _, pageSize := range cgroupfs.HugePageSizes {
for _, pageSize := range cgroupfs.HugePageSizes { if pageSizes.Has(pageSize) {
if pageSizes.Has(pageSize) { continue
continue
}
resources.HugetlbLimit = append(resources.HugetlbLimit, &libcontainerconfigs.HugepageLimit{
Pagesize: pageSize,
Limit: uint64(0),
})
} }
resources.HugetlbLimit = append(resources.HugetlbLimit, &libcontainerconfigs.HugepageLimit{
Pagesize: pageSize,
Limit: uint64(0),
})
} }
return resources return resources
} }

View File

@ -612,7 +612,7 @@ func (m *ManagerImpl) devicesToAllocate(podUID, contName, resource string, requi
devicesInUse := m.allocatedDevices[resource] devicesInUse := m.allocatedDevices[resource]
// Gets a list of available devices. // Gets a list of available devices.
available := m.healthyDevices[resource].Difference(devicesInUse) 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()) return nil, fmt.Errorf("requested number of devices unavailable for %s. Requested: %d, Available: %d", resource, needed, available.Len())
} }
allocated := available.UnsortedList()[:needed] allocated := available.UnsortedList()[:needed]

View File

@ -26,9 +26,7 @@ import (
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/klog" "k8s.io/klog"
kubefeatures "k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/kubelet/events" "k8s.io/kubernetes/pkg/kubelet/events"
kubetypes "k8s.io/kubernetes/pkg/kubelet/types" kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
) )
@ -159,9 +157,7 @@ func getCgroupConfig(rl v1.ResourceList) *ResourceConfig {
val := MilliCPUToShares(q.MilliValue()) val := MilliCPUToShares(q.MilliValue())
rc.CpuShares = &val rc.CpuShares = &val
} }
if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.HugePages) { rc.HugePageLimit = HugePageLimits(rl)
rc.HugePageLimit = HugePageLimits(rl)
}
return &rc return &rc
} }

View File

@ -108,9 +108,7 @@ func (m *qosContainerManagerImpl) Start(getNodeAllocatable func() v1.ResourceLis
} }
// for each enumerated huge page size, the qos tiers are unbounded // 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 // check if it exists
if !cm.Exists(containerName) { 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) // 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 {
if err := m.setHugePagesConfig(qosConfigs); err != nil { return err
return err
}
} }
if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.QOSReserved) { if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.QOSReserved) {

View File

@ -19,12 +19,12 @@ go_library(
"//pkg/proxy/iptables:go_default_library", "//pkg/proxy/iptables:go_default_library",
"//pkg/util/conntrack:go_default_library", "//pkg/util/conntrack:go_default_library",
"//pkg/util/iptables: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/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/errors: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", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/k8s.io/klog:go_default_library", "//vendor/k8s.io/klog:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library", "//vendor/k8s.io/utils/exec:go_default_library",
"//vendor/k8s.io/utils/net:go_default_library",
], ],
) )

View File

@ -31,8 +31,8 @@ import (
iptablesproxy "k8s.io/kubernetes/pkg/proxy/iptables" iptablesproxy "k8s.io/kubernetes/pkg/proxy/iptables"
"k8s.io/kubernetes/pkg/util/conntrack" "k8s.io/kubernetes/pkg/util/conntrack"
utiliptables "k8s.io/kubernetes/pkg/util/iptables" utiliptables "k8s.io/kubernetes/pkg/util/iptables"
utilnet "k8s.io/kubernetes/pkg/util/net"
"k8s.io/utils/exec" "k8s.io/utils/exec"
utilnet "k8s.io/utils/net"
) )
// HostPortManager is an interface for adding and removing hostport for a given pod sandbox. // HostPortManager is an interface for adding and removing hostport for a given pod sandbox.

View File

@ -43,7 +43,6 @@ import (
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/dynamic"
clientset "k8s.io/client-go/kubernetes" clientset "k8s.io/client-go/kubernetes"
v1core "k8s.io/client-go/kubernetes/typed/core/v1" v1core "k8s.io/client-go/kubernetes/typed/core/v1"
corelisters "k8s.io/client-go/listers/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/util/oom"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/csi" "k8s.io/kubernetes/pkg/volume/csi"
nodeapiclientset "k8s.io/node-api/pkg/client/clientset/versioned"
utilexec "k8s.io/utils/exec" utilexec "k8s.io/utils/exec"
"k8s.io/utils/integer" "k8s.io/utils/integer"
) )
@ -249,7 +249,7 @@ type Dependencies struct {
OnHeartbeatFailure func() OnHeartbeatFailure func()
KubeClient clientset.Interface KubeClient clientset.Interface
CSIClient csiclientset.Interface CSIClient csiclientset.Interface
DynamicKubeClient dynamic.Interface NodeAPIClient nodeapiclientset.Interface
Mounter mount.Interface Mounter mount.Interface
OOMAdjuster *oom.OOMAdjuster OOMAdjuster *oom.OOMAdjuster
OSInterface kubecontainer.OSInterface OSInterface kubecontainer.OSInterface
@ -658,8 +658,8 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
} }
klet.runtimeService = runtimeService klet.runtimeService = runtimeService
if utilfeature.DefaultFeatureGate.Enabled(features.RuntimeClass) && kubeDeps.DynamicKubeClient != nil { if utilfeature.DefaultFeatureGate.Enabled(features.RuntimeClass) && kubeDeps.NodeAPIClient != nil {
klet.runtimeClassManager = runtimeclass.NewManager(kubeDeps.DynamicKubeClient) klet.runtimeClassManager = runtimeclass.NewManager(kubeDeps.NodeAPIClient)
} }
runtime, err := kuberuntime.NewKubeGenericRuntimeManager( runtime, err := kuberuntime.NewKubeGenericRuntimeManager(
@ -1303,6 +1303,7 @@ func (kl *Kubelet) initializeModules() error {
collectors.NewVolumeStatsCollector(kl), collectors.NewVolumeStatsCollector(kl),
collectors.NewLogMetricsCollector(kl.StatsProvider.ListPodStats), collectors.NewLogMetricsCollector(kl.StatsProvider.ListPodStats),
) )
metrics.SetNodeName(kl.nodeName)
// Setup filesystem directories. // Setup filesystem directories.
if err := kl.setupDataDirs(); err != nil { if err := kl.setupDataDirs(); err != nil {
@ -1426,7 +1427,7 @@ func (kl *Kubelet) Run(updates <-chan kubetypes.PodUpdate) {
// Start syncing RuntimeClasses if enabled. // Start syncing RuntimeClasses if enabled.
if kl.runtimeClassManager != nil { if kl.runtimeClassManager != nil {
go kl.runtimeClassManager.Run(wait.NeverStop) kl.runtimeClassManager.Start(wait.NeverStop)
} }
// Start the pod lifecycle event generator. // Start the pod lifecycle event generator.

Some files were not shown because too many files have changed in this diff Show More