Skip to content

Commit

Permalink
Add new config struct for workload-identity-api service
Browse files Browse the repository at this point in the history
  • Loading branch information
strideynet committed Jan 8, 2025
1 parent 5eeb25c commit a42bdb9
Show file tree
Hide file tree
Showing 7 changed files with 246 additions and 0 deletions.
6 changes: 6 additions & 0 deletions lib/tbot/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,12 @@ func (o *ServiceConfigs) UnmarshalYAML(node *yaml.Node) error {
return trace.Wrap(err)
}
out = append(out, v)
case WorkloadIdentityAPIServiceType:
v := &WorkloadIdentityAPIService{}
if err := node.Decode(v); err != nil {
return trace.Wrap(err)
}
out = append(out, v)
default:
return trace.BadParameter("unrecognized service type (%s)", header.Type)
}
Expand Down
6 changes: 6 additions & 0 deletions lib/tbot/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,12 @@ func TestBotConfig_YAML(t *testing.T) {
Name: "my-workload-identity",
},
},
&WorkloadIdentityAPIService{
Listen: "tcp://127.0.0.1:123",
WorkloadIdentity: WorkloadIdentitySelector{
Name: "my-workload-identity",
},
},
},
},
},
Expand Down
78 changes: 78 additions & 0 deletions lib/tbot/config/service_workload_identity_api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Teleport
// Copyright (C) 2025 Gravitational, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

package config

import (
"github.com/gravitational/trace"
"gopkg.in/yaml.v3"

"github.com/gravitational/teleport/lib/tbot/spiffe/workloadattest"
)

const WorkloadIdentityAPIServiceType = "workload-identity-api"

var (
_ ServiceConfig = &WorkloadIdentityAPIService{}
)

// WorkloadIdentityAPIService is the configuration for the
// WorkloadIdentityAPIService
type WorkloadIdentityAPIService struct {
// Listen is the address on which the SPIFFE Workload API server should
// listen. This should either be prefixed with "unix://" or "tcp://".
Listen string `yaml:"listen"`
// Attestors is the configuration for the workload attestation process.
Attestors workloadattest.Config `yaml:"attestors"`
// WorkloadIdentity is the selector for the WorkloadIdentity resource that
// will be used to issue WICs.
WorkloadIdentity WorkloadIdentitySelector `yaml:"workload_identity"`
}

// CheckAndSetDefaults checks the SPIFFESVIDOutput values and sets any defaults.
func (o *WorkloadIdentityAPIService) CheckAndSetDefaults() error {
if o.Listen == "" {
return trace.BadParameter("listen: should not be empty")
}
if err := o.Attestors.CheckAndSetDefaults(); err != nil {
return trace.Wrap(err, "validating attestor")
}
if err := o.WorkloadIdentity.CheckAndSetDefaults(); err != nil {
return trace.Wrap(err, "validating workload_identity")
}
return nil
}

// Type returns the type of the service.
func (o *WorkloadIdentityAPIService) Type() string {
return WorkloadIdentityAPIServiceType
}

// MarshalYAML marshals the WorkloadIdentityOutput into YAML.
func (o *WorkloadIdentityAPIService) MarshalYAML() (interface{}, error) {
type raw WorkloadIdentityAPIService
return withTypeHeader((*raw)(o), WorkloadIdentityAPIServiceType)
}

// UnmarshalYAML unmarshals the WorkloadIdentityOutput from YAML.
func (o *WorkloadIdentityAPIService) UnmarshalYAML(node *yaml.Node) error {
// Alias type to remove UnmarshalYAML to avoid recursion
type raw WorkloadIdentityAPIService
if err := node.Decode((*raw)(o)); err != nil {
return trace.Wrap(err)
}
return nil
}
129 changes: 129 additions & 0 deletions lib/tbot/config/service_workload_identity_api_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// Teleport
// Copyright (C) 2025 Gravitational, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

package config

import (
"testing"

"github.com/gravitational/teleport/lib/tbot/spiffe/workloadattest"
)

func TestWorkloadIdentityAPIService_YAML(t *testing.T) {
t.Parallel()

tests := []testYAMLCase[WorkloadIdentityAPIService]{
{
name: "full",
in: WorkloadIdentityAPIService{
Listen: "tcp://0.0.0.0:4040",
Attestors: workloadattest.Config{
Kubernetes: workloadattest.KubernetesAttestorConfig{
Enabled: true,
Kubelet: workloadattest.KubeletClientConfig{
SecurePort: 12345,
TokenPath: "/path/to/token",
CAPath: "/path/to/ca.pem",
SkipVerify: true,
Anonymous: true,
},
},
},
WorkloadIdentity: WorkloadIdentitySelector{
Name: "my-workload-identity",
},
},
},
{
name: "minimal",
in: WorkloadIdentityAPIService{
Listen: "tcp://0.0.0.0:4040",
WorkloadIdentity: WorkloadIdentitySelector{
Name: "my-workload-identity",
},
},
},
}
testYAML(t, tests)
}

func TestWorkloadIdentityAPIService_CheckAndSetDefaults(t *testing.T) {
t.Parallel()

tests := []testCheckAndSetDefaultsCase[*WorkloadIdentityAPIService]{
{
name: "valid",
in: func() *WorkloadIdentityAPIService {
return &WorkloadIdentityAPIService{
WorkloadIdentity: WorkloadIdentitySelector{
Name: "my-workload-identity",
},
Listen: "tcp://0.0.0.0:4040",
}
},
},
{
name: "valid with labels",
in: func() *WorkloadIdentityAPIService {
return &WorkloadIdentityAPIService{
WorkloadIdentity: WorkloadIdentitySelector{
Labels: map[string][]string{
"key": {"value"},
},
},
Listen: "tcp://0.0.0.0:4040",
}
},
},
{
name: "missing selectors",
in: func() *WorkloadIdentityAPIService {
return &WorkloadIdentityAPIService{
WorkloadIdentity: WorkloadIdentitySelector{},
Listen: "tcp://0.0.0.0:4040",
}
},
wantErr: "one of ['name', 'labels'] must be set",
},
{
name: "too many selectors",
in: func() *WorkloadIdentityAPIService {
return &WorkloadIdentityAPIService{
WorkloadIdentity: WorkloadIdentitySelector{
Name: "my-workload-identity",
Labels: map[string][]string{
"key": {"value"},
},
},
Listen: "tcp://0.0.0.0:4040",
}
},
wantErr: "at most one of ['name', 'labels'] can be set",
},
{
name: "missing listen",
in: func() *WorkloadIdentityAPIService {
return &WorkloadIdentityAPIService{
WorkloadIdentity: WorkloadIdentitySelector{
Name: "my-workload-identity",
},
}
},
wantErr: "listen: should not be empty",
},
}
testCheckAndSetDefaults(t, tests)
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ services:
destination:
type: directory
path: /an/output/path
- type: workload-identity-api
listen: tcp://127.0.0.1:123
attestors:
kubernetes:
enabled: false
workload_identity:
name: my-workload-identity
debug: true
auth_server: example.teleport.sh:443
certificate_ttl: 1m0s
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
type: workload-identity-api
listen: tcp://0.0.0.0:4040
attestors:
kubernetes:
enabled: true
kubelet:
secure_port: 12345
token_path: /path/to/token
ca_path: /path/to/ca.pem
skip_verify: true
anonymous: true
workload_identity:
name: my-workload-identity
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
type: workload-identity-api
listen: tcp://0.0.0.0:4040
attestors:
kubernetes:
enabled: false
workload_identity:
name: my-workload-identity

0 comments on commit a42bdb9

Please sign in to comment.