Skip to content

Commit fcf8808

Browse files
committed
[TEP-0089] Enable SPIRE for signing taskrun results in alpha.
Breaking down PR tektoncd#4759 originally proposed by @pxp928 to address TEP-0089 according @lumjjb suggestions. Plan for breaking down PR is PR 1.1: api PR 1.2: entrypointer (+cmd line + test/entrypointer) Entrypoint takes results and signs the results (termination message). PR 1.3: reconciler + pod + cmd/controller + integration tests Controller will verify the signed result. This commit corresponds to 1.3 above.
1 parent d53dc1b commit fcf8808

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+2737
-89
lines changed

cmd/imagedigestexporter/main.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ var (
3333
terminationMessagePath = flag.String("terminationMessagePath", "/tekton/termination", "Location of file containing termination message")
3434
)
3535

36-
/* The input of this go program will be a JSON string with all the output PipelineResources of type
36+
/*
37+
The input of this go program will be a JSON string with all the output PipelineResources of type
3738
Image, which will include the path to where the index.json file will be located. The program will
3839
read the related index.json file(s) and log another JSON string including the name of the image resource
3940
and the digests.

config/config-feature-flags.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,7 @@ data:
9595
# `PipelineRun` status with name, kind, and API version information for each `TaskRun` and
9696
# `Run` in the `PipelineRun` instead. Set it to "both" to do both.
9797
embedded-status: "full"
98+
# Setting this flag to "true" enables spire integration with pipeline.
99+
# This is an experimental feature and thus should still be considered
100+
# an alpha feature.
101+
enable-spire: "false"

config/config-spire.yaml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Copyright 2022 The Tekton Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
apiVersion: v1
16+
kind: ConfigMap
17+
metadata:
18+
name: config-spire
19+
namespace: tekton-pipelines
20+
labels:
21+
app.kubernetes.io/instance: default
22+
app.kubernetes.io/part-of: tekton-pipelines
23+
data:
24+
_example: |
25+
################################
26+
# #
27+
# EXAMPLE CONFIGURATION #
28+
# #
29+
################################
30+
# This block is not actually functional configuration,
31+
# but serves to illustrate the available configuration
32+
# options and document them in a way that is accessible
33+
# to users that `kubectl edit` this config map.
34+
#
35+
# These sample configuration options may be copied out of
36+
# this example block and unindented to be in the data block
37+
# to actually change the configuration.
38+
#
39+
# spire-trust-domain specifies the SPIRE trust domain to use.
40+
# spire-trust-domain: "example.org"
41+
#
42+
# spire-socket-path specifies the SPIRE agent socket for SPIFFE workload API.
43+
# spire-socket-path: "unix:///spiffe-workload-api/spire-agent.sock"
44+
#
45+
# spire-server-addr specifies the SPIRE server address for workload/node registration.
46+
# spire-server-addr: "spire-server.spire.svc.cluster.local:8081"
47+
#
48+
# spire-node-alias-prefix specifies the SPIRE node alias prefix to use.
49+
# spire-node-alias-prefix: "/tekton-node/"

config/controller.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ spec:
116116
value: feature-flags
117117
- name: CONFIG_LEADERELECTION_NAME
118118
value: config-leader-election
119+
- name: CONFIG_SPIRE
120+
value: config-spire
119121
- name: CONFIG_TRUSTED_RESOURCES_NAME
120122
value: config-trusted-resources
121123
- name: SSL_CERT_FILE

docs/spire.md

Lines changed: 287 additions & 0 deletions
Large diffs are not rendered by default.

examples/v1beta1/pipelineruns/4808-regression.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,4 @@ spec:
9292
name: result-test
9393
params:
9494
- name: RESULT_STRING_LENGTH
95-
value: "3000"
95+
value: "2000"

hack/update-codegen.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ ${PREFIX}/deepcopy-gen \
5757
--go-header-file ${REPO_ROOT_DIR}/hack/boilerplate/boilerplate.go.txt \
5858
-i github.com/tektoncd/pipeline/pkg/apis/config
5959

60+
${PREFIX}/deepcopy-gen \
61+
-O zz_generated.deepcopy \
62+
--go-header-file ${REPO_ROOT_DIR}/hack/boilerplate/boilerplate.go.txt \
63+
-i github.com/tektoncd/pipeline/pkg/spire/config
64+
6065
${PREFIX}/deepcopy-gen \
6166
-O zz_generated.deepcopy \
6267
--go-header-file ${REPO_ROOT_DIR}/hack/boilerplate/boilerplate.go.txt \

pkg/apis/config/spire_config.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
Copyright 2022 The Tekton Authors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package config
18+
19+
import (
20+
"fmt"
21+
"os"
22+
23+
sc "github.com/tektoncd/pipeline/pkg/spire/config"
24+
corev1 "k8s.io/api/core/v1"
25+
)
26+
27+
const (
28+
// SpireConfigMapName is the name of the trusted resources configmap
29+
SpireConfigMapName = "config-spire"
30+
31+
// SpireTrustDomain is the key to extract out the SPIRE trust domain to use
32+
SpireTrustDomain = "spire-trust-domain"
33+
// SpireSocketPath is the key to extract out the SPIRE agent socket for SPIFFE workload API
34+
SpireSocketPath = "spire-socket-path"
35+
// SpireServerAddr is the key to extract out the SPIRE server address for workload/node registration
36+
SpireServerAddr = "spire-server-addr"
37+
// SpireNodeAliasPrefix is the key to extract out the SPIRE node alias prefix to use
38+
SpireNodeAliasPrefix = "spire-node-alias-prefix"
39+
40+
// SpireTrustDomainDefault is the default value for the SpireTrustDomain
41+
SpireTrustDomainDefault = "example.org"
42+
// SpireSocketPathDefault is the default value for the SpireSocketPath
43+
SpireSocketPathDefault = "unix:///spiffe-workload-api/spire-agent.sock"
44+
// SpireServerAddrDefault is the default value for the SpireServerAddr
45+
SpireServerAddrDefault = "spire-server.spire.svc.cluster.local:8081"
46+
// SpireNodeAliasPrefixDefault is the default value for the SpireNodeAliasPrefix
47+
SpireNodeAliasPrefixDefault = "/tekton-node/"
48+
)
49+
50+
// NewSpireConfigFromMap creates a Config from the supplied map
51+
func NewSpireConfigFromMap(data map[string]string) (*sc.SpireConfig, error) {
52+
cfg := &sc.SpireConfig{}
53+
var ok bool
54+
if cfg.TrustDomain, ok = data[SpireTrustDomain]; !ok {
55+
cfg.TrustDomain = SpireTrustDomainDefault
56+
}
57+
if cfg.SocketPath, ok = data[SpireSocketPath]; !ok {
58+
cfg.SocketPath = SpireSocketPathDefault
59+
}
60+
if cfg.ServerAddr, ok = data[SpireServerAddr]; !ok {
61+
cfg.ServerAddr = SpireServerAddrDefault
62+
}
63+
if cfg.NodeAliasPrefix, ok = data[SpireNodeAliasPrefix]; !ok {
64+
cfg.NodeAliasPrefix = SpireNodeAliasPrefixDefault
65+
}
66+
if err := cfg.Validate(); err != nil {
67+
return nil, fmt.Errorf("failed to parse SPIRE configmap: %w", err)
68+
}
69+
return cfg, nil
70+
}
71+
72+
// NewSpireConfigFromConfigMap creates a Config from the supplied ConfigMap
73+
func NewSpireConfigFromConfigMap(configMap *corev1.ConfigMap) (*sc.SpireConfig, error) {
74+
return NewSpireConfigFromMap(configMap.Data)
75+
}
76+
77+
// GetSpireConfigName returns the name of Spire ConfigMap
78+
func GetSpireConfigName() string {
79+
if e := os.Getenv("CONFIG_SPIRE"); e != "" {
80+
return e
81+
}
82+
return SpireConfigMapName
83+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
Copyright 2021 The Tekton Authors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package config_test
18+
19+
import (
20+
"testing"
21+
22+
"github.com/google/go-cmp/cmp"
23+
"github.com/tektoncd/pipeline/pkg/apis/config"
24+
test "github.com/tektoncd/pipeline/pkg/reconciler/testing"
25+
sc "github.com/tektoncd/pipeline/pkg/spire/config"
26+
"github.com/tektoncd/pipeline/test/diff"
27+
)
28+
29+
func TestNewSpireConfigFromConfigMap(t *testing.T) {
30+
type testCase struct {
31+
expectedConfig *sc.SpireConfig
32+
fileName string
33+
}
34+
35+
testCases := []testCase{
36+
{
37+
expectedConfig: &sc.SpireConfig{
38+
TrustDomain: "test.com",
39+
SocketPath: "unix:///spiffe-workload-api/test-spire-agent.sock",
40+
ServerAddr: "test-spire-server.spire.svc.cluster.local:8081",
41+
NodeAliasPrefix: "/test-tekton-node/",
42+
},
43+
fileName: config.GetSpireConfigName(),
44+
},
45+
}
46+
47+
for _, tc := range testCases {
48+
verifyConfigFileWithExpectedSpireConfig(t, tc.fileName, tc.expectedConfig)
49+
}
50+
}
51+
52+
func TestNewSpireConfigFromEmptyConfigMap(t *testing.T) {
53+
SpireConfigEmptyName := "config-spire-empty"
54+
expectedConfig := &sc.SpireConfig{
55+
TrustDomain: "example.org",
56+
SocketPath: "unix:///spiffe-workload-api/spire-agent.sock",
57+
ServerAddr: "spire-server.spire.svc.cluster.local:8081",
58+
NodeAliasPrefix: "/tekton-node/",
59+
}
60+
verifyConfigFileWithExpectedSpireConfig(t, SpireConfigEmptyName, expectedConfig)
61+
}
62+
63+
func verifyConfigFileWithExpectedSpireConfig(t *testing.T, fileName string, expectedConfig *sc.SpireConfig) {
64+
cm := test.ConfigMapFromTestFile(t, fileName)
65+
if ab, err := config.NewSpireConfigFromConfigMap(cm); err == nil {
66+
if d := cmp.Diff(ab, expectedConfig); d != "" {
67+
t.Errorf("Diff:\n%s", diff.PrintWantGot(d))
68+
}
69+
} else {
70+
t.Errorf("NewSpireConfigFromConfigMap(actual) = %v", err)
71+
}
72+
}

pkg/apis/config/store.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package config
1919
import (
2020
"context"
2121

22+
sc "github.com/tektoncd/pipeline/pkg/spire/config"
2223
"knative.dev/pkg/configmap"
2324
)
2425

@@ -33,6 +34,7 @@ type Config struct {
3334
ArtifactPVC *ArtifactPVC
3435
Metrics *Metrics
3536
TrustedResources *TrustedResources
37+
SpireConfig *sc.SpireConfig
3638
}
3739

3840
// FromContext extracts a Config from the provided context.
@@ -56,13 +58,16 @@ func FromContextOrDefaults(ctx context.Context) *Config {
5658
artifactPVC, _ := NewArtifactPVCFromMap(map[string]string{})
5759
metrics, _ := newMetricsFromMap(map[string]string{})
5860
trustedresources, _ := NewTrustedResourcesConfigFromMap(map[string]string{})
61+
spireconfig, _ := NewSpireConfigFromMap(map[string]string{})
62+
5963
return &Config{
6064
Defaults: defaults,
6165
FeatureFlags: featureFlags,
6266
ArtifactBucket: artifactBucket,
6367
ArtifactPVC: artifactPVC,
6468
Metrics: metrics,
6569
TrustedResources: trustedresources,
70+
SpireConfig: spireconfig,
6671
}
6772
}
6873

@@ -91,6 +96,7 @@ func NewStore(logger configmap.Logger, onAfterStore ...func(name string, value i
9196
GetArtifactPVCConfigName(): NewArtifactPVCFromConfigMap,
9297
GetMetricsConfigName(): NewMetricsFromConfigMap,
9398
GetTrustedResourcesConfigName(): NewTrustedResourcesConfigFromConfigMap,
99+
GetSpireConfigName(): NewSpireConfigFromConfigMap,
94100
},
95101
onAfterStore...,
96102
),
@@ -131,6 +137,10 @@ func (s *Store) Load() *Config {
131137
if trustedresources == nil {
132138
trustedresources, _ = NewTrustedResourcesConfigFromMap(map[string]string{})
133139
}
140+
spireconfig := s.UntypedLoad(GetSpireConfigName())
141+
if spireconfig == nil {
142+
spireconfig, _ = NewSpireConfigFromMap(map[string]string{})
143+
}
134144

135145
return &Config{
136146
Defaults: defaults.(*Defaults).DeepCopy(),
@@ -139,5 +149,6 @@ func (s *Store) Load() *Config {
139149
ArtifactPVC: artifactPVC.(*ArtifactPVC).DeepCopy(),
140150
Metrics: metrics.(*Metrics).DeepCopy(),
141151
TrustedResources: trustedresources.(*TrustedResources).DeepCopy(),
152+
SpireConfig: spireconfig.(*sc.SpireConfig).DeepCopy(),
142153
}
143154
}

0 commit comments

Comments
 (0)