Skip to content

Commit b4b4cc3

Browse files
authored
feat: add OpenShift related Annotations & Labels (#1106)
* feat: add OpenShift related Annotations & Labels Signed-off-by: Zbynek Roubalik <[email protected]> * fix test Signed-off-by: Zbynek Roubalik <[email protected]>
1 parent f4537dd commit b4b4cc3

File tree

5 files changed

+146
-23
lines changed

5 files changed

+146
-23
lines changed

Diff for: client_int_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ func TestRemoteRepositories(t *testing.T) {
205205
func newClient(verbose bool) *fn.Client {
206206
builder := buildpacks.NewBuilder(buildpacks.WithVerbose(verbose))
207207
pusher := docker.NewPusher(docker.WithVerbose(verbose))
208-
deployer := knative.NewDeployer(DefaultNamespace, verbose)
208+
deployer := knative.NewDeployer(knative.WithDeployerNamespace(DefaultNamespace), knative.WithDeployerVerbose(verbose))
209209
remover := knative.NewRemover(DefaultNamespace, verbose)
210210
lister := knative.NewLister(DefaultNamespace, verbose)
211211

Diff for: cmd/client.go

+37-10
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,12 @@ func NewClientFactory(n func() *fn.Client) ClientFactory {
6161
// defer done()
6262
func NewClient(cfg ClientConfig, options ...fn.Option) (*fn.Client, func()) {
6363
var (
64-
p = progress.New(cfg.Verbose) // updates the CLI
65-
t = newTransport() // may provide a custom impl which proxies
66-
c = newCredentialsProvider(t) // for accessing registries
67-
o = []fn.Option{ // standard (shared) options for all commands
64+
p = progress.New(cfg.Verbose) // updates the CLI
65+
t = newTransport() // may provide a custom impl which proxies
66+
c = newCredentialsProvider(t) // for accessing registries
67+
d = newKnativeDeployer(cfg.Namespace, cfg.Verbose)
68+
pp = newTektonPipelinesProvider(cfg.Namespace, p, c, cfg.Verbose)
69+
o = []fn.Option{ // standard (shared) options for all commands
6870
fn.WithVerbose(cfg.Verbose),
6971
fn.WithProgressListener(p),
7072
fn.WithTransport(t),
@@ -73,12 +75,8 @@ func NewClient(cfg ClientConfig, options ...fn.Option) (*fn.Client, func()) {
7375
fn.WithDescriber(knative.NewDescriber(cfg.Namespace, cfg.Verbose)),
7476
fn.WithLister(knative.NewLister(cfg.Namespace, cfg.Verbose)),
7577
fn.WithRunner(docker.NewRunner(cfg.Verbose)),
76-
fn.WithDeployer(knative.NewDeployer(cfg.Namespace, cfg.Verbose)),
77-
fn.WithPipelinesProvider(tekton.NewPipelinesProvider(
78-
tekton.WithNamespace(cfg.Namespace),
79-
tekton.WithProgressListener(p),
80-
tekton.WithCredentialsProvider(c),
81-
tekton.WithVerbose(cfg.Verbose))),
78+
fn.WithDeployer(d),
79+
fn.WithPipelinesProvider(pp),
8280
fn.WithPusher(docker.NewPusher(
8381
docker.WithCredentialsProvider(c),
8482
docker.WithProgressListener(p),
@@ -132,6 +130,35 @@ func newCredentialsProvider(t http.RoundTripper) docker.CredentialsProvider {
132130
return creds.NewCredentialsProvider(options...)
133131
}
134132

133+
func newTektonPipelinesProvider(namespace string, progress *progress.Bar, creds docker.CredentialsProvider, verbose bool) *tekton.PipelinesProvider {
134+
options := []tekton.Opt{
135+
tekton.WithNamespace(namespace),
136+
tekton.WithProgressListener(progress),
137+
tekton.WithCredentialsProvider(creds),
138+
tekton.WithVerbose(verbose),
139+
}
140+
141+
if openshift.IsOpenShift() {
142+
options = append(options, tekton.WithPipelineDecorator(openshift.OpenshiftMetadataDecorator{}))
143+
}
144+
145+
return tekton.NewPipelinesProvider(options...)
146+
147+
}
148+
149+
func newKnativeDeployer(namespace string, verbose bool) fn.Deployer {
150+
options := []knative.DeployerOpt{
151+
knative.WithDeployerNamespace(namespace),
152+
knative.WithDeployerVerbose(verbose),
153+
}
154+
155+
if openshift.IsOpenShift() {
156+
options = append(options, knative.WithDeployerDecorator(openshift.OpenshiftMetadataDecorator{}))
157+
}
158+
159+
return knative.NewDeployer(options...)
160+
}
161+
135162
func GetDefaultRegistry() string {
136163
switch {
137164
case openshift.IsOpenShift():

Diff for: knative/deployer.go

+56-12
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,48 @@ import (
2828
const LIVENESS_ENDPOINT = "/health/liveness"
2929
const READINESS_ENDPOINT = "/health/readiness"
3030

31+
type DeployDecorator interface {
32+
UpdateAnnotations(fn.Function, map[string]string) map[string]string
33+
UpdateLabels(fn.Function, map[string]string) map[string]string
34+
}
35+
36+
type DeployerOpt func(*Deployer)
37+
3138
type Deployer struct {
3239
// Namespace with which to override that set on the default configuration (such as the ~/.kube/config).
3340
// If left blank, deployment will commence to the configured namespace.
3441
Namespace string
3542
// verbose logging enablement flag.
3643
verbose bool
44+
45+
decorator DeployDecorator
46+
}
47+
48+
func NewDeployer(opts ...DeployerOpt) *Deployer {
49+
d := &Deployer{}
50+
51+
for _, opt := range opts {
52+
opt(d)
53+
}
54+
55+
return d
56+
}
57+
58+
func WithDeployerNamespace(namespace string) DeployerOpt {
59+
return func(d *Deployer) {
60+
d.Namespace = namespace
61+
}
62+
}
63+
64+
func WithDeployerVerbose(verbose bool) DeployerOpt {
65+
return func(d *Deployer) {
66+
d.verbose = verbose
67+
}
3768
}
3869

39-
func NewDeployer(namespaceOverride string, verbose bool) *Deployer {
40-
return &Deployer{
41-
Namespace: namespaceOverride,
42-
verbose: verbose,
70+
func WithDeployerDecorator(decorator DeployDecorator) DeployerOpt {
71+
return func(d *Deployer) {
72+
d.decorator = decorator
4373
}
4474
}
4575

@@ -94,7 +124,7 @@ func (d *Deployer) Deploy(ctx context.Context, f fn.Function) (fn.DeploymentResu
94124
referencedSecrets := sets.NewString()
95125
referencedConfigMaps := sets.NewString()
96126

97-
service, err := generateNewService(f)
127+
service, err := generateNewService(f, d.decorator)
98128
if err != nil {
99129
err = fmt.Errorf("knative deployer failed to generate the Knative Service: %v", err)
100130
return fn.DeploymentResult{}, err
@@ -195,7 +225,7 @@ func (d *Deployer) Deploy(ctx context.Context, f fn.Function) (fn.DeploymentResu
195225
return fn.DeploymentResult{}, err
196226
}
197227

198-
_, err = client.UpdateServiceWithRetry(ctx, f.Name, updateService(f, newEnv, newEnvFrom, newVolumes, newVolumeMounts), 3)
228+
_, err = client.UpdateServiceWithRetry(ctx, f.Name, updateService(f, newEnv, newEnvFrom, newVolumes, newVolumeMounts, d.decorator), 3)
199229
if err != nil {
200230
err = fmt.Errorf("knative deployer failed to update the Knative Service: %v", err)
201231
return fn.DeploymentResult{}, err
@@ -240,7 +270,7 @@ func setHealthEndpoints(f fn.Function, c *corev1.Container) *corev1.Container {
240270
return c
241271
}
242272

243-
func generateNewService(f fn.Function) (*v1.Service, error) {
273+
func generateNewService(f fn.Function, decorator DeployDecorator) (*v1.Service, error) {
244274
container := corev1.Container{
245275
Image: f.ImageWithDigest(),
246276
}
@@ -262,16 +292,21 @@ func generateNewService(f fn.Function) (*v1.Service, error) {
262292
}
263293
container.VolumeMounts = newVolumeMounts
264294

265-
labels, err := processLabels(f)
295+
labels, err := processLabels(f, decorator)
266296
if err != nil {
267297
return nil, err
268298
}
269299

300+
annotations := f.Annotations
301+
if decorator != nil {
302+
annotations = decorator.UpdateAnnotations(f, annotations)
303+
}
304+
270305
service := &v1.Service{
271306
ObjectMeta: metav1.ObjectMeta{
272307
Name: f.Name,
273308
Labels: labels,
274-
Annotations: f.Annotations,
309+
Annotations: annotations,
275310
},
276311
Spec: v1.ServiceSpec{
277312
ConfigurationSpec: v1.ConfigurationSpec{
@@ -297,14 +332,18 @@ func generateNewService(f fn.Function) (*v1.Service, error) {
297332
return service, nil
298333
}
299334

300-
func updateService(f fn.Function, newEnv []corev1.EnvVar, newEnvFrom []corev1.EnvFromSource, newVolumes []corev1.Volume, newVolumeMounts []corev1.VolumeMount) func(service *v1.Service) (*v1.Service, error) {
335+
func updateService(f fn.Function, newEnv []corev1.EnvVar, newEnvFrom []corev1.EnvFromSource, newVolumes []corev1.Volume, newVolumeMounts []corev1.VolumeMount, decorator DeployDecorator) func(service *v1.Service) (*v1.Service, error) {
301336
return func(service *v1.Service) (*v1.Service, error) {
302337
// Removing the name so the k8s server can fill it in with generated name,
303338
// this prevents conflicts in Revision name when updating the KService from multiple places.
304339
service.Spec.Template.Name = ""
305340

306341
// Don't bother being as clever as we are with env variables
307342
// Just set the annotations and labels to be whatever we find in func.yaml
343+
if decorator != nil {
344+
service.ObjectMeta.Annotations = decorator.UpdateAnnotations(f, service.ObjectMeta.Annotations)
345+
}
346+
308347
for k, v := range f.Annotations {
309348
service.ObjectMeta.Annotations[k] = v
310349
}
@@ -328,7 +367,7 @@ func updateService(f fn.Function, newEnv []corev1.EnvVar, newEnvFrom []corev1.En
328367
return service, err
329368
}
330369

331-
labels, err := processLabels(f)
370+
labels, err := processLabels(f, decorator)
332371
if err != nil {
333372
return service, err
334373
}
@@ -354,7 +393,7 @@ func updateService(f fn.Function, newEnv []corev1.EnvVar, newEnvFrom []corev1.En
354393
// value: value1
355394
// - key: EXAMPLE2 # Label from the local ENV var
356395
// value: {{ env:MY_ENV }}
357-
func processLabels(f fn.Function) (map[string]string, error) {
396+
func processLabels(f fn.Function, decorator DeployDecorator) (map[string]string, error) {
358397
labels := map[string]string{
359398
labels.FunctionKey: labels.FunctionValue,
360399
labels.FunctionNameKey: f.Name,
@@ -365,6 +404,11 @@ func processLabels(f fn.Function) (map[string]string, error) {
365404
labels.DeprecatedFunctionRuntimeKey: f.Runtime,
366405
// --- end of handling usage of deprecated runtime labels
367406
}
407+
408+
if decorator != nil {
409+
labels = decorator.UpdateLabels(f, labels)
410+
}
411+
368412
for _, label := range f.Labels {
369413
if label.Key != nil && label.Value != nil {
370414
if strings.HasPrefix(*label.Value, "{{") {

Diff for: openshift/metadata.go

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package openshift
2+
3+
import (
4+
fn "knative.dev/kn-plugin-func"
5+
)
6+
7+
const (
8+
AnnotationOpenShiftVcsUri = "app.openshift.io/vcs-uri"
9+
AnnotationOpenShiftVcsRef = "app.openshift.io/vcs-ref"
10+
11+
LabelAppK8sInstance = "app.kubernetes.io/instance"
12+
)
13+
14+
type OpenshiftMetadataDecorator struct{}
15+
16+
func (o OpenshiftMetadataDecorator) UpdateAnnotations(f fn.Function, annotations map[string]string) map[string]string {
17+
if annotations == nil {
18+
annotations = map[string]string{}
19+
}
20+
if f.Git.URL != nil {
21+
annotations[AnnotationOpenShiftVcsUri] = *f.Git.URL
22+
}
23+
if f.Git.Revision != nil {
24+
annotations[AnnotationOpenShiftVcsRef] = *f.Git.Revision
25+
}
26+
27+
return annotations
28+
}
29+
30+
func (o OpenshiftMetadataDecorator) UpdateLabels(f fn.Function, labels map[string]string) map[string]string {
31+
if labels == nil {
32+
labels = map[string]string{}
33+
}
34+
35+
labels[LabelAppK8sInstance] = f.Name
36+
37+
return labels
38+
}

Diff for: pipelines/tekton/pipeplines_provider.go

+14
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ import (
2424
"knative.dev/pkg/apis"
2525
)
2626

27+
type PipelineDecorator interface {
28+
UpdateLabels(fn.Function, map[string]string) map[string]string
29+
}
30+
2731
type Opt func(*PipelinesProvider)
2832

2933
type PipelinesProvider struct {
@@ -33,6 +37,7 @@ type PipelinesProvider struct {
3337
verbose bool
3438
progressListener fn.ProgressListener
3539
credentialsProvider docker.CredentialsProvider
40+
decorator PipelineDecorator
3641
}
3742

3843
func WithNamespace(namespace string) Opt {
@@ -59,6 +64,12 @@ func WithVerbose(verbose bool) Opt {
5964
}
6065
}
6166

67+
func WithPipelineDecorator(decorator PipelineDecorator) Opt {
68+
return func(pp *PipelinesProvider) {
69+
pp.decorator = decorator
70+
}
71+
}
72+
6273
func NewPipelinesProvider(opts ...Opt) *PipelinesProvider {
6374
pp := &PipelinesProvider{}
6475

@@ -87,6 +98,9 @@ func (pp *PipelinesProvider) Run(ctx context.Context, f fn.Function) error {
8798

8899
// let's specify labels that will be applied to every resouce that is created for a Pipeline
89100
labels := map[string]string{labels.FunctionNameKey: f.Name}
101+
if pp.decorator != nil {
102+
labels = pp.decorator.UpdateLabels(f, labels)
103+
}
90104

91105
err = k8s.CreatePersistentVolumeClaim(ctx, getPipelinePvcName(f), pp.namespace, labels, corev1.ReadWriteOnce, *resource.NewQuantity(DefaultPersistentVolumeClaimSize, resource.DecimalSI))
92106
if err != nil {

0 commit comments

Comments
 (0)