Skip to content

Commit

Permalink
Improvement in the kubeconfigwriter and in Resource struct
Browse files Browse the repository at this point in the history
Kubeconfigwriter needs to be improved to replace pipeline resource type "cluster" with the kubeconfig-creator task.
In order to do that, some extra configurations(e.g. client-key-data, client-certificate-data) needs to be added in the
Resource struct with some changes in the kubeconfigwriter implementation.

Ref: [tektoncd/catalog#95], [tektoncd/catalog#251]

Signed-off-by: Divyansh42 <[email protected]>
  • Loading branch information
divyansh42 committed Apr 9, 2020
1 parent fedf61a commit 7cf18c4
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 14 deletions.
21 changes: 18 additions & 3 deletions cmd/kubeconfigwriter/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (

var (
clusterConfig = flag.String("clusterConfig", "", "json string with the configuration of a cluster based on values from a cluster resource. Only required for external clusters.")
destinationDir = flag.String("destinationDir", "", "destination directory where generated kubeconfig file will be stored.")
)

func main() {
Expand All @@ -48,10 +49,10 @@ func main() {
if err != nil {
logger.Fatalf("Error reading cluster config: %v", err)
}
createKubeconfigFile(&cr, logger)
createKubeconfigFile(&cr, logger, destinationDir)
}

func createKubeconfigFile(resource *cluster.Resource, logger *zap.SugaredLogger) {
func createKubeconfigFile(resource *cluster.Resource, logger *zap.SugaredLogger, destinationDir *string) {
cluster := &clientcmdapi.Cluster{
Server: resource.URL,
InsecureSkipTLSVerify: resource.Insecure,
Expand All @@ -72,6 +73,8 @@ func createKubeconfigFile(resource *cluster.Resource, logger *zap.SugaredLogger)
//only one authentication technique per user is allowed in a kubeconfig, so clear out the password if a token is provided
user := resource.Username
pass := resource.Password
clientKeyData := resource.ClientKeyData
clientCertificateData := resource.ClientCertificateData
if resource.Token != "" {
user = ""
pass = ""
Expand All @@ -80,6 +83,8 @@ func createKubeconfigFile(resource *cluster.Resource, logger *zap.SugaredLogger)
Token: resource.Token,
Username: user,
Password: pass,
ClientKeyData: clientKeyData,
ClientCertificateData: clientCertificateData,
}
context := &clientcmdapi.Context{
Cluster: resource.Name,
Expand All @@ -95,7 +100,17 @@ func createKubeconfigFile(resource *cluster.Resource, logger *zap.SugaredLogger)
c.APIVersion = "v1"
c.Kind = "Config"

destinationFile := fmt.Sprintf("/workspace/%s/kubeconfig", resource.Name)
// kubeconfig file location
var destinationFile string

// If the destination Directory is provided, kubeconfig will be written to the given directory.
// otherwise it will use default location i.e. "/workspace/<cluster-name>/
if *destinationDir != "" {
destinationFile = fmt.Sprintf("%s/kubeconfig", *destinationDir)
} else {
destinationFile = fmt.Sprintf("/workspace/%s/kubeconfig", resource.Name)
}

if err := clientcmd.WriteToFile(*c, destinationFile); err != nil {
logger.Fatalf("Error writing kubeconfig to file: %v", err)
}
Expand Down
6 changes: 6 additions & 0 deletions docs/resources.md
Original file line number Diff line number Diff line change
Expand Up @@ -610,11 +610,17 @@ The Cluster resource has the following parameters:
certificate.
- `cadata` (required): holds PEM-encoded bytes (typically read from a root
certificates bundle).
- `clientKeyData`: contains PEM-encoded data from a client key file
for TLS
- `clientCertificateData`: contains PEM-encoded data from a client cert file for TLS

Note: Since only one authentication technique is allowed per user, either a
`token` or a `password` should be provided, if both are provided, the `password`
will be ignored.

`ClientKeyData` and `ClientCertificateData` are only required if `token` or
`password` is not provided for authentication to cluster.

The following example shows the syntax and structure of a `cluster` resource:

```yaml
Expand Down
36 changes: 26 additions & 10 deletions pkg/apis/resource/v1alpha1/cluster/cluster_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ type Resource struct {
// CAData holds PEM-encoded bytes (typically read from a root certificates bundle).
// CAData takes precedence over CAFile
CAData []byte `json:"cadata"`
// ClientKeyData contains PEM-encoded data from a client key file for TLS.
ClientKeyData []byte `json:"clientKeyData"`
// ClientCertificateData contains PEM-encoded data from a client cert file for TLS.
ClientCertificateData []byte `json:"clientCertificateData"`
//Secrets holds a struct to indicate a field name and corresponding secret name to populate it
Secrets []resource.SecretParam `json:"secrets"`

Expand Down Expand Up @@ -88,6 +92,16 @@ func NewResource(kubeconfigWriterImage string, r *resource.PipelineResource) (*R
sDec, _ := b64.StdEncoding.DecodeString(param.Value)
clusterResource.CAData = sDec
}
case strings.EqualFold(param.Name, "ClientKeyData"):
if param.Value != "" {
sDec, _ := b64.StdEncoding.DecodeString(param.Value)
clusterResource.ClientKeyData = sDec
}
case strings.EqualFold(param.Name, "ClientCertificateData"):
if param.Value != "" {
sDec, _ := b64.StdEncoding.DecodeString(param.Value)
clusterResource.ClientCertificateData = sDec
}
}
}
clusterResource.Secrets = r.Spec.SecretParams
Expand Down Expand Up @@ -123,16 +137,18 @@ func (s *Resource) GetURL() string {
// Replacements is used for template replacement on a ClusterResource inside of a Taskrun.
func (s *Resource) Replacements() map[string]string {
return map[string]string{
"name": s.Name,
"type": s.Type,
"url": s.URL,
"revision": s.Revision,
"username": s.Username,
"password": s.Password,
"namespace": s.Namespace,
"token": s.Token,
"insecure": strconv.FormatBool(s.Insecure),
"cadata": string(s.CAData),
"name": s.Name,
"type": s.Type,
"url": s.URL,
"revision": s.Revision,
"username": s.Username,
"password": s.Password,
"namespace": s.Namespace,
"token": s.Token,
"insecure": strconv.FormatBool(s.Insecure),
"cadata": string(s.CAData),
"clientKeyData": string(s.ClientKeyData),
"clientCertificateData": string(s.ClientCertificateData),
}
}

Expand Down
22 changes: 21 additions & 1 deletion pkg/apis/resource/v1alpha1/cluster/cluster_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,26 @@ func TestNewClusterResource(t *testing.T) {
Password: "pass",
KubeconfigWriterImage: "override-with-kubeconfig-writer:latest",
},
},{
desc: "resource with clientKeyData and clientCertificateData instead of token or password",
resource: tb.PipelineResource("test-cluster-resource", "default", tb.PipelineResourceSpec(
resourcev1alpha1.PipelineResourceTypeCluster,
tb.PipelineResourceSpecParam("url", "http://10.10.10.10"),
tb.PipelineResourceSpecParam("username", "user"),
tb.PipelineResourceSpecParam("cadata", "bXktY2x1c3Rlci1jZXJ0Cg"),
tb.PipelineResourceSpecParam("clientKeyData", "Y2xpZW50LWtleS1kYXRh"),
tb.PipelineResourceSpecParam("clientCertificateData", "Y2xpZW50LWNlcnRpZmljYXRlLWRhdGE="),
)),
want: &cluster.Resource{
Name: "test-cluster-resource",
Type: resourcev1alpha1.PipelineResourceTypeCluster,
URL: "http://10.10.10.10",
Username: "user",
CAData: []byte("my-cluster-cert"),
ClientKeyData: []byte("client-key-data"),
ClientCertificateData: []byte("client-certificate-data"),
KubeconfigWriterImage: "override-with-kubeconfig-writer:latest",
},
}, {
desc: "set insecure flag to true when there is no cert",
resource: tb.PipelineResource("test-cluster-resource", "foo", tb.PipelineResourceSpec(
Expand Down Expand Up @@ -155,7 +175,7 @@ func TestClusterResource_GetInputTaskModifier(t *testing.T) {
Name: "kubeconfig-9l9zj",
Image: "override-with-kubeconfig-writer:latest",
Command: []string{"/ko-app/kubeconfigwriter"},
Args: []string{"-clusterConfig", `{"name":"test-cluster-resource","type":"cluster","url":"http://10.10.10.10","revision":"","username":"","password":"","namespace":"","token":"","Insecure":false,"cadata":null,"secrets":[{"fieldName":"cadata","secretKey":"cadatakey","secretName":"secret1"}]}`},
Args: []string{"-clusterConfig", `{"name":"test-cluster-resource","type":"cluster","url":"http://10.10.10.10","revision":"","username":"","password":"","namespace":"","token":"","Insecure":false,"cadata":null,"clientKeyData":null,"clientCertificateData":null,"secrets":[{"fieldName":"cadata","secretKey":"cadatakey","secretName":"secret1"}]}`},
Env: []corev1.EnvVar{{
Name: "CADATA",
ValueFrom: &corev1.EnvVarSource{
Expand Down

0 comments on commit 7cf18c4

Please sign in to comment.