This repository has been archived by the owner on Oct 10, 2023. It is now read-only.
/
bom_util.go
172 lines (152 loc) · 6.25 KB
/
bom_util.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
// Copyright 2021 VMware, Inc. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package util
import (
"context"
"fmt"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/vmware-tanzu/tanzu-framework/addons/pkg/constants"
tkrv1 "github.com/vmware-tanzu/tanzu-framework/apis/run/pkg/tkr/v1"
)
// GetBOMByTKRName returns the bom associated with the TKR
func GetBOMByTKRName(ctx context.Context, c client.Client, tkrName string) (*tkrv1.Bom, error) {
configMapList := &corev1.ConfigMapList{}
var bomConfigMap *corev1.ConfigMap
if err := c.List(ctx, configMapList, client.InNamespace(constants.TKGBomNamespace), client.MatchingLabels{constants.TKRLabel: tkrName}); err != nil {
return nil, err
}
if len(configMapList.Items) == 0 {
return nil, nil
}
bomConfigMap = &configMapList.Items[0]
bomData, ok := bomConfigMap.BinaryData[constants.TKRBomContent]
if !ok {
bomDataString, ok := bomConfigMap.Data[constants.TKRBomContent]
if !ok {
return nil, nil
}
bomData = []byte(bomDataString)
}
bom, err := tkrv1.NewBom(bomData)
if err != nil {
return nil, err
}
return &bom, nil
}
func GetTkgBomConfigMapByName(ctx context.Context, c client.Client, configmapName string) (*tkrv1.TkgBom, error) {
var bomConfigMap corev1.ConfigMap
objectKey := client.ObjectKey{Namespace: constants.ClusterMetadataNamespace, Name: configmapName}
if err := c.Get(ctx, objectKey, &bomConfigMap); err != nil {
return nil, err
}
bomData, ok := bomConfigMap.BinaryData[constants.TKGBomContent]
if !ok {
bomDataString, ok := bomConfigMap.Data[constants.TKGBomContent]
if !ok {
return nil, nil
}
bomData = []byte(bomDataString)
}
tkgBom, err := tkrv1.NewTkgBom(bomData)
if err != nil {
return nil, err
}
return &tkgBom, nil
}
// GetTKRNameFromBOMConfigMap returns tkr name given a bom configmap
func GetTKRNameFromBOMConfigMap(bomConfigMap *corev1.ConfigMap) string {
return bomConfigMap.Labels[constants.TKRLabel]
}
// GetAddonImageRepository returns imageRepository from configMap `tkr-controller-config` in namespace `tkg-system`.
// If not found, try the legacy `tkr-system`, else use BOM
func GetAddonImageRepository(ctx context.Context, c client.Client, bom *tkrv1.Bom) (string, error) {
bomConfigMap := &corev1.ConfigMap{}
// Todo: temporary workaround for getting addon image repo. Because in legacy mgmt cluster
// the tkr-controller-config configmap is stored in `tkr-system`, and in clusterclass or clusterclass
// capable mgmt cluster, it is stored in `tkg-system`.
// Getting from `tkr-system` should be removed once no legacy management cluster exists.
err := c.Get(ctx, client.ObjectKey{
Namespace: constants.TKGBomNamespaceClassyClusters,
Name: constants.TKRConfigmapName,
}, bomConfigMap)
if err != nil && errors.IsNotFound(err) {
err = c.Get(ctx, client.ObjectKey{
Namespace: constants.TKGBomNamespace,
Name: constants.TKRConfigmapName,
}, bomConfigMap)
}
// if the configmap exists, try get repository from the config map
if err == nil {
if imgRepo, ok := bomConfigMap.Data[constants.TKRRepoKey]; ok && imgRepo != "" {
return imgRepo, nil
}
} else if !errors.IsNotFound(err) {
// return the error to controller if err is not IsNotFound
return "", err
}
// if the configmap doesn't exist, or there is no `imageRepository` field, get repository from BOM
return bom.GetImageRepository()
}
// GetCorePackageRepositoryImageFromBom generates the core PackageRepository Object
func GetCorePackageRepositoryImageFromBom(bom *tkrv1.Bom) (*tkrv1.ImageInfo, error) {
repositoryImage, err := bom.GetImageInfo(constants.TKGCorePackageRepositoryComponentName, "", constants.TKGCorePackageRepositoryImageName)
if err != nil {
return nil, err
}
return &repositoryImage, nil
}
// GetTemplateImageURLFromBom gets the image template image url of an addon
// This method first checks if packageName is present in addonConfig
// If packageName is present, it will use it to find imgpkg bundle in tkg-core-packages
// If packageName is not present, it will look for addonTemplatesImage
// addonTemplatesImage should be present in a 1.3.1 cluster, and will be used to find images in tanzu_core_addons
// If addonTemplatesImage is not present, it will fall back to using templatesImagePath and templatesImageTag to find template images
func GetTemplateImageURLFromBom(addonConfig *tkrv1.Addon, imageRepository string, bom *tkrv1.Bom) (string, error) {
/*example addon section in BOM:
kapp-controller:
category: addons-management
clusterTypes:
- management
- workload
templatesImagePath: tanzu_core/addons/kapp-controller-templates (1.3.0-)
templatesImageTag: v1.3.0 (1.3.0-)
addonTemplatesImage: (1.3.1)
- componentRef: tanzu_core_addons (1.3.1)
imageRefs: (1.3.1)
- kappControllerTemplatesImage (1.3.1)
addonContainerImages: (1.3.1)
- componentRef: kapp-controller (1.3.1)
imageRefs: (1.3.1)
- kappControllerImage (1.3.1)
packageName: addons-manager.tkg-core.tanzu.vmware (1.4.0+)
*/
var templateImagePath, templateImageTag string
if addonConfig.PackageName != "" {
addonPackageImage, err := bom.GetImageInfo(constants.TKGCorePackageRepositoryComponentName, "", addonConfig.PackageName)
if err != nil {
return "", err
}
templateImagePath = addonPackageImage.ImagePath
templateImageTag = addonPackageImage.Tag
} else if len(addonConfig.AddonTemplatesImage) < 1 || len(addonConfig.AddonTemplatesImage[0].ImageRefs) < 1 {
// if AddonTemplatesImage and AddonTemplatesImage are not present, use the older BOM format
templateImagePath = addonConfig.TemplatesImagePath
templateImageTag = addonConfig.TemplatesImageTag
} else {
templateImageComponentName := addonConfig.AddonTemplatesImage[0].ComponentRef
templateImageName := addonConfig.AddonTemplatesImage[0].ImageRefs[0]
templateImage, err := bom.GetImageInfo(templateImageComponentName, "", templateImageName)
if err != nil {
return "", err
}
templateImagePath = templateImage.ImagePath
templateImageTag = templateImage.Tag
}
if templateImagePath == "" || templateImageTag == "" {
err := fmt.Errorf("unable to get template image")
return "", err
}
return fmt.Sprintf("%s/%s:%s", imageRepository, templateImagePath, templateImageTag), nil
}