... | ... |
@@ -318,7 +318,7 @@ docker tag -f openshift/ruby-20-centos7:latest ${DOCKER_REGISTRY}/cache/ruby-20- |
318 | 318 |
docker push ${DOCKER_REGISTRY}/cache/ruby-20-centos7:latest |
319 | 319 |
echo "[INFO] Pushed ruby-20-centos7" |
320 | 320 |
|
321 |
-echo "[INFO] Back to 'master' context with 'admin' user..." |
|
321 |
+echo "[INFO] Back to 'default' project with 'admin' user..." |
|
322 | 322 |
osc project ${CLUSTER_ADMIN_CONTEXT} |
323 | 323 |
|
324 | 324 |
# The build requires a dockercfg secret in the builder service account in order |
... | ... |
@@ -338,12 +338,7 @@ osc project test |
338 | 338 |
echo "[INFO] Applying STI application config" |
339 | 339 |
osc create -f "${STI_CONFIG_FILE}" |
340 | 340 |
|
341 |
- |
|
342 |
-# this needs to be done before waiting for the build because right now only cluster-admins can see build logs, because that uses proxy |
|
343 |
-echo "[INFO] Back to 'master' context with 'admin' user..." |
|
344 |
-osc project default |
|
345 |
- |
|
346 |
-# Trigger build |
|
341 |
+# Wait for build which should have triggered automatically |
|
347 | 342 |
echo "[INFO] Starting build from ${STI_CONFIG_FILE} and streaming its logs..." |
348 | 343 |
#osc start-build -n test ruby-sample-build --follow |
349 | 344 |
wait_for_build "test" |
... | ... |
@@ -363,6 +358,9 @@ wait_for_app "test" |
363 | 363 |
#wait_for_build "custom" |
364 | 364 |
#wait_for_app "custom" |
365 | 365 |
|
366 |
+echo "[INFO] Back to 'default' project with 'admin' user..." |
|
367 |
+osc project ${CLUSTER_ADMIN_CONTEXT} |
|
368 |
+ |
|
366 | 369 |
# ensure the router is started |
367 | 370 |
# TODO: simplify when #4702 is fixed upstream |
368 | 371 |
wait_for_command '[[ "$(osc get endpoints router --output-version=v1beta3 -t "{{ if .subsets }}{{ len .subsets }}{{ else }}0{{ end }}" || echo "0")" != "0" ]]' $((5*TIME_MIN)) |
... | ... |
@@ -36,7 +36,7 @@ func TestSubjects(t *testing.T) { |
36 | 36 |
Verb: "get", |
37 | 37 |
Resource: "pods", |
38 | 38 |
}, |
39 |
- expectedUsers: util.NewStringSet("Anna", "ClusterAdmin", "Ellen", "Valerie", "system:openshift-client", "system:openshift-deployer"), |
|
39 |
+ expectedUsers: util.NewStringSet("Anna", "ClusterAdmin", "Ellen", "Valerie", "system:openshift-client"), |
|
40 | 40 |
expectedGroups: util.NewStringSet("RootUsers", "system:cluster-admins", "system:cluster-readers", "system:nodes"), |
41 | 41 |
} |
42 | 42 |
test.clusterPolicies = newDefaultClusterPolicies() |
... | ... |
@@ -77,7 +77,6 @@ func DefaultAPIClientCAFile(certDir string) string { |
77 | 77 |
|
78 | 78 |
func DefaultAPIClientCerts(certDir string) []ClientCertInfo { |
79 | 79 |
return []ClientCertInfo{ |
80 |
- DefaultDeployerClientCertInfo(certDir), |
|
81 | 80 |
DefaultOpenshiftLoopbackClientCertInfo(certDir), |
82 | 81 |
DefaultClusterAdminClientCertInfo(certDir), |
83 | 82 |
DefaultRouterClientCertInfo(certDir), |
... | ... |
@@ -109,18 +108,6 @@ func DefaultRegistryClientCertInfo(certDir string) ClientCertInfo { |
109 | 109 |
} |
110 | 110 |
} |
111 | 111 |
|
112 |
-func DefaultDeployerClientCertInfo(certDir string) ClientCertInfo { |
|
113 |
- return ClientCertInfo{ |
|
114 |
- CertLocation: configapi.CertInfo{ |
|
115 |
- CertFile: DefaultCertFilename(certDir, "openshift-deployer"), |
|
116 |
- KeyFile: DefaultKeyFilename(certDir, "openshift-deployer"), |
|
117 |
- }, |
|
118 |
- UnqualifiedUser: "openshift-deployer", |
|
119 |
- User: "system:openshift-deployer", |
|
120 |
- Groups: util.NewStringSet("system:deployers"), |
|
121 |
- } |
|
122 |
-} |
|
123 |
- |
|
124 | 112 |
func DefaultOpenshiftLoopbackClientCertInfo(certDir string) ClientCertInfo { |
125 | 113 |
return ClientCertInfo{ |
126 | 114 |
CertLocation: configapi.CertInfo{ |
... | ... |
@@ -108,7 +108,6 @@ func GetMasterFileReferences(config *MasterConfig) []*string { |
108 | 108 |
refs = append(refs, &config.ServiceAccountConfig.PublicKeyFiles[i]) |
109 | 109 |
} |
110 | 110 |
|
111 |
- refs = append(refs, &config.MasterClients.DeployerKubeConfig) |
|
112 | 111 |
refs = append(refs, &config.MasterClients.OpenShiftLoopbackKubeConfig) |
113 | 112 |
refs = append(refs, &config.MasterClients.ExternalKubernetesKubeConfig) |
114 | 113 |
|
... | ... |
@@ -224,8 +224,6 @@ type ServingInfo struct { |
224 | 224 |
} |
225 | 225 |
|
226 | 226 |
type MasterClients struct { |
227 |
- // DeployerKubeConfig is a .kubeconfig filename for depoyment pods to use |
|
228 |
- DeployerKubeConfig string |
|
229 | 227 |
// OpenShiftLoopbackKubeConfig is a .kubeconfig filename for system components to loopback to this master |
230 | 228 |
OpenShiftLoopbackKubeConfig string |
231 | 229 |
// ExternalKubernetesKubeConfig is a .kubeconfig filename for proxying to kubernetes |
... | ... |
@@ -213,8 +213,6 @@ type ServingInfo struct { |
213 | 213 |
} |
214 | 214 |
|
215 | 215 |
type MasterClients struct { |
216 |
- // DeployerKubeConfig is a .kubeconfig filename for depoyment pods to use |
|
217 |
- DeployerKubeConfig string `json:"deployerKubeConfig"` |
|
218 | 216 |
// OpenShiftLoopbackKubeConfig is a .kubeconfig filename for system components to loopback to this master |
219 | 217 |
OpenShiftLoopbackKubeConfig string `json:"openshiftLoopbackKubeConfig"` |
220 | 218 |
// ExternalKubernetesKubeConfig is a .kubeconfig filename for proxying to kubernetes |
... | ... |
@@ -113,7 +113,6 @@ func ValidateMasterConfig(config *api.MasterConfig) ValidationResults { |
113 | 113 |
validationResults.AddErrors(fielderrors.NewFieldInvalid("kubernetesMasterConfig", config.KubernetesMasterConfig, "kubernetesMasterConfig and masterClients.externalKubernetesKubeConfig are mutually exclusive")) |
114 | 114 |
} |
115 | 115 |
|
116 |
- validationResults.AddErrors(ValidateKubeConfig(config.MasterClients.DeployerKubeConfig, "deployerKubeConfig").Prefix("masterClients")...) |
|
117 | 116 |
validationResults.AddErrors(ValidateKubeConfig(config.MasterClients.OpenShiftLoopbackKubeConfig, "openShiftLoopbackKubeConfig").Prefix("masterClients")...) |
118 | 117 |
|
119 | 118 |
if len(config.MasterClients.ExternalKubernetesKubeConfig) > 0 { |
... | ... |
@@ -125,7 +124,7 @@ func ValidateMasterConfig(config *api.MasterConfig) ValidationResults { |
125 | 125 |
validationResults.AddErrors(ValidateOAuthConfig(config.OAuthConfig).Prefix("oauthConfig")...) |
126 | 126 |
} |
127 | 127 |
|
128 |
- validationResults.AddErrors(ValidateServiceAccountConfig(config.ServiceAccountConfig, builtInKubernetes).Prefix("serviceAccountConfig")...) |
|
128 |
+ validationResults.Append(ValidateServiceAccountConfig(config.ServiceAccountConfig, builtInKubernetes).Prefix("serviceAccountConfig")) |
|
129 | 129 |
|
130 | 130 |
validationResults.AddErrors(ValidateServingInfo(config.ServingInfo).Prefix("servingInfo")...) |
131 | 131 |
|
... | ... |
@@ -177,47 +176,50 @@ func ValidateEtcdStorageConfig(config api.EtcdStorageConfig) fielderrors.Validat |
177 | 177 |
return allErrs |
178 | 178 |
} |
179 | 179 |
|
180 |
-func ValidateServiceAccountConfig(config api.ServiceAccountConfig, builtInKubernetes bool) fielderrors.ValidationErrorList { |
|
181 |
- allErrs := fielderrors.ValidationErrorList{} |
|
180 |
+func ValidateServiceAccountConfig(config api.ServiceAccountConfig, builtInKubernetes bool) ValidationResults { |
|
181 |
+ validationResults := ValidationResults{} |
|
182 | 182 |
|
183 | 183 |
managedNames := util.NewStringSet(config.ManagedNames...) |
184 | 184 |
if !managedNames.Has(bootstrappolicy.BuilderServiceAccountName) { |
185 |
- // TODO: warn that default builder service account won't be auto-created |
|
185 |
+ validationResults.AddWarnings(fielderrors.NewFieldInvalid("managedNames", "", fmt.Sprintf("missing %q, which will require manual creation in each namespace before builds can run", bootstrappolicy.BuilderServiceAccountName))) |
|
186 |
+ } |
|
187 |
+ if !managedNames.Has(bootstrappolicy.DeployerServiceAccountName) { |
|
188 |
+ validationResults.AddWarnings(fielderrors.NewFieldInvalid("managedNames", "", fmt.Sprintf("missing %q, which will require manual creation in each namespace before deployments can run", bootstrappolicy.DeployerServiceAccountName))) |
|
186 | 189 |
} |
187 | 190 |
if builtInKubernetes && !managedNames.Has(bootstrappolicy.DefaultServiceAccountName) { |
188 |
- // TODO: warn that default service account won't be auto-created |
|
191 |
+ validationResults.AddWarnings(fielderrors.NewFieldInvalid("managedNames", "", fmt.Sprintf("missing %q, which will prevent creation of pods that do not specify a valid service account", bootstrappolicy.DefaultServiceAccountName))) |
|
189 | 192 |
} |
190 | 193 |
|
191 | 194 |
for i, name := range config.ManagedNames { |
192 | 195 |
if ok, msg := kvalidation.ValidateServiceAccountName(name, false); !ok { |
193 |
- allErrs = append(allErrs, fielderrors.NewFieldInvalid(fmt.Sprintf("", i), name, msg)) |
|
196 |
+ validationResults.AddErrors(fielderrors.NewFieldInvalid(fmt.Sprintf("managedNames[%d]", i), name, msg)) |
|
194 | 197 |
} |
195 | 198 |
} |
196 | 199 |
|
197 | 200 |
if len(config.PrivateKeyFile) > 0 { |
198 | 201 |
if fileErrs := ValidateFile(config.PrivateKeyFile, "privateKeyFile"); len(fileErrs) > 0 { |
199 |
- allErrs = append(allErrs, fileErrs...) |
|
202 |
+ validationResults.AddErrors(fileErrs...) |
|
200 | 203 |
} else if privateKey, err := serviceaccount.ReadPrivateKey(config.PrivateKeyFile); err != nil { |
201 |
- allErrs = append(allErrs, fielderrors.NewFieldInvalid("privateKeyFile", config.PrivateKeyFile, err.Error())) |
|
204 |
+ validationResults.AddErrors(fielderrors.NewFieldInvalid("privateKeyFile", config.PrivateKeyFile, err.Error())) |
|
202 | 205 |
} else if err := privateKey.Validate(); err != nil { |
203 |
- allErrs = append(allErrs, fielderrors.NewFieldInvalid("privateKeyFile", config.PrivateKeyFile, err.Error())) |
|
206 |
+ validationResults.AddErrors(fielderrors.NewFieldInvalid("privateKeyFile", config.PrivateKeyFile, err.Error())) |
|
204 | 207 |
} |
205 | 208 |
} else if builtInKubernetes { |
206 |
- // TODO: warn that no service account tokens will be generated |
|
209 |
+ validationResults.AddWarnings(fielderrors.NewFieldInvalid("privateKeyFile", "", "no service account tokens will be generated, which could prevent builds and deployments from working")) |
|
207 | 210 |
} |
208 | 211 |
|
209 | 212 |
if len(config.PublicKeyFiles) == 0 { |
210 |
- // TODO: warn that no service accounts will be able to authenticate |
|
213 |
+ validationResults.AddWarnings(fielderrors.NewFieldInvalid("publicKeyFiles", "", "no service account tokens will be accepted by the API, which will prevent builds and deployments from working")) |
|
211 | 214 |
} |
212 | 215 |
for i, publicKeyFile := range config.PublicKeyFiles { |
213 | 216 |
if fileErrs := ValidateFile(publicKeyFile, fmt.Sprintf("publicKeyFiles[%d]", i)); len(fileErrs) > 0 { |
214 |
- allErrs = append(allErrs, fileErrs...) |
|
217 |
+ validationResults.AddErrors(fileErrs...) |
|
215 | 218 |
} else if _, err := serviceaccount.ReadPublicKey(publicKeyFile); err != nil { |
216 |
- allErrs = append(allErrs, fielderrors.NewFieldInvalid(fmt.Sprintf("publicKeyFiles[%d]", i), publicKeyFile, err.Error())) |
|
219 |
+ validationResults.AddErrors(fielderrors.NewFieldInvalid(fmt.Sprintf("publicKeyFiles[%d]", i), publicKeyFile, err.Error())) |
|
217 | 220 |
} |
218 | 221 |
} |
219 | 222 |
|
220 |
- return allErrs |
|
223 |
+ return validationResults |
|
221 | 224 |
} |
222 | 225 |
|
223 | 226 |
func ValidateAssetConfig(config *api.AssetConfig) fielderrors.ValidationErrorList { |
... | ... |
@@ -7,8 +7,9 @@ const ( |
7 | 7 |
|
8 | 8 |
// users |
9 | 9 |
const ( |
10 |
- DefaultServiceAccountName = "default" |
|
11 |
- BuilderServiceAccountName = "builder" |
|
10 |
+ DefaultServiceAccountName = "default" |
|
11 |
+ BuilderServiceAccountName = "builder" |
|
12 |
+ DeployerServiceAccountName = "deployer" |
|
12 | 13 |
|
13 | 14 |
RouterUnqualifiedUsername = "openshift-router" |
14 | 15 |
RegistryUnqualifiedUsername = "openshift-registry" |
... | ... |
@@ -21,7 +22,6 @@ const ( |
21 | 21 |
const ( |
22 | 22 |
UnauthenticatedUsername = "system:anonymous" |
23 | 23 |
InternalComponentUsername = "system:openshift-client" |
24 |
- DeployerUsername = "system:openshift-deployer" |
|
25 | 24 |
|
26 | 25 |
AuthenticatedGroup = "system:authenticated" |
27 | 26 |
UnauthenticatedGroup = "system:unauthenticated" |
... | ... |
@@ -413,15 +413,6 @@ func GetBootstrapClusterRoleBindings() []authorizationapi.ClusterRoleBinding { |
413 | 413 |
}, |
414 | 414 |
{ |
415 | 415 |
ObjectMeta: kapi.ObjectMeta{ |
416 |
- Name: DeployerRoleBindingName, |
|
417 |
- }, |
|
418 |
- RoleRef: kapi.ObjectReference{ |
|
419 |
- Name: DeployerRoleName, |
|
420 |
- }, |
|
421 |
- Users: util.NewStringSet(DeployerUsername), |
|
422 |
- }, |
|
423 |
- { |
|
424 |
- ObjectMeta: kapi.ObjectMeta{ |
|
425 | 416 |
Name: ClusterAdminRoleBindingName, |
426 | 417 |
}, |
427 | 418 |
RoleRef: kapi.ObjectReference{ |
... | ... |
@@ -30,5 +30,15 @@ func GetBootstrapServiceAccountProjectRoleBindings(namespace string) []authoriza |
30 | 30 |
}, |
31 | 31 |
Users: util.NewStringSet(serviceaccount.MakeUsername(namespace, BuilderServiceAccountName)), |
32 | 32 |
}, |
33 |
+ { |
|
34 |
+ ObjectMeta: kapi.ObjectMeta{ |
|
35 |
+ Name: DeployerRoleBindingName, |
|
36 |
+ Namespace: namespace, |
|
37 |
+ }, |
|
38 |
+ RoleRef: kapi.ObjectReference{ |
|
39 |
+ Name: DeployerRoleName, |
|
40 |
+ }, |
|
41 |
+ Users: util.NewStringSet(serviceaccount.MakeUsername(namespace, DeployerServiceAccountName)), |
|
42 |
+ }, |
|
33 | 43 |
} |
34 | 44 |
} |
... | ... |
@@ -59,7 +59,6 @@ func BuildKubernetesMasterConfig(options configapi.MasterConfig, requestContextM |
59 | 59 |
|
60 | 60 |
// in-order list of plug-ins that should intercept admission decisions |
61 | 61 |
// TODO: Push node environment support to upstream in future |
62 |
- // TODO: JTL: update serviceaccount admission plugin to limit secrets to the ones held by the serviceaccount |
|
63 | 62 |
admissionControlPluginNames := []string{"NamespaceExists", "NamespaceLifecycle", "OriginPodNodeEnvironment", "LimitRanger", "ServiceAccount", "ResourceQuota"} |
64 | 63 |
admissionController := admission.NewFromPlugins(kubeClient, admissionControlPluginNames, "") |
65 | 64 |
|
... | ... |
@@ -10,6 +10,7 @@ import ( |
10 | 10 |
"net" |
11 | 11 |
"net/http" |
12 | 12 |
"os" |
13 |
+ "path" |
|
13 | 14 |
"regexp" |
14 | 15 |
"strings" |
15 | 16 |
"time" |
... | ... |
@@ -33,6 +34,7 @@ import ( |
33 | 33 |
etcdallocator "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/allocator/etcd" |
34 | 34 |
"github.com/GoogleCloudPlatform/kubernetes/pkg/serviceaccount" |
35 | 35 |
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" |
36 |
+ serviceaccountadmission "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/serviceaccount" |
|
36 | 37 |
|
37 | 38 |
"github.com/openshift/origin/pkg/api/latest" |
38 | 39 |
"github.com/openshift/origin/pkg/api/v1" |
... | ... |
@@ -984,18 +986,20 @@ func (c *MasterConfig) RunDeploymentController() error { |
984 | 984 |
if err != nil { |
985 | 985 |
return err |
986 | 986 |
} |
987 |
- // TODO eliminate these environment variables once we figure out what they do |
|
988 |
- env := []api.EnvVar{ |
|
989 |
- {Name: "KUBERNETES_MASTER", Value: kclientConfig.Host}, |
|
990 |
- {Name: "OPENSHIFT_MASTER", Value: kclientConfig.Host}, |
|
991 |
- } |
|
992 |
- env = append(env, clientcmd.EnvVarsFromConfig(c.DeployerClientConfig())...) |
|
987 |
+ // TODO eliminate these environment variables once service accounts provide a kubeconfig that includes all of this info |
|
988 |
+ env := clientcmd.EnvVars( |
|
989 |
+ kclientConfig.Host, |
|
990 |
+ kclientConfig.CAData, |
|
991 |
+ kclientConfig.Insecure, |
|
992 |
+ path.Join(serviceaccountadmission.DefaultAPITokenMountPath, kapi.ServiceAccountTokenKey), |
|
993 |
+ ) |
|
993 | 994 |
|
994 | 995 |
factory := deploycontroller.DeploymentControllerFactory{ |
995 |
- KubeClient: kclient, |
|
996 |
- Codec: latest.Codec, |
|
997 |
- Environment: env, |
|
998 |
- DeployerImage: c.ImageFor("deployer"), |
|
996 |
+ KubeClient: kclient, |
|
997 |
+ Codec: latest.Codec, |
|
998 |
+ Environment: env, |
|
999 |
+ DeployerImage: c.ImageFor("deployer"), |
|
1000 |
+ ServiceAccount: bootstrappolicy.DeployerServiceAccountName, |
|
999 | 1001 |
} |
1000 | 1002 |
|
1001 | 1003 |
controller := factory.Create() |
... | ... |
@@ -87,8 +87,6 @@ type MasterConfig struct { |
87 | 87 |
// PrivilegedLoopbackClientConfig is the client configuration used to call OpenShift APIs from system components |
88 | 88 |
// To apply different access control to a system component, create a client config specifically for that component. |
89 | 89 |
PrivilegedLoopbackClientConfig kclient.Config |
90 |
- // DeployerPrivilegedLoopbackClientConfig is the client configuration used to call OpenShift APIs from launched deployer pods |
|
91 |
- DeployerOSClientConfig kclient.Config |
|
92 | 90 |
|
93 | 91 |
// kubeClient is the client used to call Kubernetes APIs from system components, built from KubeClientConfig. |
94 | 92 |
// It should only be accessed via the *Client() helper methods. |
... | ... |
@@ -127,10 +125,6 @@ func BuildMasterConfig(options configapi.MasterConfig) (*MasterConfig, error) { |
127 | 127 |
if err != nil { |
128 | 128 |
return nil, err |
129 | 129 |
} |
130 |
- _, deployerOSClientConfig, err := configapi.GetOpenShiftClient(options.MasterClients.DeployerKubeConfig) |
|
131 |
- if err != nil { |
|
132 |
- return nil, err |
|
133 |
- } |
|
134 | 130 |
|
135 | 131 |
imageTemplate := variable.NewDefaultImageTemplate() |
136 | 132 |
imageTemplate.Format = options.ImageConfig.Format |
... | ... |
@@ -173,7 +167,6 @@ func BuildMasterConfig(options configapi.MasterConfig) (*MasterConfig, error) { |
173 | 173 |
ClientCAs: clientCAs, |
174 | 174 |
APIClientCAs: apiClientCAs, |
175 | 175 |
|
176 |
- DeployerOSClientConfig: *deployerOSClientConfig, |
|
177 | 176 |
PrivilegedLoopbackClientConfig: *privilegedLoopbackClientConfig, |
178 | 177 |
PrivilegedLoopbackOpenShiftClient: privilegedLoopbackOpenShiftClient, |
179 | 178 |
PrivilegedLoopbackKubernetesClient: privilegedLoopbackKubeClient, |
... | ... |
@@ -362,12 +355,6 @@ func (c *MasterConfig) DeploymentControllerClients() (*osclient.Client, *kclient |
362 | 362 |
return c.PrivilegedLoopbackOpenShiftClient, c.PrivilegedLoopbackKubernetesClient |
363 | 363 |
} |
364 | 364 |
|
365 |
-// DeployerClientConfig returns the client configuration a Deployer instance launched in a pod |
|
366 |
-// should use when making API calls. |
|
367 |
-func (c *MasterConfig) DeployerClientConfig() *kclient.Config { |
|
368 |
- return &c.DeployerOSClientConfig |
|
369 |
-} |
|
370 |
- |
|
371 | 365 |
func (c *MasterConfig) DeploymentConfigControllerClients() (*osclient.Client, *kclient.Client) { |
372 | 366 |
return c.PrivilegedLoopbackOpenShiftClient, c.PrivilegedLoopbackKubernetesClient |
373 | 367 |
} |
... | ... |
@@ -173,7 +173,6 @@ func (args MasterArgs) BuildSerializeableMasterConfig() (*configapi.MasterConfig |
173 | 173 |
}, |
174 | 174 |
|
175 | 175 |
MasterClients: configapi.MasterClients{ |
176 |
- DeployerKubeConfig: admin.DefaultKubeConfigFilename(args.ConfigDir.Value(), "openshift-deployer"), |
|
177 | 176 |
OpenShiftLoopbackKubeConfig: admin.DefaultKubeConfigFilename(args.ConfigDir.Value(), "openshift-client"), |
178 | 177 |
ExternalKubernetesKubeConfig: args.KubeConnectionArgs.ClientConfigLoadingRules.ExplicitPath, |
179 | 178 |
}, |
... | ... |
@@ -229,10 +228,11 @@ func (args MasterArgs) BuildSerializeableMasterConfig() (*configapi.MasterConfig |
229 | 229 |
} |
230 | 230 |
|
231 | 231 |
if builtInKubernetes { |
232 |
- // When we start Kubernetes, we're responsible for generating the default account |
|
232 |
+ // When we start Kubernetes, we're responsible for generating all the managed service accounts |
|
233 | 233 |
config.ServiceAccountConfig.ManagedNames = []string{ |
234 | 234 |
bootstrappolicy.DefaultServiceAccountName, |
235 | 235 |
bootstrappolicy.BuilderServiceAccountName, |
236 |
+ bootstrappolicy.DeployerServiceAccountName, |
|
236 | 237 |
} |
237 | 238 |
// We also need the private key file to give to the token generator |
238 | 239 |
config.ServiceAccountConfig.PrivateKeyFile = admin.DefaultServiceAccountPrivateKeyFile(args.ConfigDir.Value()) |
... | ... |
@@ -241,11 +241,12 @@ func (args MasterArgs) BuildSerializeableMasterConfig() (*configapi.MasterConfig |
241 | 241 |
admin.DefaultServiceAccountPublicKeyFile(args.ConfigDir.Value()), |
242 | 242 |
} |
243 | 243 |
} else { |
244 |
- // When running against an external Kubernetes, we're only responsible for the builder account. |
|
244 |
+ // When running against an external Kubernetes, we're only responsible for the builder and deployer accounts. |
|
245 | 245 |
// We don't have the private key, but we need to get the public key to authenticate signed tokens. |
246 | 246 |
// TODO: JTL: take arg for public key(s)? |
247 | 247 |
config.ServiceAccountConfig.ManagedNames = []string{ |
248 | 248 |
bootstrappolicy.BuilderServiceAccountName, |
249 |
+ bootstrappolicy.DeployerServiceAccountName, |
|
249 | 250 |
} |
250 | 251 |
config.ServiceAccountConfig.PublicKeyFiles = []string{} |
251 | 252 |
} |
... | ... |
@@ -48,17 +48,23 @@ func (cfg *Config) Bind(flags *pflag.FlagSet) { |
48 | 48 |
BindClientConfigSecurityFlags(&cfg.CommonConfig, flags) |
49 | 49 |
} |
50 | 50 |
|
51 |
-func EnvVarsFromConfig(config *kclient.Config) []api.EnvVar { |
|
52 |
- insecure := "false" |
|
53 |
- if config.Insecure { |
|
54 |
- insecure = "true" |
|
51 |
+func EnvVars(host string, caData []byte, insecure bool, bearerTokenFile string) []api.EnvVar { |
|
52 |
+ envvars := []api.EnvVar{ |
|
53 |
+ {Name: "KUBERNETES_MASTER", Value: host}, |
|
54 |
+ {Name: "OPENSHIFT_MASTER", Value: host}, |
|
55 | 55 |
} |
56 |
- return []api.EnvVar{ |
|
57 |
- {Name: "OPENSHIFT_CA_DATA", Value: string(config.CAData)}, |
|
58 |
- {Name: "OPENSHIFT_CERT_DATA", Value: string(config.CertData)}, |
|
59 |
- {Name: "OPENSHIFT_KEY_DATA", Value: string(config.KeyData)}, |
|
60 |
- {Name: "OPENSHIFT_INSECURE", Value: insecure}, |
|
56 |
+ |
|
57 |
+ if len(bearerTokenFile) > 0 { |
|
58 |
+ envvars = append(envvars, api.EnvVar{Name: "BEARER_TOKEN_FILE", Value: bearerTokenFile}) |
|
59 |
+ } |
|
60 |
+ |
|
61 |
+ if len(caData) > 0 { |
|
62 |
+ envvars = append(envvars, api.EnvVar{Name: "OPENSHIFT_CA_DATA", Value: string(caData)}) |
|
63 |
+ } else if insecure { |
|
64 |
+ envvars = append(envvars, api.EnvVar{Name: "OPENSHIFT_INSECURE", Value: "true"}) |
|
61 | 65 |
} |
66 |
+ |
|
67 |
+ return envvars |
|
62 | 68 |
} |
63 | 69 |
|
64 | 70 |
func (cfg *Config) bindEnv() error { |
... | ... |
@@ -25,6 +25,8 @@ import ( |
25 | 25 |
// |
26 | 26 |
// Use the DeploymentControllerFactory to create this controller. |
27 | 27 |
type DeploymentController struct { |
28 |
+ // serviceAccount to create deployment pods with |
|
29 |
+ serviceAccount string |
|
28 | 30 |
// deploymentClient provides access to deployments. |
29 | 31 |
deploymentClient deploymentClient |
30 | 32 |
// podClient provides access to pods. |
... | ... |
@@ -210,6 +212,7 @@ func (c *DeploymentController) makeDeployerPod(deployment *kapi.ReplicationContr |
210 | 210 |
}, |
211 | 211 |
ActiveDeadlineSeconds: &maxDeploymentDurationSeconds, |
212 | 212 |
RestartPolicy: kapi.RestartPolicyNever, |
213 |
+ ServiceAccount: c.serviceAccount, |
|
213 | 214 |
}, |
214 | 215 |
} |
215 | 216 |
|
... | ... |
@@ -26,6 +26,8 @@ type DeploymentControllerFactory struct { |
26 | 26 |
KubeClient kclient.Interface |
27 | 27 |
// Codec is used for encoding/decoding. |
28 | 28 |
Codec runtime.Codec |
29 |
+ // ServiceAccount is the service account name to run deployer pods as |
|
30 |
+ ServiceAccount string |
|
29 | 31 |
// Environment is a set of environment which should be injected into all deployer pod containers. |
30 | 32 |
Environment []kapi.EnvVar |
31 | 33 |
// DeployerImage specifies which Docker image can support the default strategies. |
... | ... |
@@ -51,6 +53,7 @@ func (factory *DeploymentControllerFactory) Create() controller.RunnableControll |
51 | 51 |
eventBroadcaster.StartRecordingToSink(factory.KubeClient.Events("")) |
52 | 52 |
|
53 | 53 |
deployController := &DeploymentController{ |
54 |
+ serviceAccount: factory.ServiceAccount, |
|
54 | 55 |
deploymentClient: &deploymentClientImpl{ |
55 | 56 |
getDeploymentFunc: func(namespace, name string) (*kapi.ReplicationController, error) { |
56 | 57 |
return factory.KubeClient.ReplicationControllers(namespace).Get(name) |