Issue kube-scheduler cert in nodeup

This commit is contained in:
John Gardiner Myers 2020-06-08 23:09:56 -07:00
parent 10bb3cf334
commit b0694300df
6 changed files with 313 additions and 74 deletions

View File

@ -17,6 +17,7 @@ limitations under the License.
package model package model
import ( import (
"crypto/x509/pkix"
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
@ -27,7 +28,6 @@ import (
"k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/apis/kops/util" "k8s.io/kops/pkg/apis/kops/util"
"k8s.io/kops/pkg/apis/nodeup" "k8s.io/kops/pkg/apis/nodeup"
"k8s.io/kops/pkg/kubeconfig"
"k8s.io/kops/pkg/systemd" "k8s.io/kops/pkg/systemd"
"k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/nodeup/nodetasks" "k8s.io/kops/upup/pkg/fi/nodeup/nodetasks"
@ -193,6 +193,33 @@ func (c *NodeupModelContext) KubeletKubeConfig() string {
return "/var/lib/kubelet/kubeconfig" return "/var/lib/kubelet/kubeconfig"
} }
// BuildIssuedKubeconfig generates a kubeconfig with a locally issued client certificate.
func (c *NodeupModelContext) BuildIssuedKubeconfig(name string, subject pkix.Name, ctx *fi.ModelBuilderContext) *fi.TaskDependentResource {
issueCert := &nodetasks.IssueCert{
Name: name,
Signer: fi.CertificateIDCA,
Type: "client",
Subject: subject,
}
ctx.AddTask(issueCert)
certResource, keyResource, caResource := issueCert.GetResources()
kubeConfig := &nodetasks.KubeConfig{
Name: name,
Cert: certResource,
Key: keyResource,
CA: caResource,
}
if c.IsMaster {
// @note: use https even for local connections, so we can turn off the insecure port
kubeConfig.ServerURL = "https://127.0.0.1"
} else {
kubeConfig.ServerURL = "https://" + c.Cluster.Spec.MasterInternalName
}
ctx.AddTask(kubeConfig)
return kubeConfig.GetConfig()
}
// BuildPKIKubeconfig generates a kubeconfig // BuildPKIKubeconfig generates a kubeconfig
func (c *NodeupModelContext) BuildPKIKubeconfig(name string) (string, error) { func (c *NodeupModelContext) BuildPKIKubeconfig(name string) (string, error) {
ca, err := c.GetCert(fi.CertificateIDCA) ca, err := c.GetCert(fi.CertificateIDCA)
@ -215,54 +242,29 @@ func (c *NodeupModelContext) BuildPKIKubeconfig(name string) (string, error) {
// BuildKubeConfig is responsible for building a kubeconfig // BuildKubeConfig is responsible for building a kubeconfig
func (c *NodeupModelContext) BuildKubeConfig(username string, ca, certificate, privateKey []byte) (string, error) { func (c *NodeupModelContext) BuildKubeConfig(username string, ca, certificate, privateKey []byte) (string, error) {
user := kubeconfig.KubectlUser{ kubeConfig := &nodetasks.KubeConfig{
ClientCertificateData: certificate, Name: username,
ClientKeyData: privateKey, Cert: fi.NewBytesResource(certificate),
Key: fi.NewBytesResource(privateKey),
CA: fi.NewBytesResource(ca),
} }
cluster := kubeconfig.KubectlCluster{
CertificateAuthorityData: ca,
}
if c.IsMaster { if c.IsMaster {
// @note: use https even for local connections, so we can turn off the insecure port // @note: use https even for local connections, so we can turn off the insecure port
cluster.Server = "https://127.0.0.1" kubeConfig.ServerURL = "https://127.0.0.1"
} else { } else {
cluster.Server = "https://" + c.Cluster.Spec.MasterInternalName kubeConfig.ServerURL = "https://" + c.Cluster.Spec.MasterInternalName
} }
config := &kubeconfig.KubectlConfig{ err := kubeConfig.Run(nil)
ApiVersion: "v1",
Kind: "Config",
Users: []*kubeconfig.KubectlUserWithName{
{
Name: username,
User: user,
},
},
Clusters: []*kubeconfig.KubectlClusterWithName{
{
Name: "local",
Cluster: cluster,
},
},
Contexts: []*kubeconfig.KubectlContextWithName{
{
Name: "service-account-context",
Context: kubeconfig.KubectlContext{
Cluster: "local",
User: username,
},
},
},
CurrentContext: "service-account-context",
}
yaml, err := kops.ToRawYaml(config)
if err != nil { if err != nil {
return "", fmt.Errorf("error marshaling kubeconfig to yaml: %v", err) return "", err
} }
return string(yaml), nil config, err := fi.ResourceAsString(kubeConfig.GetConfig())
if err != nil {
return "", err
}
return config, nil
} }
// IsKubernetesGTE checks if the version is greater-than-or-equal // IsKubernetesGTE checks if the version is greater-than-or-equal

View File

@ -17,6 +17,7 @@ limitations under the License.
package model package model
import ( import (
"crypto/x509/pkix"
"fmt" "fmt"
"strconv" "strconv"
@ -24,6 +25,7 @@ import (
"k8s.io/kops/pkg/flagbuilder" "k8s.io/kops/pkg/flagbuilder"
"k8s.io/kops/pkg/k8scodecs" "k8s.io/kops/pkg/k8scodecs"
"k8s.io/kops/pkg/kubemanifest" "k8s.io/kops/pkg/kubemanifest"
"k8s.io/kops/pkg/rbac"
"k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/nodeup/nodetasks" "k8s.io/kops/upup/pkg/fi/nodeup/nodetasks"
"k8s.io/kops/util/pkg/exec" "k8s.io/kops/util/pkg/exec"
@ -83,14 +85,11 @@ func (b *KubeSchedulerBuilder) Build(c *fi.ModelBuilderContext) error {
} }
{ {
kubeconfig, err := b.BuildPKIKubeconfig("kube-scheduler") kubeconfig := b.BuildIssuedKubeconfig("kube-scheduler", pkix.Name{CommonName: rbac.KubeScheduler}, c)
if err != nil {
return err
}
c.AddTask(&nodetasks.File{ c.AddTask(&nodetasks.File{
Path: "/var/lib/kube-scheduler/kubeconfig", Path: "/var/lib/kube-scheduler/kubeconfig",
Contents: fi.NewStringResource(kubeconfig), Contents: kubeconfig,
Type: nodetasks.FileType_File, Type: nodetasks.FileType_File,
Mode: s("0400"), Mode: s("0400"),
}) })

View File

@ -63,25 +63,65 @@ mode: "0400"
path: /var/lib/kube-scheduler/config.yaml path: /var/lib/kube-scheduler/config.yaml
type: file type: file
--- ---
contents: | contents:
apiVersion: v1 Resource: null
clusters: Task:
- cluster: CA:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMyRENDQWNDZ0F3SUJBZ0lSQUxKWEFrVmo5NjR0cTY3d01TSThvSlF3RFFZSktvWklodmNOQVFFTEJRQXcKRlRFVE1CRUdBMVVFQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB4TnpFeU1qY3lNelV5TkRCYUZ3MHlOekV5TWpjeQpNelV5TkRCYU1CVXhFekFSQmdOVkJBTVRDbXQxWW1WeWJtVjBaWE13Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBCkE0SUJEd0F3Z2dFS0FvSUJBUURnbkNrU210bm1meEVnUzNxTlBhVUNINVFPQkdESC9pbkhiV0NPRExCQ0s5Z2QKWEVjQmw3RlZ2OFQya0ZyMURZYjBIVkR0TUk3dGl4UlZGRExna3dObFczNHh3V2RaWEI3R2VvRmdVMXhXT1FTWQpPQUNDOEpnWVRRLzEzOUhCRXZncTRzZWo2N3ArL3MvU05jdzM0S2s3SEl1RmhsazFyUms1a01leEtJbEpCS1AxCllZVVlldHNKL1FwVU9rcUo1SFc0R29ldEU3Nll0SG5PUmZZdm55YnZpU01yaDJ3R0dhTjZyL3M0Q2hPYUliWkMKQW44L1lpUEtHSURhWkdwajZHWG5tWEFSUlgvVElkZ1NRa0x3dDBhVERCblBaNFh2dHBJOGFhTDhEWUpJcUF6QQpOUEgyYjQvdU55bGF0NWpEbzBiMEc1NGFnTWk5NysyQVVyQzlVVVhwQWdNQkFBR2pJekFoTUE0R0ExVWREd0VCCi93UUVBd0lCQmpBUEJnTlZIUk1CQWY4RUJUQURBUUgvTUEwR0NTcUdTSWIzRFFFQkN3VUFBNElCQVFCVkdSMnIKaHpYelJNVTV3cmlQUUFKU2Nzek5PUnZvQnBYZlpvWjA5Rkl1cHVkRnhCVlUzZDRoVjlTdEtuUWdQU0dBNVhRTwpIRTk3K0J4SkR1QS9yQjVvQlVzTUJqYzd5MWNkZS9UNmhtaTNyTG9FWUJTblN1ZENPWEpFNEc5LzBmOGJ5QUplCnJOOCtObzFyMlZnWnZaaDZwNzRURWtYdi9sM0hCUFdNN0lkVVYwSE85SkRoU2dPVkYxZnlRS0p4UnVMSlI4anQKTzZtUEgyVVgwdk13VmE0anZ3dGtkZHFrMk9BZFlRdkg5cmJEampiemFpVzBLbm1kdWVSbzkyS0hBTjdCc0RaeQpWcFhIcHFvMUt6ZzdEM2ZwYVhDZjVzaTdscXFyZEpWWEg0SkM3Mnp4c1BlaHFnaThlSXVxT0JraURXbVJ4QXhoCjh5R2VSeDlBYmtuSGg0SWEKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= Resource: null
server: https://127.0.0.1 Task:
name: local Name: kube-scheduler
contexts: signer: ca
- context: subject:
cluster: local CommonName: system:kube-scheduler
user: kube-scheduler Country: null
name: service-account-context ExtraNames: null
current-context: service-account-context Locality: null
kind: Config Names: null
users: Organization: null
- name: kube-scheduler OrganizationalUnit: null
user: PostalCode: null
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMyRENDQWNDZ0F3SUJBZ0lSQUxKWEFrVmo5NjR0cTY3d01TSThvSlF3RFFZSktvWklodmNOQVFFTEJRQXcKRlRFVE1CRUdBMVVFQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB4TnpFeU1qY3lNelV5TkRCYUZ3MHlOekV5TWpjeQpNelV5TkRCYU1CVXhFekFSQmdOVkJBTVRDbXQxWW1WeWJtVjBaWE13Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBCkE0SUJEd0F3Z2dFS0FvSUJBUURnbkNrU210bm1meEVnUzNxTlBhVUNINVFPQkdESC9pbkhiV0NPRExCQ0s5Z2QKWEVjQmw3RlZ2OFQya0ZyMURZYjBIVkR0TUk3dGl4UlZGRExna3dObFczNHh3V2RaWEI3R2VvRmdVMXhXT1FTWQpPQUNDOEpnWVRRLzEzOUhCRXZncTRzZWo2N3ArL3MvU05jdzM0S2s3SEl1RmhsazFyUms1a01leEtJbEpCS1AxCllZVVlldHNKL1FwVU9rcUo1SFc0R29ldEU3Nll0SG5PUmZZdm55YnZpU01yaDJ3R0dhTjZyL3M0Q2hPYUliWkMKQW44L1lpUEtHSURhWkdwajZHWG5tWEFSUlgvVElkZ1NRa0x3dDBhVERCblBaNFh2dHBJOGFhTDhEWUpJcUF6QQpOUEgyYjQvdU55bGF0NWpEbzBiMEc1NGFnTWk5NysyQVVyQzlVVVhwQWdNQkFBR2pJekFoTUE0R0ExVWREd0VCCi93UUVBd0lCQmpBUEJnTlZIUk1CQWY4RUJUQURBUUgvTUEwR0NTcUdTSWIzRFFFQkN3VUFBNElCQVFCVkdSMnIKaHpYelJNVTV3cmlQUUFKU2Nzek5PUnZvQnBYZlpvWjA5Rkl1cHVkRnhCVlUzZDRoVjlTdEtuUWdQU0dBNVhRTwpIRTk3K0J4SkR1QS9yQjVvQlVzTUJqYzd5MWNkZS9UNmhtaTNyTG9FWUJTblN1ZENPWEpFNEc5LzBmOGJ5QUplCnJOOCtObzFyMlZnWnZaaDZwNzRURWtYdi9sM0hCUFdNN0lkVVYwSE85SkRoU2dPVkYxZnlRS0p4UnVMSlI4anQKTzZtUEgyVVgwdk13VmE0anZ3dGtkZHFrMk9BZFlRdkg5cmJEampiemFpVzBLbm1kdWVSbzkyS0hBTjdCc0RaeQpWcFhIcHFvMUt6ZzdEM2ZwYVhDZjVzaTdscXFyZEpWWEg0SkM3Mnp4c1BlaHFnaThlSXVxT0JraURXbVJ4QXhoCjh5R2VSeDlBYmtuSGg0SWEKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= Province: null
client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBNEp3cEVwclo1bjhSSUV0NmpUMmxBaCtVRGdSZ3gvNHB4MjFnamd5d1FpdllIVnhICkFaZXhWYi9FOXBCYTlRMkc5QjFRN1RDTzdZc1VWUlF5NEpNRFpWdCtNY0ZuV1Z3ZXhucUJZRk5jVmprRW1EZ0EKZ3ZDWUdFMFA5ZC9Sd1JMNEt1TEhvK3U2ZnY3UDBqWE1OK0NwT3h5TGhZWlpOYTBaT1pESHNTaUpTUVNqOVdHRgpHSHJiQ2YwS1ZEcEtpZVIxdUJxSHJSTyttTFI1emtYMkw1OG03NGtqSzRkc0JobWplcS83T0FvVG1pRzJRZ0ovClAySWp5aGlBMm1ScVkraGw1NWx3RVVWLzB5SFlFa0pDOExkR2t3d1p6MmVGNzdhU1BHbWkvQTJDU0tnTXdEVHgKOW0rUDdqY3BXcmVZdzZORzlCdWVHb0RJdmUvdGdGS3d2VkZGNlFJREFRQUJBb0lCQUEwa3RqYVRmeXJBeHNUSQpCZXpiN1pyNU5CVzU1ZHZ1SUkyOTljZDZNSm8rckkvVFJZaHZVdjQ4a1k4SUZYcC9oeVVqemdlREx1bnhtSWY5Ci9aZ3NvaWM5T2w0NC9nNDVtTWR1aGNHWVB6QUFlQ2RjSjVPQjlyUjlWZkRDWHlqWUxsTjhIOGlVMDczNHRUcU0KMFYxM3RROXpkU3FrR1BaT0ljcS9rUi9weWxiT1phUU1lOTdCVGxzQW5PTVNNS0RnbmZ0WTQxMjJMcTNHWXkrdAp2cHIrYktWYVFad3ZrTG9TVTNyRUNDYUthZ2hnd0N5WDdqZnQ5YUVraGRKditLbHdic0dZNldFcnZ4T2FMV0hkCmN1TVFqR2FwWTFGYS80VUQwMG12ckEyNjBOeUtmenJwNitQNDZSclZNd0VZUkpNSVE4WUJBazZONkhoN2RjMEcKOFo2aTFtMENnWUVBOUhlQ0pSMFRTd2JJUTFiRFhVcnpwZnRIdWlkRzVCblNCdGF4L05EOXFJUGhSL0ZCVzVuagoyMm53TGM0OEtreWlybGZJVUxkMGFlNHFWWEpuN3dmWWN1WC9jSk1MRG1TVnRsTTVEem1pLzkxeFJpRmdJengxCkFzYkJ6YUZqSVNQMkhwU2dMK2U5RnRTWGFhcWVaVnJmbGl0VmhZS1VwSS9BS1YzMXFHSGYwNHNDZ1lFQTZ6VFYKOTlTYjQ5V2RsbnM1SWdzZm5YbDZUb1J0dEIxOGxmRUtjVmZqQU00ZnJua2swNkpwRkFaZVIrOUdHS1VYWkhxcwp6MnFjcGx3NGQvbW9DQzZwM3JZUEJNTFhzckdORVVGWnFCbGd6NzJRQTZCQnEzWDBDZzFCYzJaYks1Vkl6d2tnClNUMlNTdXg2Y2NST2ZnVUxtTjVaaUxPdGRVS05FWnBGRjNpM3F0c0NnWUFEVC9zN2RZRmxhdG9iejNrbU1uWEsKc2ZUdTJNbGxIZFJ5czBZR0h1N1E4YmlEdVFraHJKd2h4UFcwS1M4M2c0SlF5bSswYUVmemgzNmJXY2wrdTZSNwpLaEtqKzlvU2Y5cG5kZ2szNDVnSnozNVJiUEpZaCtFdUFITnZ6ZGdDQXZLNngxakVUV2VLZjZidGo1cEYxVTFpClE0UU5Jdy9RaXdJWGpXWmV1YlRHc1FLQmdRQ2JkdUx1MnJMbmx5eUFhSlpNOERsSFp5SDJnQVhiQlpweHFVOFQKdDltdGtKRFVTL0tSaUVvWUdGVjlDcVMwYVhyYXlWTXNEZlhZNkIvUy9VdVpqTzV1N0x0a2xEenFPZjFhS0czUQpkR1hQS2lia25xcUpZSCtiblVOanVZWU5lckVUVjU3bGlqTUdIdVNZQ2Y4dndMbjNveEJmRVJSWDYxTS9EVThaCndvcnovUUtCZ1FEQ1RKSTIramRYZzI2WHVZVW1NNFhYZm5vY2Z6QVhoWEJVTHQxbkVOY29nTmYxZmNwdEFWdHUKQkFpejQvSGlwUUtxb1dWVVlteGZnYmJMUktLTEswczBsT1dLYllkVmpoRW0vbTJaVTh3dFhUYWdOd2tJR295cQpZL0MxTG94NGYxUk9KbkNqYy9oZmNPamN4WDVNOEE4cGVlY0hXbFZ0VVBLVEpneFE3b01LY3c9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo= SerialNumber: ""
StreetAddress: null
type: client
Cert:
Resource: null
Task:
Name: kube-scheduler
signer: ca
subject:
CommonName: system:kube-scheduler
Country: null
ExtraNames: null
Locality: null
Names: null
Organization: null
OrganizationalUnit: null
PostalCode: null
Province: null
SerialNumber: ""
StreetAddress: null
type: client
Key:
Resource: null
Task:
Name: kube-scheduler
signer: ca
subject:
CommonName: system:kube-scheduler
Country: null
ExtraNames: null
Locality: null
Names: null
Organization: null
OrganizationalUnit: null
PostalCode: null
Province: null
SerialNumber: ""
StreetAddress: null
type: client
Name: kube-scheduler
ServerURL: https://127.0.0.1
mode: "0400" mode: "0400"
path: /var/lib/kube-scheduler/kubeconfig path: /var/lib/kube-scheduler/kubeconfig
type: file type: file
@ -91,3 +131,76 @@ ifNotExists: true
mode: "0400" mode: "0400"
path: /var/log/kube-scheduler.log path: /var/log/kube-scheduler.log
type: file type: file
---
Name: kube-scheduler
signer: ca
subject:
CommonName: system:kube-scheduler
Country: null
ExtraNames: null
Locality: null
Names: null
Organization: null
OrganizationalUnit: null
PostalCode: null
Province: null
SerialNumber: ""
StreetAddress: null
type: client
---
CA:
Resource: null
Task:
Name: kube-scheduler
signer: ca
subject:
CommonName: system:kube-scheduler
Country: null
ExtraNames: null
Locality: null
Names: null
Organization: null
OrganizationalUnit: null
PostalCode: null
Province: null
SerialNumber: ""
StreetAddress: null
type: client
Cert:
Resource: null
Task:
Name: kube-scheduler
signer: ca
subject:
CommonName: system:kube-scheduler
Country: null
ExtraNames: null
Locality: null
Names: null
Organization: null
OrganizationalUnit: null
PostalCode: null
Province: null
SerialNumber: ""
StreetAddress: null
type: client
Key:
Resource: null
Task:
Name: kube-scheduler
signer: ca
subject:
CommonName: system:kube-scheduler
Country: null
ExtraNames: null
Locality: null
Names: null
Organization: null
OrganizationalUnit: null
PostalCode: null
Province: null
SerialNumber: ""
StreetAddress: null
type: client
Name: kube-scheduler
ServerURL: https://127.0.0.1

View File

@ -72,16 +72,6 @@ func (b *PKIModelBuilder) Build(c *fi.ModelBuilderContext) error {
Signer: defaultCA, Signer: defaultCA,
}) })
} }
{
t := &fitasks.Keypair{
Name: fi.String("kube-scheduler"),
Lifecycle: b.Lifecycle,
Subject: "cn=" + rbac.KubeScheduler,
Type: "client",
Signer: defaultCA,
}
c.AddTask(t)
}
{ {
t := &fitasks.Keypair{ t := &fitasks.Keypair{

View File

@ -11,6 +11,7 @@ go_library(
"file.go", "file.go",
"group.go", "group.go",
"issue_cert.go", "issue_cert.go",
"kubeconfig.go",
"load_image.go", "load_image.go",
"package.go", "package.go",
"service.go", "service.go",
@ -20,7 +21,9 @@ go_library(
importpath = "k8s.io/kops/upup/pkg/fi/nodeup/nodetasks", importpath = "k8s.io/kops/upup/pkg/fi/nodeup/nodetasks",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"//pkg/apis/kops:go_default_library",
"//pkg/backoff:go_default_library", "//pkg/backoff:go_default_library",
"//pkg/kubeconfig:go_default_library",
"//pkg/pki:go_default_library", "//pkg/pki:go_default_library",
"//upup/pkg/fi:go_default_library", "//upup/pkg/fi:go_default_library",
"//upup/pkg/fi/nodeup/cloudinit:go_default_library", "//upup/pkg/fi/nodeup/cloudinit:go_default_library",

View File

@ -0,0 +1,132 @@
/*
Copyright 2020 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 nodetasks
import (
"fmt"
"k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/kubeconfig"
"k8s.io/kops/upup/pkg/fi"
)
type KubeConfig struct {
Name string
Cert fi.Resource
Key fi.Resource
CA fi.Resource
ServerURL string
config *fi.TaskDependentResource
}
var _ fi.Task = &KubeConfig{}
var _ fi.HasName = &KubeConfig{}
var _ fi.HasDependencies = &KubeConfig{}
func (k *KubeConfig) GetName() *string {
return &k.Name
}
// String returns a string representation, implementing the Stringer interface
func (k *KubeConfig) String() string {
return fmt.Sprintf("KubeConfig: %s", k.Name)
}
func (k *KubeConfig) GetDependencies(tasks map[string]fi.Task) []fi.Task {
var deps []fi.Task
if hasDep, ok := k.Cert.(fi.HasDependencies); ok {
deps = append(deps, hasDep.GetDependencies(tasks)...)
}
if hasDep, ok := k.Key.(fi.HasDependencies); ok {
deps = append(deps, hasDep.GetDependencies(tasks)...)
}
if hasDep, ok := k.CA.(fi.HasDependencies); ok {
deps = append(deps, hasDep.GetDependencies(tasks)...)
}
return deps
}
func (k *KubeConfig) GetConfig() *fi.TaskDependentResource {
if k.config == nil {
k.config = &fi.TaskDependentResource{Task: k}
}
return k.config
}
func (k *KubeConfig) Run(_ *fi.Context) error {
cert, err := fi.ResourceAsBytes(k.Cert)
if err != nil {
return err
}
key, err := fi.ResourceAsBytes(k.Key)
if err != nil {
return err
}
ca, err := fi.ResourceAsBytes(k.CA)
if err != nil {
return err
}
user := kubeconfig.KubectlUser{
ClientCertificateData: cert,
ClientKeyData: key,
}
cluster := kubeconfig.KubectlCluster{
CertificateAuthorityData: ca,
Server: k.ServerURL,
}
config := &kubeconfig.KubectlConfig{
ApiVersion: "v1",
Kind: "Config",
Users: []*kubeconfig.KubectlUserWithName{
{
Name: k.Name,
User: user,
},
},
Clusters: []*kubeconfig.KubectlClusterWithName{
{
Name: "local",
Cluster: cluster,
},
},
Contexts: []*kubeconfig.KubectlContextWithName{
{
Name: "service-account-context",
Context: kubeconfig.KubectlContext{
Cluster: "local",
User: k.Name,
},
},
},
CurrentContext: "service-account-context",
}
yaml, err := kops.ToRawYaml(config)
if err != nil {
return fmt.Errorf("error marshaling kubeconfig to yaml: %v", err)
}
output := k.GetConfig()
output.Resource = fi.NewBytesResource(yaml)
return nil
}