Merge pull request #43 from ultimateboy/pull-auth

feat(server): create docker pull secret in application namespace and append imagepullsecret to default service account.
This commit is contained in:
Matt Tucker 2017-05-11 10:49:28 -06:00 коммит произвёл GitHub
Родитель f9718af4a9 4c95ff88c1
Коммит 4994e2e636
6 изменённых файлов: 231 добавлений и 39 удалений

Просмотреть файл

@ -132,6 +132,6 @@ endif
ifndef HAS_GIT
$(error You must install git)
endif
glide install
glide install --strip-vendor
include versioning.mk

9
NOTICE
Просмотреть файл

@ -76,3 +76,12 @@ The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
****
Kubernetes client-go
Apache 2.0 License
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
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions and limitations under the License.

Просмотреть файл

@ -24,6 +24,8 @@ import (
"github.com/ghodss/yaml"
"github.com/gorilla/websocket"
"github.com/julienschmidt/httprouter"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/pkg/api/v1"
"k8s.io/helm/pkg/chartutil"
"k8s.io/helm/pkg/helm"
"k8s.io/helm/pkg/proto/hapi/release"
@ -33,6 +35,13 @@ import (
"github.com/Azure/draft/pkg/version"
)
const (
// name of the docker pull secret draftd will create in the desired destination namespace
pullSecretName = "draftd-pullsecret"
// name of the default service account draftd will modify with the imagepullsecret
defaultServiceAccountName = "default"
)
// WebsocketUpgrader represents the default websocket.Upgrader that Draft employs
var WebsocketUpgrader = websocket.Upgrader{
EnableCompression: true,
@ -48,6 +57,7 @@ type Server struct {
Listener net.Listener
DockerClient *docker.Client
HelmClient *helm.Client
KubeClient *kubernetes.Clientset
// RegistryAuth is the authorization token used to push images up to the registry.
//
// This field follows the format of the X-Registry-Auth header.
@ -61,6 +71,17 @@ type Server struct {
Basedomain string
}
// DockerAuth is a container for the registry authentication credentials wrapped by the registry server name
type DockerAuth map[string]RegistryAuth
// RegistryAuth is the registry authentication credentials
type RegistryAuth struct {
Username string `json:"username"`
Password string `json:"password"`
Email string `json:"email"`
RegistryToken string `json:"registrytoken"`
}
// Serve starts the HTTP server, accepting all new connections.
func (s *Server) Serve() error {
return s.HTTPServer.Serve(s.Listener)
@ -358,6 +379,78 @@ func buildApp(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
handleClosingError(conn, "Could not load chart archive", err)
}
// Determine if the destination namespace exists, create it if not.
_, err = server.KubeClient.CoreV1().Namespaces().Get(namespace)
if err != nil {
_, err = server.KubeClient.CoreV1().Namespaces().Create(&v1.Namespace{
ObjectMeta: v1.ObjectMeta{
Name: namespace,
},
})
if err != nil {
handleClosingError(conn, "Could not create namespace", err)
}
}
// Determine if the registry pull secret exists in the desired namespace, create it if not.
_, err = server.KubeClient.CoreV1().Secrets(namespace).Get(pullSecretName)
if err != nil {
// Base64 decode the registryauth string.
data, err := base64.StdEncoding.DecodeString(server.RegistryAuth)
if err != nil {
handleClosingError(conn, "Could not base64 decode registry authentication string", err)
}
// Break up registry auth json string into a RegistryAuth object.
var regAuth RegistryAuth
err = json.Unmarshal(data, &regAuth)
if err != nil {
handleClosingError(conn, "Could not json decode registry authentication string", err)
}
// Create a new json string with the full dockerauth, including the registry URL.
jsonString, err := json.Marshal(DockerAuth{server.RegistryURL: regAuth})
if err != nil {
handleClosingError(conn, "Could not json encode docker authentication string", err)
}
_, err = server.KubeClient.CoreV1().Secrets(namespace).Create(&v1.Secret{
ObjectMeta: v1.ObjectMeta{
Name: pullSecretName,
Namespace: namespace,
},
Type: v1.SecretTypeDockercfg,
StringData: map[string]string{
".dockercfg": string(jsonString),
},
})
if err != nil {
handleClosingError(conn, "Could not create registry pull secret", err)
}
}
// Determine if the default service account in the desired namespace has the correct imagePullSecret, add it if not.
serviceAccount, err := server.KubeClient.CoreV1().ServiceAccounts(namespace).Get(defaultServiceAccountName)
if err != nil {
handleClosingError(conn, "Could not load default service account", err)
}
foundPullSecret := false
for _, ps := range serviceAccount.ImagePullSecrets {
if ps.Name == pullSecretName {
foundPullSecret = true
break
}
}
if !foundPullSecret {
serviceAccount.ImagePullSecrets = append(serviceAccount.ImagePullSecrets, v1.LocalObjectReference{
Name: pullSecretName,
})
_, err = server.KubeClient.CoreV1().ServiceAccounts(namespace).Update(serviceAccount)
if err != nil {
handleClosingError(conn, "Could not modify default service account with registry pull secret", err)
}
}
// combinedVars takes the basedomain configured in draftd and appends that to the rawVals
combinedVars := append([]byte(fmt.Sprintf("basedomain: %s\n", server.Basedomain))[:], []byte(rawVals)[:]...)

Просмотреть файл

@ -8,6 +8,8 @@ import (
log "github.com/Sirupsen/logrus"
docker "github.com/docker/docker/client"
"github.com/spf13/cobra"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/helm/pkg/helm"
"github.com/Azure/draft/api"
@ -86,6 +88,15 @@ func (c *startCmd) run() error {
return err
}
kubeConfig, err := rest.InClusterConfig()
if err != nil {
return err
}
kubeClientset, err := kubernetes.NewForConfig(kubeConfig)
if err != nil {
return err
}
server, err := api.NewServer(protoAndAddr[0], protoAndAddr[1])
if err != nil {
return fmt.Errorf("failed to create server at %s: %v", c.listenAddr, err)
@ -96,6 +107,7 @@ func (c *startCmd) run() error {
server.RegistryURL = c.registryURL
server.Basedomain = c.basedomain
server.HelmClient = helm.NewClient(helm.Host(c.tillerURI))
server.KubeClient = kubeClientset
log.Printf("server is now listening at %s", c.listenAddr)
return server.Serve()
}

150
glide.lock сгенерированный
Просмотреть файл

@ -1,5 +1,5 @@
hash: d26f2b79aa1989919720da9a9b7dbd7d6bd6fab51c1aa7e8b99a47e7ad5d6bf1
updated: 2017-05-08T10:21:44.503026775-07:00
hash: f40bc7017f0f46cf9ffaaaa82f7fc973cdca0884d24287171c3bb484303f3eac
updated: 2017-05-09T14:23:38.824759012-06:00
imports:
- name: cloud.google.com/go
version: 3b1ae45394a234c385be014e9a488f2bb6eef821
@ -27,8 +27,6 @@ imports:
- name: github.com/coreos/pkg
version: fa29b1d70f0beaddd4c7021607cc3c3be8ce94b8
subpackages:
- capnslog
- dlopen
- health
- httputil
- timeutil
@ -163,31 +161,8 @@ imports:
- name: github.com/gogo/protobuf
version: e18d7aa8f8c624c915db340349aad4c49b10d173
subpackages:
- gogoproto
- plugin/compare
- plugin/defaultcheck
- plugin/description
- plugin/embedcheck
- plugin/enumstringer
- plugin/equal
- plugin/face
- plugin/gostring
- plugin/marshalto
- plugin/oneofcheck
- plugin/populate
- plugin/size
- plugin/stringer
- plugin/testgen
- plugin/union
- plugin/unmarshal
- proto
- protoc-gen-gogo/descriptor
- protoc-gen-gogo/generator
- protoc-gen-gogo/grpc
- protoc-gen-gogo/plugin
- sortkeys
- vanity
- vanity/command
- name: github.com/golang/glog
version: 44145f04b68cf362d9c4df2182967c2275eaefed
- name: github.com/golang/groupcache
@ -195,7 +170,7 @@ imports:
subpackages:
- lru
- name: github.com/golang/protobuf
version: df1d3ca07d2d07bba352d5b73c4313b4e2a6203e
version: 8616e8ee5e20a1704615e6c8d7afcdac06087a67
subpackages:
- proto
- ptypes/any
@ -258,7 +233,7 @@ imports:
- name: github.com/pborman/uuid
version: ca53cad383cad2479bbba7f7a1a05797ec1386e4
- name: github.com/pkg/errors
version: a22138067af1c4942683050411a841ade67fe1eb
version: 645ef00459ed84a119197bfb8d8205042c6df63d
- name: github.com/PuerkitoBio/purell
version: 8a290539e2e8629dbc4e6bad948158f790ec31f4
- name: github.com/PuerkitoBio/urlesc
@ -279,7 +254,6 @@ imports:
version: f1f1a805ed361a0e078bb537e4ea78cd37dcf065
subpackages:
- codec
- codec/codecgen
- name: github.com/vbatts/tar-split
version: b9127a139315e57ebc26030e7decf72d0a20acb4
subpackages:
@ -289,14 +263,8 @@ imports:
- name: golang.org/x/crypto
version: 1f22c0103821b9390939b6776727195525381532
subpackages:
- bcrypt
- blowfish
- curve25519
- pbkdf2
- pkcs12
- pkcs12/internal/rc2
- scrypt
- ssh
- ssh/terminal
- name: golang.org/x/net
version: e90d6d0afc4c315a0d87a568ae68577cc15149a0
@ -367,6 +335,114 @@ imports:
version: 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4
- name: gopkg.in/yaml.v2
version: a3f3340b5840cee44f372bddb5880fcbc419b46a
- name: k8s.io/client-go
version: e121606b0d09b2e1c467183ee46217fa85a6b672
subpackages:
- discovery
- kubernetes
- kubernetes/typed/apps/v1beta1
- kubernetes/typed/authentication/v1beta1
- kubernetes/typed/authorization/v1beta1
- kubernetes/typed/autoscaling/v1
- kubernetes/typed/batch/v1
- kubernetes/typed/batch/v2alpha1
- kubernetes/typed/certificates/v1alpha1
- kubernetes/typed/core/v1
- kubernetes/typed/extensions/v1beta1
- kubernetes/typed/policy/v1beta1
- kubernetes/typed/rbac/v1alpha1
- kubernetes/typed/storage/v1beta1
- pkg/api
- pkg/api/errors
- pkg/api/install
- pkg/api/meta
- pkg/api/meta/metatypes
- pkg/api/resource
- pkg/api/unversioned
- pkg/api/v1
- pkg/api/validation/path
- pkg/apimachinery
- pkg/apimachinery/announced
- pkg/apimachinery/registered
- pkg/apis/apps
- pkg/apis/apps/install
- pkg/apis/apps/v1beta1
- pkg/apis/authentication
- pkg/apis/authentication/install
- pkg/apis/authentication/v1beta1
- pkg/apis/authorization
- pkg/apis/authorization/install
- pkg/apis/authorization/v1beta1
- pkg/apis/autoscaling
- pkg/apis/autoscaling/install
- pkg/apis/autoscaling/v1
- pkg/apis/batch
- pkg/apis/batch/install
- pkg/apis/batch/v1
- pkg/apis/batch/v2alpha1
- pkg/apis/certificates
- pkg/apis/certificates/install
- pkg/apis/certificates/v1alpha1
- pkg/apis/extensions
- pkg/apis/extensions/install
- pkg/apis/extensions/v1beta1
- pkg/apis/policy
- pkg/apis/policy/install
- pkg/apis/policy/v1beta1
- pkg/apis/rbac
- pkg/apis/rbac/install
- pkg/apis/rbac/v1alpha1
- pkg/apis/storage
- pkg/apis/storage/install
- pkg/apis/storage/v1beta1
- pkg/auth/user
- pkg/conversion
- pkg/conversion/queryparams
- pkg/fields
- pkg/genericapiserver/openapi/common
- pkg/labels
- pkg/runtime
- 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/third_party/forked/golang/reflect
- pkg/third_party/forked/golang/template
- pkg/types
- pkg/util
- pkg/util/cert
- pkg/util/clock
- pkg/util/errors
- pkg/util/flowcontrol
- pkg/util/framer
- pkg/util/integer
- pkg/util/intstr
- pkg/util/json
- pkg/util/jsonpath
- pkg/util/labels
- pkg/util/net
- pkg/util/parsers
- pkg/util/rand
- pkg/util/runtime
- pkg/util/sets
- pkg/util/uuid
- pkg/util/validation
- pkg/util/validation/field
- pkg/util/wait
- pkg/util/yaml
- pkg/version
- pkg/watch
- pkg/watch/versioned
- plugin/pkg/client/auth
- plugin/pkg/client/auth/gcp
- plugin/pkg/client/auth/oidc
- rest
- tools/clientcmd/api
- tools/metrics
- transport
- name: k8s.io/helm
version: 32562a3040bb5ca690339b9840b6f60f8ce25da4
subpackages:
@ -388,7 +464,7 @@ imports:
- pkg/tiller/environment
- pkg/version
- name: k8s.io/kubernetes
version: f07eea23494be1e7c11a8e2cf51bd96d1ec9fdf1
version: 8eb75a5810cba92ccad845ca360cf924f2385881
subpackages:
- federation/apis/federation
- federation/apis/federation/install

Просмотреть файл

@ -1,8 +1,8 @@
package: github.com/Azure/draft
import:
- package: github.com/gorilla/websocket
repo: https://github.com/bacongobbler/websocket
version: 7fe3183ee95b29153898356cc2c6026a8cb7afe5
repo: https://github.com/bacongobbler/websocket
vcs: git
- package: github.com/docker/docker
version: v17.03.0-ce
@ -21,3 +21,5 @@ import:
- package: github.com/ghodss/yaml
version: 04f313413ffd65ce25f2541bfd2b2ceec5c0908c
- package: github.com/BurntSushi/toml
- package: k8s.io/client-go
version: ~v2.0.0