diff --git a/.gitignore b/.gitignore index f1c181ec9..ceb622478 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,6 @@ # Output of the go coverage tool, specifically when used with LiteIDE *.out + +# Vendor director +vendor \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..181384bf7 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,13 @@ +# Contributing guidelines + +## Sign the CLA + +Kubernetes projects require that you sign a Contributor License Agreement (CLA) before we can accept your pull requests. Please see https://git.k8s.io/community/CLA.md for more info + +### Contributing A Patch + +1. Submit an issue describing your proposed change to the repo in question. +1. The [repo owners](OWNERS) will respond to your issue promptly. +1. If your proposed change is accepted, and you haven't already done so, sign a Contributor License Agreement (see details above). +1. Fork the desired repo, develop and test your code changes. +1. Submit a pull request. diff --git a/Gopkg.lock b/Gopkg.lock new file mode 100644 index 000000000..c1fb6b070 --- /dev/null +++ b/Gopkg.lock @@ -0,0 +1,815 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + branch = "default" + name = "bitbucket.org/ww/goautoneg" + packages = ["."] + revision = "75cd24fc2f2c2a2088577d12123ddee5f54e0675" + +[[projects]] + name = "github.com/NYTimes/gziphandler" + packages = ["."] + revision = "2600fb119af974220d3916a5916d6e31176aac1b" + version = "v1.0.1" + +[[projects]] + name = "github.com/PuerkitoBio/purell" + packages = ["."] + revision = "0bcb03f4b4d0a9428594752bd2a3b9aa0a9d4bd4" + version = "v1.1.0" + +[[projects]] + branch = "master" + name = "github.com/PuerkitoBio/urlesc" + packages = ["."] + revision = "de5bf2ad457846296e2031421a34e2568e304e35" + +[[projects]] + branch = "master" + name = "github.com/beorn7/perks" + packages = ["quantile"] + revision = "3a771d992973f24aa725d07868b467d1ddfceafb" + +[[projects]] + name = "github.com/coreos/etcd" + packages = [ + "auth/authpb", + "client", + "clientv3", + "etcdserver/api/v3rpc/rpctypes", + "etcdserver/etcdserverpb", + "mvcc/mvccpb", + "pkg/pathutil", + "pkg/srv", + "pkg/tlsutil", + "pkg/transport", + "pkg/types", + "version" + ] + revision = "33245c6b5b49130ca99280408fadfab01aac0e48" + version = "v3.3.8" + +[[projects]] + name = "github.com/coreos/go-semver" + packages = ["semver"] + revision = "8ab6407b697782a06568d4b7f1db25550ec2e4c6" + version = "v0.2.0" + +[[projects]] + name = "github.com/coreos/go-systemd" + packages = ["daemon"] + revision = "39ca1b05acc7ad1220e09f133283b8859a8b71ab" + version = "v17" + +[[projects]] + name = "github.com/davecgh/go-spew" + packages = ["spew"] + revision = "346938d642f2ec3594ed81d874461961cd0faa76" + version = "v1.1.0" + +[[projects]] + name = "github.com/elazarl/go-bindata-assetfs" + packages = ["."] + revision = "30f82fa23fd844bd5bb1e5f216db87fd77b5eb43" + version = "v1.0.0" + +[[projects]] + name = "github.com/emicklei/go-restful" + packages = [ + ".", + "log" + ] + revision = "3eb9738c1697594ea6e71a7156a9bb32ed216cf0" + version = "v2.8.0" + +[[projects]] + name = "github.com/emicklei/go-restful-swagger12" + packages = ["."] + revision = "dcef7f55730566d41eae5db10e7d6981829720f6" + version = "1.0.1" + +[[projects]] + name = "github.com/evanphx/json-patch" + packages = ["."] + revision = "afac545df32f2287a079e2dfb7ba2745a643747e" + version = "v3.0.0" + +[[projects]] + name = "github.com/ghodss/yaml" + packages = ["."] + revision = "0ca9ea5df5451ffdf184b4428c902747c2c11cd7" + version = "v1.0.0" + +[[projects]] + branch = "master" + name = "github.com/go-openapi/jsonpointer" + packages = ["."] + revision = "3a0015ad55fa9873f41605d3e8f28cd279c32ab2" + +[[projects]] + branch = "master" + name = "github.com/go-openapi/jsonreference" + packages = ["."] + revision = "3fb327e6747da3043567ee86abd02bb6376b6be2" + +[[projects]] + branch = "master" + name = "github.com/go-openapi/spec" + packages = ["."] + revision = "bce47c9386f9ecd6b86f450478a80103c3fe1402" + +[[projects]] + branch = "master" + name = "github.com/go-openapi/swag" + packages = ["."] + revision = "2b0bd4f193d011c203529df626a65d63cb8a79e8" + +[[projects]] + name = "github.com/gogo/protobuf" + packages = [ + "gogoproto", + "proto", + "protoc-gen-gogo/descriptor", + "sortkeys" + ] + revision = "1adfc126b41513cc696b209667c8656ea7aac67c" + version = "v1.0.0" + +[[projects]] + branch = "master" + name = "github.com/golang/glog" + packages = ["."] + revision = "23def4e6c14b4da8ac2ed8007337bc5eb5007998" + +[[projects]] + branch = "master" + name = "github.com/golang/groupcache" + packages = ["lru"] + revision = "24b0969c4cb722950103eed87108c8d291a8df00" + +[[projects]] + name = "github.com/golang/protobuf" + packages = [ + "proto", + "ptypes", + "ptypes/any", + "ptypes/duration", + "ptypes/timestamp" + ] + revision = "b4deda0973fb4c70b50d226b1af49f3da59f5265" + version = "v1.1.0" + +[[projects]] + branch = "master" + name = "github.com/google/btree" + packages = ["."] + revision = "e89373fe6b4a7413d7acd6da1725b83ef713e6e4" + +[[projects]] + branch = "master" + name = "github.com/google/gofuzz" + packages = ["."] + revision = "24818f796faf91cd76ec7bddd72458fbced7a6c1" + +[[projects]] + name = "github.com/googleapis/gnostic" + packages = [ + "OpenAPIv2", + "compiler", + "extensions" + ] + revision = "7c663266750e7d82587642f65e60bc4083f1f84e" + version = "v0.2.0" + +[[projects]] + branch = "master" + name = "github.com/gregjones/httpcache" + packages = [ + ".", + "diskcache" + ] + revision = "9cad4c3443a7200dd6400aef47183728de563a38" + +[[projects]] + branch = "master" + name = "github.com/hashicorp/golang-lru" + packages = [ + ".", + "simplelru" + ] + revision = "0fb14efe8c47ae851c0034ed7a448854d3d34cf3" + +[[projects]] + branch = "master" + name = "github.com/howeyc/gopass" + packages = ["."] + revision = "bf9dde6d0d2c004a008c27aaee91170c786f6db8" + +[[projects]] + name = "github.com/imdario/mergo" + packages = ["."] + revision = "9316a62528ac99aaecb4e47eadd6dc8aa6533d58" + version = "v0.3.5" + +[[projects]] + name = "github.com/json-iterator/go" + packages = ["."] + revision = "ab8a2e0c74be9d3be70b3184d9acc634935ded82" + version = "1.1.4" + +[[projects]] + name = "github.com/juju/ratelimit" + packages = ["."] + revision = "59fac5042749a5afb9af70e813da1dd5474f0167" + version = "1.0.1" + +[[projects]] + name = "github.com/kubernetes-incubator/apiserver-builder" + packages = [ + "pkg/builders", + "pkg/controller" + ] + revision = "14201e804a58a140011a0044b15331f477535f91" + version = "v1.9-alpha.4" + +[[projects]] + branch = "master" + name = "github.com/mailru/easyjson" + packages = [ + "buffer", + "jlexer", + "jwriter" + ] + revision = "3fdea8d05856a0c8df22ed4bc71b3219245e4485" + +[[projects]] + name = "github.com/matttproud/golang_protobuf_extensions" + packages = ["pbutil"] + revision = "c12348ce28de40eed0136aa2b644d0ee0650e56c" + version = "v1.0.1" + +[[projects]] + name = "github.com/modern-go/concurrent" + packages = ["."] + revision = "bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94" + version = "1.0.3" + +[[projects]] + name = "github.com/modern-go/reflect2" + packages = ["."] + revision = "4b7aa43c6742a2c18fdef89dd197aaae7dac7ccd" + version = "1.0.1" + +[[projects]] + branch = "master" + name = "github.com/mxk/go-flowrate" + packages = ["flowrate"] + revision = "cca7078d478f8520f85629ad7c68962d31ed7682" + +[[projects]] + name = "github.com/pborman/uuid" + packages = ["."] + revision = "e790cca94e6cc75c7064b1332e63811d4aae1a53" + version = "v1.1" + +[[projects]] + branch = "master" + name = "github.com/petar/GoLLRB" + packages = ["llrb"] + revision = "53be0d36a84c2a886ca057d34b6aa4468df9ccb4" + +[[projects]] + name = "github.com/peterbourgon/diskv" + packages = ["."] + revision = "5f041e8faa004a95c88a202771f4cc3e991971e6" + version = "v2.0.1" + +[[projects]] + name = "github.com/prometheus/client_golang" + packages = ["prometheus"] + revision = "c5b7fccd204277076155f10851dad72b76a49317" + version = "v0.8.0" + +[[projects]] + branch = "master" + name = "github.com/prometheus/client_model" + packages = ["go"] + revision = "99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c" + +[[projects]] + branch = "master" + name = "github.com/prometheus/common" + packages = [ + "expfmt", + "internal/bitbucket.org/ww/goautoneg", + "model" + ] + revision = "7600349dcfe1abd18d72d3a1770870d9800a7801" + +[[projects]] + branch = "master" + name = "github.com/prometheus/procfs" + packages = [ + ".", + "internal/util", + "nfs", + "xfs" + ] + revision = "ae68e2d4c00fed4943b5f6698d504a5fe083da8a" + +[[projects]] + name = "github.com/spf13/pflag" + packages = ["."] + revision = "583c0c0531f06d5278b7d917446061adc344b5cd" + version = "v1.0.1" + +[[projects]] + name = "github.com/ugorji/go" + packages = ["codec"] + revision = "b4c50a2b199d93b13dc15e78929cfb23bfdf21ab" + version = "v1.1.1" + +[[projects]] + branch = "master" + name = "golang.org/x/crypto" + packages = ["ssh/terminal"] + revision = "a49355c7e3f8fe157a85be2f77e6e269a0f89602" + +[[projects]] + branch = "master" + name = "golang.org/x/net" + packages = [ + "context", + "html", + "html/atom", + "http/httpguts", + "http2", + "http2/hpack", + "idna", + "internal/timeseries", + "trace", + "websocket" + ] + revision = "039a4258aec0ad3c79b905677cceeab13b296a77" + +[[projects]] + branch = "master" + name = "golang.org/x/sys" + packages = [ + "unix", + "windows" + ] + revision = "1b2967e3c290b7c545b3db0deeda16e9be4f98a2" + +[[projects]] + name = "golang.org/x/text" + packages = [ + "collate", + "collate/build", + "internal/colltab", + "internal/gen", + "internal/tag", + "internal/triegen", + "internal/ucd", + "language", + "secure/bidirule", + "transform", + "unicode/bidi", + "unicode/cldr", + "unicode/norm", + "unicode/rangetable", + "width" + ] + revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0" + version = "v0.3.0" + +[[projects]] + branch = "master" + name = "golang.org/x/tools" + packages = [ + "go/ast/astutil", + "imports", + "internal/fastwalk" + ] + revision = "2087f8c10712366cfc2f4fcb1bf99eeef61ab21e" + +[[projects]] + branch = "master" + name = "google.golang.org/genproto" + packages = ["googleapis/rpc/status"] + revision = "e92b116572682a5b432ddd840aeaba2a559eeff1" + +[[projects]] + name = "google.golang.org/grpc" + packages = [ + ".", + "balancer", + "balancer/base", + "balancer/roundrobin", + "codes", + "connectivity", + "credentials", + "encoding", + "encoding/proto", + "grpclog", + "health/grpc_health_v1", + "internal", + "internal/backoff", + "internal/channelz", + "internal/grpcrand", + "keepalive", + "metadata", + "naming", + "peer", + "resolver", + "resolver/dns", + "resolver/passthrough", + "stats", + "status", + "tap", + "transport" + ] + revision = "168a6198bcb0ef175f7dacec0b8691fc141dc9b8" + version = "v1.13.0" + +[[projects]] + name = "gopkg.in/inf.v0" + packages = ["."] + revision = "d2d2541c53f18d2a059457998ce2876cc8e67cbf" + version = "v0.9.1" + +[[projects]] + name = "gopkg.in/yaml.v2" + packages = ["."] + revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183" + version = "v2.2.1" + +[[projects]] + branch = "release-1.9" + name = "k8s.io/api" + packages = [ + "admission/v1beta1", + "admissionregistration/v1alpha1", + "admissionregistration/v1beta1", + "apps/v1", + "apps/v1beta1", + "apps/v1beta2", + "authentication/v1", + "authentication/v1beta1", + "authorization/v1", + "authorization/v1beta1", + "autoscaling/v1", + "autoscaling/v2beta1", + "batch/v1", + "batch/v1beta1", + "batch/v2alpha1", + "certificates/v1beta1", + "core/v1", + "events/v1beta1", + "extensions/v1beta1", + "networking/v1", + "policy/v1beta1", + "rbac/v1", + "rbac/v1alpha1", + "rbac/v1beta1", + "scheduling/v1alpha1", + "settings/v1alpha1", + "storage/v1", + "storage/v1alpha1", + "storage/v1beta1" + ] + revision = "9273ee02527c608cecc74969b3e489f5dba686da" + +[[projects]] + branch = "release-1.9" + name = "k8s.io/apimachinery" + packages = [ + "pkg/api/equality", + "pkg/api/errors", + "pkg/api/meta", + "pkg/api/resource", + "pkg/api/validation", + "pkg/api/validation/path", + "pkg/apimachinery", + "pkg/apimachinery/announced", + "pkg/apimachinery/registered", + "pkg/apis/meta/internalversion", + "pkg/apis/meta/v1", + "pkg/apis/meta/v1/unstructured", + "pkg/apis/meta/v1/validation", + "pkg/apis/meta/v1alpha1", + "pkg/conversion", + "pkg/conversion/queryparams", + "pkg/fields", + "pkg/labels", + "pkg/runtime", + "pkg/runtime/schema", + "pkg/runtime/serializer", + "pkg/runtime/serializer/json", + "pkg/runtime/serializer/protobuf", + "pkg/runtime/serializer/recognizer", + "pkg/runtime/serializer/streaming", + "pkg/runtime/serializer/versioning", + "pkg/selection", + "pkg/types", + "pkg/util/cache", + "pkg/util/clock", + "pkg/util/diff", + "pkg/util/errors", + "pkg/util/framer", + "pkg/util/httpstream", + "pkg/util/intstr", + "pkg/util/json", + "pkg/util/mergepatch", + "pkg/util/net", + "pkg/util/proxy", + "pkg/util/rand", + "pkg/util/runtime", + "pkg/util/sets", + "pkg/util/strategicpatch", + "pkg/util/uuid", + "pkg/util/validation", + "pkg/util/validation/field", + "pkg/util/wait", + "pkg/util/waitgroup", + "pkg/util/yaml", + "pkg/version", + "pkg/watch", + "third_party/forked/golang/json", + "third_party/forked/golang/netutil", + "third_party/forked/golang/reflect" + ] + revision = "fb40df2b502912cbe3a93aa61c2b2487f39cb42f" + +[[projects]] + branch = "release-1.9" + name = "k8s.io/apiserver" + packages = [ + "pkg/admission", + "pkg/admission/configuration", + "pkg/admission/initializer", + "pkg/admission/metrics", + "pkg/admission/plugin/initialization", + "pkg/admission/plugin/namespace/lifecycle", + "pkg/admission/plugin/webhook/config", + "pkg/admission/plugin/webhook/config/apis/webhookadmission", + "pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1", + "pkg/admission/plugin/webhook/errors", + "pkg/admission/plugin/webhook/mutating", + "pkg/admission/plugin/webhook/namespace", + "pkg/admission/plugin/webhook/request", + "pkg/admission/plugin/webhook/rules", + "pkg/admission/plugin/webhook/validating", + "pkg/admission/plugin/webhook/versioned", + "pkg/apis/apiserver", + "pkg/apis/apiserver/install", + "pkg/apis/apiserver/v1alpha1", + "pkg/apis/audit", + "pkg/apis/audit/v1alpha1", + "pkg/apis/audit/v1beta1", + "pkg/apis/audit/validation", + "pkg/audit", + "pkg/audit/policy", + "pkg/authentication/authenticator", + "pkg/authentication/authenticatorfactory", + "pkg/authentication/group", + "pkg/authentication/request/anonymous", + "pkg/authentication/request/bearertoken", + "pkg/authentication/request/headerrequest", + "pkg/authentication/request/union", + "pkg/authentication/request/websocket", + "pkg/authentication/request/x509", + "pkg/authentication/serviceaccount", + "pkg/authentication/token/tokenfile", + "pkg/authentication/user", + "pkg/authorization/authorizer", + "pkg/authorization/authorizerfactory", + "pkg/authorization/union", + "pkg/endpoints", + "pkg/endpoints/discovery", + "pkg/endpoints/filters", + "pkg/endpoints/handlers", + "pkg/endpoints/handlers/negotiation", + "pkg/endpoints/handlers/responsewriters", + "pkg/endpoints/metrics", + "pkg/endpoints/openapi", + "pkg/endpoints/request", + "pkg/features", + "pkg/registry/generic", + "pkg/registry/generic/registry", + "pkg/registry/rest", + "pkg/server", + "pkg/server/filters", + "pkg/server/healthz", + "pkg/server/httplog", + "pkg/server/mux", + "pkg/server/routes", + "pkg/server/routes/data/swagger", + "pkg/storage", + "pkg/storage/errors", + "pkg/storage/etcd", + "pkg/storage/etcd/metrics", + "pkg/storage/etcd/util", + "pkg/storage/etcd3", + "pkg/storage/names", + "pkg/storage/storagebackend", + "pkg/storage/storagebackend/factory", + "pkg/storage/value", + "pkg/util/feature", + "pkg/util/flushwriter", + "pkg/util/logs", + "pkg/util/trace", + "pkg/util/webhook", + "pkg/util/wsstream", + "plugin/pkg/authenticator/token/webhook", + "plugin/pkg/authorizer/webhook" + ] + revision = "0c27ac7eec3e47fa7637c9dba4ecf70494bbc28a" + +[[projects]] + branch = "release-6.0" + name = "k8s.io/client-go" + packages = [ + "discovery", + "informers", + "informers/admissionregistration", + "informers/admissionregistration/v1alpha1", + "informers/admissionregistration/v1beta1", + "informers/apps", + "informers/apps/v1", + "informers/apps/v1beta1", + "informers/apps/v1beta2", + "informers/autoscaling", + "informers/autoscaling/v1", + "informers/autoscaling/v2beta1", + "informers/batch", + "informers/batch/v1", + "informers/batch/v1beta1", + "informers/batch/v2alpha1", + "informers/certificates", + "informers/certificates/v1beta1", + "informers/core", + "informers/core/v1", + "informers/events", + "informers/events/v1beta1", + "informers/extensions", + "informers/extensions/v1beta1", + "informers/internalinterfaces", + "informers/networking", + "informers/networking/v1", + "informers/policy", + "informers/policy/v1beta1", + "informers/rbac", + "informers/rbac/v1", + "informers/rbac/v1alpha1", + "informers/rbac/v1beta1", + "informers/scheduling", + "informers/scheduling/v1alpha1", + "informers/settings", + "informers/settings/v1alpha1", + "informers/storage", + "informers/storage/v1", + "informers/storage/v1alpha1", + "informers/storage/v1beta1", + "kubernetes", + "kubernetes/scheme", + "kubernetes/typed/admissionregistration/v1alpha1", + "kubernetes/typed/admissionregistration/v1beta1", + "kubernetes/typed/apps/v1", + "kubernetes/typed/apps/v1beta1", + "kubernetes/typed/apps/v1beta2", + "kubernetes/typed/authentication/v1", + "kubernetes/typed/authentication/v1beta1", + "kubernetes/typed/authorization/v1", + "kubernetes/typed/authorization/v1beta1", + "kubernetes/typed/autoscaling/v1", + "kubernetes/typed/autoscaling/v2beta1", + "kubernetes/typed/batch/v1", + "kubernetes/typed/batch/v1beta1", + "kubernetes/typed/batch/v2alpha1", + "kubernetes/typed/certificates/v1beta1", + "kubernetes/typed/core/v1", + "kubernetes/typed/events/v1beta1", + "kubernetes/typed/extensions/v1beta1", + "kubernetes/typed/networking/v1", + "kubernetes/typed/policy/v1beta1", + "kubernetes/typed/rbac/v1", + "kubernetes/typed/rbac/v1alpha1", + "kubernetes/typed/rbac/v1beta1", + "kubernetes/typed/scheduling/v1alpha1", + "kubernetes/typed/settings/v1alpha1", + "kubernetes/typed/storage/v1", + "kubernetes/typed/storage/v1alpha1", + "kubernetes/typed/storage/v1beta1", + "listers/admissionregistration/v1alpha1", + "listers/admissionregistration/v1beta1", + "listers/apps/v1", + "listers/apps/v1beta1", + "listers/apps/v1beta2", + "listers/autoscaling/v1", + "listers/autoscaling/v2beta1", + "listers/batch/v1", + "listers/batch/v1beta1", + "listers/batch/v2alpha1", + "listers/certificates/v1beta1", + "listers/core/v1", + "listers/events/v1beta1", + "listers/extensions/v1beta1", + "listers/networking/v1", + "listers/policy/v1beta1", + "listers/rbac/v1", + "listers/rbac/v1alpha1", + "listers/rbac/v1beta1", + "listers/scheduling/v1alpha1", + "listers/settings/v1alpha1", + "listers/storage/v1", + "listers/storage/v1alpha1", + "listers/storage/v1beta1", + "pkg/version", + "rest", + "rest/watch", + "tools/auth", + "tools/cache", + "tools/clientcmd", + "tools/clientcmd/api", + "tools/clientcmd/api/latest", + "tools/clientcmd/api/v1", + "tools/leaderelection", + "tools/leaderelection/resourcelock", + "tools/metrics", + "tools/pager", + "tools/record", + "tools/reference", + "transport", + "util/buffer", + "util/cert", + "util/flowcontrol", + "util/homedir", + "util/integer", + "util/workqueue" + ] + revision = "e2680bfa771859c129bc5c8413fdb565af2b3dcd" + +[[projects]] + branch = "release-1.9" + name = "k8s.io/code-generator" + packages = ["cmd/deepcopy-gen"] + revision = "0ab89e584187c20cc7c1a3f30db69f3b4ab64196" + +[[projects]] + branch = "master" + name = "k8s.io/gengo" + packages = [ + "args", + "examples/deepcopy-gen/generators", + "examples/set-gen/sets", + "generator", + "namer", + "parser", + "types" + ] + revision = "fdcf9f9480fdd5bf2b3c3df9bf4ecd22b25b87e2" + +[[projects]] + branch = "master" + name = "k8s.io/kube-openapi" + packages = [ + "pkg/builder", + "pkg/common", + "pkg/handler", + "pkg/util", + "pkg/util/proto" + ] + revision = "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" + +[[projects]] + branch = "master" + name = "sigs.k8s.io/cluster-api" + packages = [ + "pkg/apis/cluster", + "pkg/apis/cluster/common", + "pkg/apis/cluster/v1alpha1", + "pkg/client/clientset_generated/clientset", + "pkg/client/clientset_generated/clientset/scheme", + "pkg/client/clientset_generated/clientset/typed/cluster/v1alpha1", + "pkg/client/informers_generated/externalversions", + "pkg/client/informers_generated/externalversions/cluster", + "pkg/client/informers_generated/externalversions/cluster/v1alpha1", + "pkg/client/informers_generated/externalversions/internalinterfaces", + "pkg/client/listers_generated/cluster/v1alpha1", + "pkg/controller/cluster", + "pkg/controller/config", + "pkg/controller/machine", + "pkg/controller/noderefutil", + "pkg/controller/sharedinformers", + "pkg/util" + ] + revision = "b770dd7b06fb75834ead5169db85ea79b6215563" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "cdc10cd8ccd232cdec9f8e7e969f8734a337dbcdadab8d271e460e88879a08da" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml new file mode 100644 index 000000000..08acff8c9 --- /dev/null +++ b/Gopkg.toml @@ -0,0 +1,37 @@ +# Gopkg.toml example +# +# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md +# for detailed Gopkg.toml documentation. +# +# required = ["github.com/user/thing/cmd/thing"] +# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +# +# [[constraint]] +# name = "github.com/user/project" +# version = "1.0.0" +# +# [[constraint]] +# name = "github.com/user/project2" +# branch = "dev" +# source = "github.com/myfork/project2" +# +# [[override]] +# name = "github.com/x/y" +# version = "2.4.0" +# +# [prune] +# non-go = false +# go-tests = true +# unused-packages = true + +required = [ + "k8s.io/code-generator/cmd/deepcopy-gen", +] + +[[constraint]] + name = "sigs.k8s.io/cluster-api" + branch = "master" + +[[constraint]] + name = "k8s.io/code-generator" + branch = "release-1.9" diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..5d253e2d0 --- /dev/null +++ b/Makefile @@ -0,0 +1,56 @@ +# 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. + +.PHONY: gendeepcopy + +all: generate build images + +depend: + dep version || go get -u github.com/golang/dep/cmd/dep + dep ensure + +depend-update: work + dep ensure -update + +generate: gendeepcopy + +gendeepcopy: + go build -o $$GOPATH/bin/deepcopy-gen sigs.k8s.io/cluster-api-provider-aws/vendor/k8s.io/code-generator/cmd/deepcopy-gen + deepcopy-gen \ + -i ./cloud/aws/providerconfig,./cloud/aws/providerconfig/v1alpha1 \ + -O zz_generated.deepcopy \ + -h boilerplate.go.txt + +build: depend + CGO_ENABLED=0 go install -a -ldflags '-extldflags "-static"' sigs.k8s.io/cluster-api-provider-aws/cmd/cluster-controller + CGO_ENABLED=0 go install -a -ldflags '-extldflags "-static"' sigs.k8s.io/cluster-api-provider-aws/cmd/machine-controller + +images: depend + $(MAKE) -C cmd/cluster-controller image + $(MAKE) -C cmd/machine-controller image + +push: depend + $(MAKE) -C cmd/cluster-controller push + $(MAKE) -C cmd/machine-controller push + +check: depend fmt vet + +test: + go test -race -cover ./cmd/... ./cloud/... + +fmt: + hack/verify-gofmt.sh + +vet: + go vet ./... \ No newline at end of file diff --git a/OWNERS b/OWNERS new file mode 100644 index 000000000..05016d87d --- /dev/null +++ b/OWNERS @@ -0,0 +1,12 @@ +# See the OWNERS docs: https://git.k8s.io/community/contributors/guide/owners.md + +approvers: + - sig-cluster-lifecycle-leads + - sig-aws-leads + - cluster-api-admins + - cluster-api-maintainers + - cluster-api-aws-maintainers + +reviewers: + - cluster-api-maintainers + - cluster-api-aws-maintainers diff --git a/OWNERS_ALIASES b/OWNERS_ALIASES new file mode 100644 index 000000000..101a3e6ef --- /dev/null +++ b/OWNERS_ALIASES @@ -0,0 +1,33 @@ +# See the OWNERS docs: https://git.k8s.io/community/docs/devel/owners.md + +aliases: + sig-cluster-lifecycle-leads: + - lukemarsden + - luxas + - roberthbailey + - timothysc + cluster-api-admins: + - justinsb + - krousey + - luxas + - roberthbailey + - kris-nova + cluster-api-maintainers: + - jessicaochen + - k4leung4 + - karan + - kris-nova + - krousey + - medinatiger + - mkjelland + - roberthbailey + - rsdcastro + - spew + sig-aws-leads: + - justinsb + - kris-nova + - countspongebob + cluster-api-aws-maintainers: + - detiber + - chuckha + - davidewatson diff --git a/README.md b/README.md index 42378fad5..9e5d85f1c 100644 --- a/README.md +++ b/README.md @@ -1 +1,16 @@ -# cluster-api-provider-aws \ No newline at end of file +# Kubernetes cluster-api-provider-aws Project + +This repository hosts an implementation of a provider for AWS for the [cluster-api project](https://sigs.k8s.io/cluster-api). + +## Community, discussion, contribution, and support + +Learn how to engage with the Kubernetes community on the [community page](http://kubernetes.io/community/). + +You can reach the maintainers of this project at: + +- [Slack](http://slack.k8s.io/) +- [Mailing List](https://groups.google.com/forum/#!forum/kubernetes-dev) + +### Code of conduct + +Participation in the Kubernetes community is governed by the [Kubernetes Code of Conduct](code-of-conduct.md). diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 000000000..031fc65ba --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,9 @@ +# Release Process + +The Kubernetes cluster-api-provider-aws is released on an as-needed basis. The process is as follows: + +1. An issue is proposing a new release with a changelog since the last release +1. All [OWNERS](OWNERS) must LGTM this release +1. An OWNER runs `git tag -s $VERSION` and inserts the changelog and pushes the tag with `git push $VERSION` +1. The release issue is closed +1. An announcement email is sent to `kubernetes-dev@googlegroups.com` with the subject `[ANNOUNCE] cluster-api-provider-aws $VERSION is released` diff --git a/SECURITY_CONTACTS b/SECURITY_CONTACTS new file mode 100644 index 000000000..686757663 --- /dev/null +++ b/SECURITY_CONTACTS @@ -0,0 +1,16 @@ +# Defined below are the security contacts for this repo. +# +# They are the contact point for the Product Security Team to reach out +# to for triaging and handling of incoming issues. +# +# The below names agree to abide by the +# [Embargo Policy](https://github.com/kubernetes/sig-release/blob/master/security-release-process-documentation/security-release-process.md#embargo-policy) +# and will be removed and replaced if they violate that agreement. +# +# DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE +# INSTRUCTIONS AT https://kubernetes.io/security/ + +lukemarsden +luxas +roberthbailey +timothysc diff --git a/boilerplate.go.txt b/boilerplate.go.txt new file mode 100644 index 000000000..ef168d266 --- /dev/null +++ b/boilerplate.go.txt @@ -0,0 +1,12 @@ +// 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. \ No newline at end of file diff --git a/cloud/aws/actuators/cluster/actuator.go b/cloud/aws/actuators/cluster/actuator.go new file mode 100644 index 000000000..0bcac1ff5 --- /dev/null +++ b/cloud/aws/actuators/cluster/actuator.go @@ -0,0 +1,51 @@ +// 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 cluster + +import ( + "fmt" + + "github.com/golang/glog" + clusterv1 "sigs.k8s.io/cluster-api/pkg/apis/cluster/v1alpha1" + client "sigs.k8s.io/cluster-api/pkg/client/clientset_generated/clientset/typed/cluster/v1alpha1" +) + +// Actuator is responsible for performing cluster reconciliation +type Actuator struct { + clusterClient client.ClusterInterface +} + +// ActuatorParams holds parameter information for Actuator +type ActuatorParams struct { + ClusterClient client.ClusterInterface +} + +// NewActuator creates a new Actuator +func NewActuator(params ActuatorParams) (*Actuator, error) { + return &Actuator{ + clusterClient: params.ClusterClient, + }, nil +} + +// Reconcile reconciles a cluster and is invoked by the Cluster Controller +func (a *Actuator) Reconcile(cluster *clusterv1.Cluster) error { + glog.Infof("Reconciling cluster %v.", cluster.Name) + return fmt.Errorf("TODO: Not yet implemented") +} + +// Delete deletes a cluster and is invoked by the Cluster Controller +func (a *Actuator) Delete(cluster *clusterv1.Cluster) error { + glog.Infof("Deleting cluster %v.", cluster.Name) + return fmt.Errorf("TODO: Not yet implemented") +} diff --git a/cloud/aws/actuators/machine/actuator.go b/cloud/aws/actuators/machine/actuator.go new file mode 100644 index 000000000..42d13d0f4 --- /dev/null +++ b/cloud/aws/actuators/machine/actuator.go @@ -0,0 +1,63 @@ +// 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 machine + +import ( + "fmt" + + "github.com/golang/glog" + clusterv1 "sigs.k8s.io/cluster-api/pkg/apis/cluster/v1alpha1" + client "sigs.k8s.io/cluster-api/pkg/client/clientset_generated/clientset/typed/cluster/v1alpha1" +) + +// Actuator is responsible for performing machine reconciliation +type Actuator struct { + clusterClient client.ClusterInterface +} + +// ActuatorParams holds parameter information for Actuator +type ActuatorParams struct { + ClusterClient client.ClusterInterface +} + +// NewActuator creates a new Actuator +func NewActuator(params ActuatorParams) (*Actuator, error) { + return &Actuator{ + clusterClient: params.ClusterClient, + }, nil +} + +// Create creates a machine and is invoked by the Machine Controller +func (a *Actuator) Create(cluster *clusterv1.Cluster, machine *clusterv1.Machine) error { + glog.Infof("Creating machine %v for cluster %v.", machine.Name, cluster.Name) + return fmt.Errorf("TODO: Not yet implemented") +} + +// Delete deletes a machine and is invoked by the Machine Controller +func (a *Actuator) Delete(cluster *clusterv1.Cluster, machine *clusterv1.Machine) error { + glog.Infof("Deleting machine %v for cluster %v.", machine.Name, cluster.Name) + return fmt.Errorf("TODO: Not yet implemented") +} + +// Update updates a machine and is invoked by the Machine Controller +func (a *Actuator) Update(cluster *clusterv1.Cluster, machine *clusterv1.Machine) error { + glog.Infof("Updating machine %v for cluster %v.", machine.Name, cluster.Name) + return fmt.Errorf("TODO: Not yet implemented") +} + +// Exists test for the existance of a machine and is invoked by the Machine Controller +func (a *Actuator) Exists(cluster *clusterv1.Cluster, machine *clusterv1.Machine) (bool, error) { + glog.Info("Checking if machine %v for cluster %v exists.", machine.Name, cluster.Name) + return false, fmt.Errorf("TODO: Not yet implemented") +} diff --git a/cloud/aws/controllers/cluster/controller.go b/cloud/aws/controllers/cluster/controller.go new file mode 100644 index 000000000..ee2b2cee8 --- /dev/null +++ b/cloud/aws/controllers/cluster/controller.go @@ -0,0 +1,157 @@ +/* +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 cluster + +import ( + "os" + + "github.com/golang/glog" + "github.com/kubernetes-incubator/apiserver-builder/pkg/controller" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/uuid" + "k8s.io/client-go/kubernetes" + v1core "k8s.io/client-go/kubernetes/typed/core/v1" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/leaderelection" + "k8s.io/client-go/tools/leaderelection/resourcelock" + "k8s.io/client-go/tools/record" + "sigs.k8s.io/cluster-api/pkg/client/clientset_generated/clientset" + clusterapiclientsetscheme "sigs.k8s.io/cluster-api/pkg/client/clientset_generated/clientset/scheme" + "sigs.k8s.io/cluster-api/pkg/controller/cluster" + "sigs.k8s.io/cluster-api/pkg/controller/config" + "sigs.k8s.io/cluster-api/pkg/controller/sharedinformers" + + clusteractuator "sigs.k8s.io/cluster-api-provider-aws/cloud/aws/actuators/cluster" + "sigs.k8s.io/cluster-api-provider-aws/cloud/aws/controllers/cluster/options" +) + +const ( + controllerName = "aws-cluster-controller" +) + +func Start(server *options.Server, shutdown <-chan struct{}) { + config, err := controller.GetConfig(server.CommonConfig.Kubeconfig) + if err != nil { + glog.Fatalf("Could not create Config for talking to the apiserver: %v", err) + } + + client, err := clientset.NewForConfig(config) + if err != nil { + glog.Fatalf("Could not create client for talking to the apiserver: %v", err) + } + + params := clusteractuator.ActuatorParams{ + ClusterClient: client.ClusterV1alpha1().Clusters(corev1.NamespaceDefault), + } + actuator, err := clusteractuator.NewActuator(params) + if err != nil { + glog.Fatalf("Could not create aws cluster actuator: %v", err) + } + + si := sharedinformers.NewSharedInformers(config, shutdown) + c := cluster.NewClusterController(config, si, actuator) + c.RunAsync(shutdown) + + select {} +} + +func Run(server *options.Server) error { + kubeConfig, err := controller.GetConfig(server.CommonConfig.Kubeconfig) + if err != nil { + glog.Errorf("Could not create Config for talking to the apiserver: %v", err) + return err + } + + kubeClientControl, err := kubernetes.NewForConfig( + rest.AddUserAgent(kubeConfig, "cluster-controller-manager"), + ) + if err != nil { + glog.Errorf("Invalid API configuration for kubeconfig-control: %v", err) + return err + } + + recorder, err := createRecorder(kubeClientControl) + if err != nil { + glog.Errorf("Could not create event recorder : %v", err) + return err + } + + // run function will block and never return. + run := func(stop <-chan struct{}) { + Start(server, stop) + } + + leaderElectConfig := config.GetLeaderElectionConfig() + if !leaderElectConfig.LeaderElect { + run(make(<-chan (struct{}))) + } + + // Identity used to distinguish between multiple cluster controller instances. + id, err := os.Hostname() + if err != nil { + return err + } + + leaderElectionClient := kubernetes.NewForConfigOrDie(rest.AddUserAgent(kubeConfig, "cluster-leader-election")) + + id = id + "-" + string(uuid.NewUUID()) + // Lock required for leader election + rl, err := resourcelock.New( + leaderElectConfig.ResourceLock, + metav1.NamespaceSystem, + controllerName, + leaderElectionClient.CoreV1(), + resourcelock.ResourceLockConfig{ + Identity: id + "-" + controllerName, + EventRecorder: recorder, + }) + if err != nil { + return err + } + + // Try and become the leader and start cluster controller loops + leaderelection.RunOrDie(leaderelection.LeaderElectionConfig{ + Lock: rl, + LeaseDuration: leaderElectConfig.LeaseDuration.Duration, + RenewDeadline: leaderElectConfig.RenewDeadline.Duration, + RetryPeriod: leaderElectConfig.RetryPeriod.Duration, + Callbacks: leaderelection.LeaderCallbacks{ + OnStartedLeading: run, + OnStoppedLeading: func() { + glog.Fatalf("leaderelection lost") + }, + }, + }) + panic("unreachable") +} + +func createRecorder(kubeClient *kubernetes.Clientset) (record.EventRecorder, error) { + + eventsScheme := runtime.NewScheme() + if err := corev1.AddToScheme(eventsScheme); err != nil { + return nil, err + } + // We also emit events for our own types + clusterapiclientsetscheme.AddToScheme(eventsScheme) + + eventBroadcaster := record.NewBroadcaster() + eventBroadcaster.StartLogging(glog.Infof) + eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: v1core.New(kubeClient.CoreV1().RESTClient()).Events("")}) + return eventBroadcaster.NewRecorder(eventsScheme, corev1.EventSource{Component: controllerName}), nil +} diff --git a/cloud/aws/controllers/cluster/options/options.go b/cloud/aws/controllers/cluster/options/options.go new file mode 100644 index 000000000..fe5666042 --- /dev/null +++ b/cloud/aws/controllers/cluster/options/options.go @@ -0,0 +1,32 @@ +/* +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 options + +import ( + "sigs.k8s.io/cluster-api/pkg/controller/config" +) + +type Server struct { + CommonConfig *config.Configuration +} + +func NewServer() *Server { + s := Server{ + CommonConfig: &config.ControllerConfig, + } + return &s +} diff --git a/cloud/aws/controllers/machine/controller.go b/cloud/aws/controllers/machine/controller.go new file mode 100644 index 000000000..82f4f1355 --- /dev/null +++ b/cloud/aws/controllers/machine/controller.go @@ -0,0 +1,157 @@ +/* +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 machine + +import ( + "os" + + "github.com/golang/glog" + "github.com/kubernetes-incubator/apiserver-builder/pkg/controller" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/uuid" + "k8s.io/client-go/kubernetes" + v1core "k8s.io/client-go/kubernetes/typed/core/v1" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/leaderelection" + "k8s.io/client-go/tools/leaderelection/resourcelock" + "k8s.io/client-go/tools/record" + "sigs.k8s.io/cluster-api/pkg/client/clientset_generated/clientset" + clusterapiclientsetscheme "sigs.k8s.io/cluster-api/pkg/client/clientset_generated/clientset/scheme" + "sigs.k8s.io/cluster-api/pkg/controller/config" + machinecontroller "sigs.k8s.io/cluster-api/pkg/controller/machine" + "sigs.k8s.io/cluster-api/pkg/controller/sharedinformers" + + machineactuator "sigs.k8s.io/cluster-api-provider-aws/cloud/aws/actuators/machine" + "sigs.k8s.io/cluster-api-provider-aws/cloud/aws/controllers/machine/options" +) + +const ( + controllerName = "aws-machine-controller" +) + +func Start(server *options.Server, shutdown <-chan struct{}) { + config, err := controller.GetConfig(server.CommonConfig.Kubeconfig) + if err != nil { + glog.Fatalf("Could not create Config for talking to the apiserver: %v", err) + } + + client, err := clientset.NewForConfig(config) + if err != nil { + glog.Fatalf("Could not create client for talking to the apiserver: %v", err) + } + + params := machineactuator.ActuatorParams{ + ClusterClient: client.ClusterV1alpha1().Clusters(corev1.NamespaceDefault), + } + actuator, err := machineactuator.NewActuator(params) + if err != nil { + glog.Fatalf("Could not create aws machine actuator: %v", err) + } + + si := sharedinformers.NewSharedInformers(config, shutdown) + c := machinecontroller.NewMachineController(config, si, actuator) + c.RunAsync(shutdown) + + select {} +} + +func Run(server *options.Server) error { + kubeConfig, err := controller.GetConfig(server.CommonConfig.Kubeconfig) + if err != nil { + glog.Errorf("Could not create Config for talking to the apiserver: %v", err) + return err + } + + kubeClientControl, err := kubernetes.NewForConfig( + rest.AddUserAgent(kubeConfig, "machine-controller-manager"), + ) + if err != nil { + glog.Errorf("Invalid API configuration for kubeconfig-control: %v", err) + return err + } + + recorder, err := createRecorder(kubeClientControl) + if err != nil { + glog.Errorf("Could not create event recorder : %v", err) + return err + } + + // run function will block and never return. + run := func(stop <-chan struct{}) { + Start(server, stop) + } + + leaderElectConfig := config.GetLeaderElectionConfig() + if !leaderElectConfig.LeaderElect { + run(make(<-chan (struct{}))) + } + + // Identity used to distinguish between multiple machine controller instances. + id, err := os.Hostname() + if err != nil { + return err + } + + leaderElectionClient := kubernetes.NewForConfigOrDie(rest.AddUserAgent(kubeConfig, "machine-leader-election")) + + id = id + "-" + string(uuid.NewUUID()) + // Lock required for leader election + rl, err := resourcelock.New( + leaderElectConfig.ResourceLock, + metav1.NamespaceSystem, + controllerName, + leaderElectionClient.CoreV1(), + resourcelock.ResourceLockConfig{ + Identity: id + "-" + controllerName, + EventRecorder: recorder, + }) + if err != nil { + return err + } + + // Try and become the leader and start machine controller loops + leaderelection.RunOrDie(leaderelection.LeaderElectionConfig{ + Lock: rl, + LeaseDuration: leaderElectConfig.LeaseDuration.Duration, + RenewDeadline: leaderElectConfig.RenewDeadline.Duration, + RetryPeriod: leaderElectConfig.RetryPeriod.Duration, + Callbacks: leaderelection.LeaderCallbacks{ + OnStartedLeading: run, + OnStoppedLeading: func() { + glog.Fatalf("leaderelection lost") + }, + }, + }) + panic("unreachable") +} + +func createRecorder(kubeClient *kubernetes.Clientset) (record.EventRecorder, error) { + + eventsScheme := runtime.NewScheme() + if err := corev1.AddToScheme(eventsScheme); err != nil { + return nil, err + } + // We also emit events for our own types + clusterapiclientsetscheme.AddToScheme(eventsScheme) + + eventBroadcaster := record.NewBroadcaster() + eventBroadcaster.StartLogging(glog.Infof) + eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: v1core.New(kubeClient.CoreV1().RESTClient()).Events("")}) + return eventBroadcaster.NewRecorder(eventsScheme, corev1.EventSource{Component: controllerName}), nil +} diff --git a/cloud/aws/controllers/machine/options/options.go b/cloud/aws/controllers/machine/options/options.go new file mode 100644 index 000000000..fe5666042 --- /dev/null +++ b/cloud/aws/controllers/machine/options/options.go @@ -0,0 +1,32 @@ +/* +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 options + +import ( + "sigs.k8s.io/cluster-api/pkg/controller/config" +) + +type Server struct { + CommonConfig *config.Configuration +} + +func NewServer() *Server { + s := Server{ + CommonConfig: &config.ControllerConfig, + } + return &s +} diff --git a/cloud/aws/providerconfig/doc.go b/cloud/aws/providerconfig/doc.go new file mode 100644 index 000000000..eb0068339 --- /dev/null +++ b/cloud/aws/providerconfig/doc.go @@ -0,0 +1,19 @@ +// 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. + +// +k8s:deepcopy-gen=package,register +// +k8s:conversion-gen=sigs.k8s.io/cluster-api-provider-aws/cloud/aws/providerconfig +// +k8s:openapi-gen=true +// +k8s:defaulter-gen=TypeMeta + +package providerconfig diff --git a/cloud/aws/providerconfig/register.go b/cloud/aws/providerconfig/register.go new file mode 100644 index 000000000..e5a858136 --- /dev/null +++ b/cloud/aws/providerconfig/register.go @@ -0,0 +1,57 @@ +// 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 providerconfig + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var ( + SchemeBuilder runtime.SchemeBuilder + AddToScheme = SchemeBuilder.AddToScheme + localSchemeBuilder = &SchemeBuilder +) + +func init() { + localSchemeBuilder.Register(addKnownTypes) +} + +const GroupName = "awsproviderconfig" + +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal} + +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &AWSMachineProviderConfig{}, + ) + scheme.AddKnownTypes(SchemeGroupVersion, + &AWSClusterProviderConfig{}, + ) + scheme.AddKnownTypes(SchemeGroupVersion, + &AWSMachineProviderStatus{}, + ) + scheme.AddKnownTypes(SchemeGroupVersion, + &AWSClusterProviderStatus{}, + ) + return nil +} diff --git a/cloud/aws/providerconfig/types.go b/cloud/aws/providerconfig/types.go new file mode 100644 index 000000000..5b9070213 --- /dev/null +++ b/cloud/aws/providerconfig/types.go @@ -0,0 +1,38 @@ +// 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 providerconfig + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type AWSMachineProviderConfig struct { + metav1.TypeMeta `json:",inline"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type AWSClusterProviderConfig struct { + metav1.TypeMeta `json:",inline"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type AWSMachineProviderStatus struct { + metav1.TypeMeta `json:",inline"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type AWSClusterProviderStatus struct { + metav1.TypeMeta `json:",inline"` +} diff --git a/cloud/aws/providerconfig/v1alpha1/doc.go b/cloud/aws/providerconfig/v1alpha1/doc.go new file mode 100644 index 000000000..6dc3bf870 --- /dev/null +++ b/cloud/aws/providerconfig/v1alpha1/doc.go @@ -0,0 +1,19 @@ +// 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. + +// +k8s:deepcopy-gen=package,register +// +k8s:conversion-gen=sigs.k8s.io/cluster-api-provider-aws/cloud/aws/providerconfig +// +k8s:openapi-gen=true +// +k8s:defaulter-gen=TypeMeta + +package v1alpha1 diff --git a/cloud/aws/providerconfig/v1alpha1/register.go b/cloud/aws/providerconfig/v1alpha1/register.go new file mode 100644 index 000000000..ebbe81e10 --- /dev/null +++ b/cloud/aws/providerconfig/v1alpha1/register.go @@ -0,0 +1,138 @@ +// 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 v1alpha1 + +import ( + "bytes" + "fmt" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/runtime/serializer" + clusterv1 "sigs.k8s.io/cluster-api/pkg/apis/cluster/v1alpha1" + + "sigs.k8s.io/cluster-api-provider-aws/cloud/aws/providerconfig" +) + +// +k8s:deepcopy-gen=false +type AWSProviderConfigCodec struct { + encoder runtime.Encoder + decoder runtime.Decoder +} + +const GroupName = "awsproviderconfig" + +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} + +var ( + SchemeBuilder runtime.SchemeBuilder + localSchemeBuilder = &SchemeBuilder + AddToScheme = localSchemeBuilder.AddToScheme +) + +func init() { + localSchemeBuilder.Register(addKnownTypes) +} + +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &AWSMachineProviderConfig{}, + ) + scheme.AddKnownTypes(SchemeGroupVersion, + &AWSClusterProviderConfig{}, + ) + scheme.AddKnownTypes(SchemeGroupVersion, + &AWSMachineProviderStatus{}, + ) + scheme.AddKnownTypes(SchemeGroupVersion, + &AWSClusterProviderStatus{}, + ) + return nil +} + +func NewScheme() (*runtime.Scheme, error) { + scheme := runtime.NewScheme() + if err := AddToScheme(scheme); err != nil { + return nil, err + } + if err := providerconfig.AddToScheme(scheme); err != nil { + return nil, err + } + return scheme, nil +} + +func NewCodec() (*AWSProviderConfigCodec, error) { + scheme, err := NewScheme() + if err != nil { + return nil, err + } + codecFactory := serializer.NewCodecFactory(scheme) + encoder, err := newEncoder(&codecFactory) + if err != nil { + return nil, err + } + codec := AWSProviderConfigCodec{ + encoder: encoder, + decoder: codecFactory.UniversalDecoder(SchemeGroupVersion), + } + return &codec, nil +} + +func (codec *AWSProviderConfigCodec) DecodeFromProviderConfig(providerConfig clusterv1.ProviderConfig, out runtime.Object) error { + if providerConfig.Value != nil { + _, _, err := codec.decoder.Decode(providerConfig.Value.Raw, nil, out) + if err != nil { + return fmt.Errorf("decoding failure: %v", err) + } + } + return nil +} + +func (codec *AWSProviderConfigCodec) EncodeToProviderConfig(in runtime.Object) (*clusterv1.ProviderConfig, error) { + var buf bytes.Buffer + if err := codec.encoder.Encode(in, &buf); err != nil { + return nil, fmt.Errorf("encoding failed: %v", err) + } + return &clusterv1.ProviderConfig{ + Value: &runtime.RawExtension{Raw: buf.Bytes()}, + }, nil +} + +func (codec *AWSProviderConfigCodec) EncodeProviderStatus(in runtime.Object) (*runtime.RawExtension, error) { + var buf bytes.Buffer + if err := codec.encoder.Encode(in, &buf); err != nil { + return nil, fmt.Errorf("encoding failed: %v", err) + } + + return &runtime.RawExtension{Raw: buf.Bytes()}, nil +} + +func (codec *AWSProviderConfigCodec) DecodeProviderStatus(providerStatus *runtime.RawExtension, out runtime.Object) error { + if providerStatus != nil { + _, _, err := codec.decoder.Decode(providerStatus.Raw, nil, out) + if err != nil { + return fmt.Errorf("decoding failure: %v", err) + } + } + return nil +} + +func newEncoder(codecFactory *serializer.CodecFactory) (runtime.Encoder, error) { + serializerInfos := codecFactory.SupportedMediaTypes() + if len(serializerInfos) == 0 { + return nil, fmt.Errorf("unable to find any serlializers") + } + encoder := codecFactory.EncoderForVersion(serializerInfos[0].Serializer, SchemeGroupVersion) + return encoder, nil +} diff --git a/cloud/aws/providerconfig/v1alpha1/types.go b/cloud/aws/providerconfig/v1alpha1/types.go new file mode 100644 index 000000000..343f423d3 --- /dev/null +++ b/cloud/aws/providerconfig/v1alpha1/types.go @@ -0,0 +1,38 @@ +// 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 v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type AWSMachineProviderConfig struct { + metav1.TypeMeta `json:",inline"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type AWSClusterProviderConfig struct { + metav1.TypeMeta `json:",inline"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type AWSMachineProviderStatus struct { + metav1.TypeMeta `json:",inline"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type AWSClusterProviderStatus struct { + metav1.TypeMeta `json:",inline"` +} diff --git a/cloud/aws/providerconfig/v1alpha1/zz_generated.deepcopy.go b/cloud/aws/providerconfig/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 000000000..adcce680b --- /dev/null +++ b/cloud/aws/providerconfig/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,121 @@ +// +build !ignore_autogenerated + +// 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. +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AWSClusterProviderConfig) DeepCopyInto(out *AWSClusterProviderConfig) { + *out = *in + out.TypeMeta = in.TypeMeta + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSClusterProviderConfig. +func (in *AWSClusterProviderConfig) DeepCopy() *AWSClusterProviderConfig { + if in == nil { + return nil + } + out := new(AWSClusterProviderConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AWSClusterProviderConfig) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AWSClusterProviderStatus) DeepCopyInto(out *AWSClusterProviderStatus) { + *out = *in + out.TypeMeta = in.TypeMeta + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSClusterProviderStatus. +func (in *AWSClusterProviderStatus) DeepCopy() *AWSClusterProviderStatus { + if in == nil { + return nil + } + out := new(AWSClusterProviderStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AWSClusterProviderStatus) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AWSMachineProviderConfig) DeepCopyInto(out *AWSMachineProviderConfig) { + *out = *in + out.TypeMeta = in.TypeMeta + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSMachineProviderConfig. +func (in *AWSMachineProviderConfig) DeepCopy() *AWSMachineProviderConfig { + if in == nil { + return nil + } + out := new(AWSMachineProviderConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AWSMachineProviderConfig) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AWSMachineProviderStatus) DeepCopyInto(out *AWSMachineProviderStatus) { + *out = *in + out.TypeMeta = in.TypeMeta + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSMachineProviderStatus. +func (in *AWSMachineProviderStatus) DeepCopy() *AWSMachineProviderStatus { + if in == nil { + return nil + } + out := new(AWSMachineProviderStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AWSMachineProviderStatus) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} diff --git a/cloud/aws/providerconfig/zz_generated.deepcopy.go b/cloud/aws/providerconfig/zz_generated.deepcopy.go new file mode 100644 index 000000000..a60b6d64b --- /dev/null +++ b/cloud/aws/providerconfig/zz_generated.deepcopy.go @@ -0,0 +1,121 @@ +// +build !ignore_autogenerated + +// 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. +// Code generated by deepcopy-gen. DO NOT EDIT. + +package providerconfig + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AWSClusterProviderConfig) DeepCopyInto(out *AWSClusterProviderConfig) { + *out = *in + out.TypeMeta = in.TypeMeta + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSClusterProviderConfig. +func (in *AWSClusterProviderConfig) DeepCopy() *AWSClusterProviderConfig { + if in == nil { + return nil + } + out := new(AWSClusterProviderConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AWSClusterProviderConfig) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AWSClusterProviderStatus) DeepCopyInto(out *AWSClusterProviderStatus) { + *out = *in + out.TypeMeta = in.TypeMeta + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSClusterProviderStatus. +func (in *AWSClusterProviderStatus) DeepCopy() *AWSClusterProviderStatus { + if in == nil { + return nil + } + out := new(AWSClusterProviderStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AWSClusterProviderStatus) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AWSMachineProviderConfig) DeepCopyInto(out *AWSMachineProviderConfig) { + *out = *in + out.TypeMeta = in.TypeMeta + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSMachineProviderConfig. +func (in *AWSMachineProviderConfig) DeepCopy() *AWSMachineProviderConfig { + if in == nil { + return nil + } + out := new(AWSMachineProviderConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AWSMachineProviderConfig) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AWSMachineProviderStatus) DeepCopyInto(out *AWSMachineProviderStatus) { + *out = *in + out.TypeMeta = in.TypeMeta + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSMachineProviderStatus. +func (in *AWSMachineProviderStatus) DeepCopy() *AWSMachineProviderStatus { + if in == nil { + return nil + } + out := new(AWSMachineProviderStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AWSMachineProviderStatus) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} diff --git a/clusterctl/examples/aws/.gitignore b/clusterctl/examples/aws/.gitignore new file mode 100644 index 000000000..89f9ac04a --- /dev/null +++ b/clusterctl/examples/aws/.gitignore @@ -0,0 +1 @@ +out/ diff --git a/clusterctl/examples/aws/README.md b/clusterctl/examples/aws/README.md new file mode 100644 index 000000000..e455b3e13 --- /dev/null +++ b/clusterctl/examples/aws/README.md @@ -0,0 +1,24 @@ +# Openstack Example Files +## Contents +*.yaml files - concrete example files that can be used as is. +*.yaml.template files - template example files that need values filled in before use. + +## Generation +For convenience, a generation script which populates templates based on openstack cloud provider +configuration is provided. + +1. Run the generation script. +``` +./generate-yaml.sh +``` + +If yaml file already exists, you will see an error like the one below: + +``` +$ ./generate-yaml.sh +File provider-components.yaml already exists. Delete it manually before running this script. +``` + +## Manual Modification +You may always manually curate files based on the examples provided. + diff --git a/clusterctl/examples/aws/cluster.yaml.template b/clusterctl/examples/aws/cluster.yaml.template new file mode 100644 index 000000000..b5d034762 --- /dev/null +++ b/clusterctl/examples/aws/cluster.yaml.template @@ -0,0 +1,16 @@ +apiVersion: "cluster.k8s.io/v1alpha1" +kind: Cluster +metadata: + name: test1 +spec: + clusterNetwork: + services: + cidrBlocks: ["10.96.0.0/12"] + pods: + cidrBlocks: ["192.168.0.0/16"] + serviceDomain: "cluster.local" + providerConfig: + value: + apiVersion: "awsproviderconfig/v1alpha1" + kind: "AWSClusterProviderConfig" + diff --git a/clusterctl/examples/aws/generate-yaml.sh b/clusterctl/examples/aws/generate-yaml.sh new file mode 100644 index 000000000..c24d51cfd --- /dev/null +++ b/clusterctl/examples/aws/generate-yaml.sh @@ -0,0 +1,54 @@ +#!/bin/sh +set -e + +PROVIDERCOMPONENT_TEMPLATE_FILE=provider-components.yaml.template +PROVIDERCOMPONENT_GENERATED_FILE=provider-components.yaml + +OVERWRITE=0 + +SCRIPT=$(basename $0) +while test $# -gt 0; do + case "$1" in + -h|--help) + echo "$SCRIPT - generates input yaml files for Cluster API on openstack" + echo " " + echo "$SCRIPT [options]" + echo " " + echo "options:" + echo "-h, --help show brief help" + echo "-f, --force-overwrite if file to be generated already exists, force script to overwrite it" + exit 0 + ;; + -f) + OVERWRITE=1 + shift + ;; + --force-overwrite) + OVERWRITE=1 + shift + ;; + *) + break + ;; + esac +done + +if [ $OVERWRITE -ne 1 ] && [ -f $PROVIDERCOMPONENT_GENERATED_FILE ]; then + echo "File $PROVIDERCOMPONENT_GENERATED_FILE already exists. Delete it manually before running this script." + exit 1 +fi + +OS=$(uname) +if [[ "$OS" =~ "Linux" ]]; then +elif [[ "$OS" =~ "Darwin" ]]; then +else + echo "Unrecognized OS : $OS" + exit 1 +fi + +cat $PROVIDERCOMPONENT_TEMPLATE_FILE \ + > $PROVIDERCOMPONENT_GENERATED_FILE + +echo "Done generating $PROVIDERCOMPONENT_GENERATED_FILE" +echo "You will still need to generate the cluster.yaml and machines.yaml" + diff --git a/clusterctl/examples/aws/machines.yaml.template b/clusterctl/examples/aws/machines.yaml.template new file mode 100644 index 000000000..d1c8f8caf --- /dev/null +++ b/clusterctl/examples/aws/machines.yaml.template @@ -0,0 +1,15 @@ +items: +- apiVersion: "cluster.k8s.io/v1alpha1" + kind: Machine + metadata: + generateName: aws-controlplane- + labels: + set: controlplane + spec: +- apiVersion: "cluster.k8s.io/v1alpha1" + kind: Machine + metadata: + generateName: aws-node- + labels: + set: node + spec: \ No newline at end of file diff --git a/clusterctl/examples/aws/provider-components.yaml.template b/clusterctl/examples/aws/provider-components.yaml.template new file mode 100644 index 000000000..e9abf5f82 --- /dev/null +++ b/clusterctl/examples/aws/provider-components.yaml.template @@ -0,0 +1,101 @@ +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + name: clusterapi-controllers + labels: + api: clusterapi +spec: + replicas: 1 + template: + metadata: + labels: + api: clusterapi + spec: + nodeSelector: + node-role.kubernetes.io/master: "" + tolerations: + - effect: NoSchedule + key: node-role.kubernetes.io/master + - key: CriticalAddonsOnly + operator: Exists + - effect: NoExecute + key: node.alpha.kubernetes.io/notReady + operator: Exists + - effect: NoExecute + key: node.alpha.kubernetes.io/unreachable + operator: Exists + containers: + - name: controller-manager + image: gcr.io/k8s-cluster-api/controller-manager:0.0.7 + volumeMounts: + - name: config + mountPath: /etc/kubernetes + - name: certs + mountPath: /etc/ssl/certs + command: + - "./controller-manager" + args: + - --kubeconfig=/etc/kubernetes/admin.conf + - --leader-elect + resources: + requests: + cpu: 100m + memory: 20Mi + limits: + cpu: 100m + memory: 30Mi + - name: aws-cluster-controller + image: gcr.io/k8s-cluster-api/aws-cluster-controller:0.0.1 + volumeMounts: + - name: config + mountPath: /etc/kubernetes + - name: certs + mountPath: /etc/ssl/certs + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + command: + - "./cluster-controller" + args: + - --kubeconfig=/etc/kubernetes/admin.conf + - --leader-elect + resources: + requests: + cpu: 200m + memory: 200Mi + limits: + cpu: 400m + memory: 500Mi + - name: aws-machine-controller + image: gcr.io/k8s-cluster-api/aws-machine-controller:0.0.1 + volumeMounts: + - name: config + mountPath: /etc/kubernetes + - name: certs + mountPath: /etc/ssl/certs + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + command: + - "./machine-controller" + args: + - --kubeconfig=/etc/kubernetes/admin.conf + - --leader-elect + resources: + requests: + cpu: 200m + memory: 200Mi + limits: + cpu: 400m + memory: 500Mi + volumes: + - name: config + hostPath: + path: /etc/kubernetes + - name: certs + hostPath: + path: /etc/ssl/certs diff --git a/cmd/cluster-controller/Dockerfile b/cmd/cluster-controller/Dockerfile new file mode 100644 index 000000000..c4918c96d --- /dev/null +++ b/cmd/cluster-controller/Dockerfile @@ -0,0 +1,29 @@ +# 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. + +# Reproducible builder image +FROM golang:1.10.0 as builder +WORKDIR /go/src/sigs.k8s.io/cluster-api-provider-aws +# This expects that the context passed to the docker build command is +# the cluster-api-provider-aws directory. +# e.g. docker build -t -f +COPY . . + +RUN CGO_ENABLED=0 GOOS=linux go install -a -ldflags '-extldflags "-static"' sigs.k8s.io/cluster-api-provider-aws/cmd/cluster-controller + +# Final container +FROM debian:stretch-slim +RUN apt-get update && apt-get install -y ca-certificates openssh-server && rm -rf /var/lib/apt/lists/* + +COPY --from=builder /go/bin/cluster-controller . diff --git a/cmd/cluster-controller/Makefile b/cmd/cluster-controller/Makefile new file mode 100644 index 000000000..abef2e8f4 --- /dev/null +++ b/cmd/cluster-controller/Makefile @@ -0,0 +1,38 @@ +# 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. + +.PHONY: image + +GCR_BUCKET = k8s-cluster-api +PREFIX = gcr.io/$(GCR_BUCKET) +DEV_PREFIX ?= gcr.io/$(shell gcloud config get-value project) +NAME = aws-cluster-controller +TAG = 0.0.1 + +image: + docker build -t "$(PREFIX)/$(NAME):$(TAG)" -f ./Dockerfile ../.. + +push: image + docker push "$(PREFIX)/$(NAME):$(TAG)" + $(MAKE) fix_gcs_permissions + +fix_gcs_permissions: + gsutil acl ch -u AllUsers:READ gs://artifacts.$(GCR_BUCKET).appspot.com + gsutil -m acl ch -r -u AllUsers:READ gs://artifacts.$(GCR_BUCKET).appspot.com + +dev_image: + docker build -t "$(DEV_PREFIX)/$(NAME):$(TAG)-dev" -f ./Dockerfile ../.. + +dev_push: dev_image + docker push "$(DEV_PREFIX)/$(NAME):$(TAG)-dev" diff --git a/cmd/cluster-controller/main.go b/cmd/cluster-controller/main.go new file mode 100644 index 000000000..bf51243e2 --- /dev/null +++ b/cmd/cluster-controller/main.go @@ -0,0 +1,47 @@ +/* +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 main + +import ( + "flag" + + "github.com/golang/glog" + "github.com/spf13/pflag" + "k8s.io/apiserver/pkg/util/logs" + "sigs.k8s.io/cluster-api/pkg/controller/config" + + "sigs.k8s.io/cluster-api-provider-aws/cloud/aws/controllers/cluster" + "sigs.k8s.io/cluster-api-provider-aws/cloud/aws/controllers/cluster/options" +) + +func init() { + config.ControllerConfig.AddFlags(pflag.CommandLine) +} + +func main() { + // the following line exists to make glog happy, for more information, see: https://github.com/kubernetes/kubernetes/issues/17162 + flag.CommandLine.Parse([]string{}) + pflag.Parse() + + logs.InitLogs() + defer logs.FlushLogs() + + clusterServer := options.NewServer() + if err := cluster.Run(clusterServer); err != nil { + glog.Errorf("Failed to start cluster controller. Err: %v", err) + } +} diff --git a/cmd/machine-controller/Dockerfile b/cmd/machine-controller/Dockerfile new file mode 100644 index 000000000..ef6feb789 --- /dev/null +++ b/cmd/machine-controller/Dockerfile @@ -0,0 +1,29 @@ +# 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. + +# Reproducible builder image +FROM golang:1.10.0 as builder +WORKDIR /go/src/sigs.k8s.io/cluster-api-provider-aws +# This expects that the context passed to the docker build command is +# the cluster-api-provider-aws directory. +# e.g. docker build -t -f +COPY . . + +RUN CGO_ENABLED=0 GOOS=linux go install -a -ldflags '-extldflags "-static"' sigs.k8s.io/cluster-api-provider-aws/cmd/machine-controller + +# Final container +FROM debian:stretch-slim +RUN apt-get update && apt-get install -y ca-certificates openssh-server && rm -rf /var/lib/apt/lists/* + +COPY --from=builder /go/bin/machine-controller . diff --git a/cmd/machine-controller/Makefile b/cmd/machine-controller/Makefile new file mode 100644 index 000000000..b80ef959b --- /dev/null +++ b/cmd/machine-controller/Makefile @@ -0,0 +1,38 @@ +# 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. + +.PHONY: image + +GCR_BUCKET = k8s-cluster-api +PREFIX = gcr.io/$(GCR_BUCKET) +DEV_PREFIX ?= gcr.io/$(shell gcloud config get-value project) +NAME = aws-machine-controller +TAG = 0.0.1 + +image: + docker build -t "$(PREFIX)/$(NAME):$(TAG)" -f ./Dockerfile ../.. + +push: image + docker push "$(PREFIX)/$(NAME):$(TAG)" + $(MAKE) fix_gcs_permissions + +fix_gcs_permissions: + gsutil acl ch -u AllUsers:READ gs://artifacts.$(GCR_BUCKET).appspot.com + gsutil -m acl ch -r -u AllUsers:READ gs://artifacts.$(GCR_BUCKET).appspot.com + +dev_image: + docker build -t "$(DEV_PREFIX)/$(NAME):$(TAG)-dev" -f ./Dockerfile ../.. + +dev_push: dev_image + docker push "$(DEV_PREFIX)/$(NAME):$(TAG)-dev" diff --git a/cmd/machine-controller/main.go b/cmd/machine-controller/main.go new file mode 100644 index 000000000..304cdfd2a --- /dev/null +++ b/cmd/machine-controller/main.go @@ -0,0 +1,47 @@ +/* +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 main + +import ( + "flag" + + "github.com/golang/glog" + "github.com/spf13/pflag" + "k8s.io/apiserver/pkg/util/logs" + "sigs.k8s.io/cluster-api/pkg/controller/config" + + "sigs.k8s.io/cluster-api-provider-aws/cloud/aws/controllers/machine" + "sigs.k8s.io/cluster-api-provider-aws/cloud/aws/controllers/machine/options" +) + +func init() { + config.ControllerConfig.AddFlags(pflag.CommandLine) +} + +func main() { + // the following line exists to make glog happy, for more information, see: https://github.com/kubernetes/kubernetes/issues/17162 + flag.CommandLine.Parse([]string{}) + pflag.Parse() + + logs.InitLogs() + defer logs.FlushLogs() + + machineServer := options.NewServer() + if err := machine.Run(machineServer); err != nil { + glog.Errorf("Failed to start the machine controller. Err: %v", err) + } +} diff --git a/code-of-conduct.md b/code-of-conduct.md new file mode 100644 index 000000000..0d15c00cf --- /dev/null +++ b/code-of-conduct.md @@ -0,0 +1,3 @@ +# Kubernetes Community Code of Conduct + +Please refer to our [Kubernetes Community Code of Conduct](https://git.k8s.io/community/code-of-conduct.md) diff --git a/hack/update-gofmt.sh b/hack/update-gofmt.sh new file mode 100755 index 000000000..a14aecbbd --- /dev/null +++ b/hack/update-gofmt.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# 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. + +set -o errexit +set -o nounset +set -o pipefail + +find . -name "*.go" | grep -v "\/vendor\/" | xargs gofmt -s -w diff --git a/hack/verify-gofmt.sh b/hack/verify-gofmt.sh new file mode 100755 index 000000000..693412cc5 --- /dev/null +++ b/hack/verify-gofmt.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# 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. + +set -o errexit +set -o nounset +set -o pipefail + +if ! which gofmt > /dev/null; then + echo "Can not find gofmt" + exit 1 +fi + +diff=$(find . -name "*.go" | grep -v "\/vendor\/" | xargs gofmt -s -d 2>&1) +if [[ -n "${diff}" ]]; then + echo "${diff}" + echo + echo "Please run hack/update-gofmt.sh" + exit 1 +fi