github.com/metaprov/modela-operator@v0.0.0-20240118193048-f378be8b74d2/pkg/kube/filters.go (about) 1 package kube 2 3 import ( 4 "encoding/base64" 5 "github.com/Masterminds/goutils" 6 k8serr "k8s.io/apimachinery/pkg/api/errors" 7 "sigs.k8s.io/kustomize/kyaml/yaml" 8 "strings" 9 ) 10 11 type LabelFilter struct { 12 Labels map[string]string 13 } 14 15 func (l LabelFilter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) { 16 filters := make([]yaml.Filter, 0) 17 for k, v := range l.Labels { 18 filters = append(filters, yaml.SetLabel(k, v)) 19 } 20 for _, node := range nodes { 21 if _, err := node.Pipe(filters...); err != nil { 22 return nil, err 23 } 24 } 25 return nodes, nil 26 } 27 28 type ContainerVersionFilter struct { 29 Version string 30 } 31 32 func (cv ContainerVersionFilter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) { 33 for _, node := range nodes { 34 containers, err := node.Pipe(yaml.Lookup("spec", "template", "spec", "containers")) 35 if err != nil || containers == nil { 36 continue 37 } 38 39 // Set ModelaSystem release 40 _ = node.PipeE(yaml.Lookup("spec", "release"), yaml.Set(yaml.NewStringRNode(cv.Version))) 41 42 // Visit each container and apply the container version 43 _ = containers.VisitElements(func(node *yaml.RNode) error { 44 imageNode, _ := node.Pipe(yaml.Lookup("image")) 45 image, _ := imageNode.String() 46 image = strings.Replace(image, "\n", "", -1) 47 // Skip data-dock image; this container is to be deprecated in a future release 48 if strings.Contains(image, "ghcr.io/metaprov/modela-data-dock") { 49 return nil 50 } 51 52 image = strings.Split(image, ":")[0] + ":" + cv.Version 53 _ = node.PipeE( 54 yaml.Lookup("image"), 55 yaml.Set(yaml.NewStringRNode(image))) 56 57 return nil 58 }) 59 } 60 61 return nodes, nil 62 } 63 64 type NamespaceFilter struct { 65 Namespace string 66 } 67 68 func (nf NamespaceFilter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) { 69 for _, node := range nodes { 70 _ = node.SetNamespace(nf.Namespace) 71 _ = node.PipeE(yaml.Lookup("spec", "tenantRef", "name"), yaml.Set(yaml.NewStringRNode(nf.Namespace))) 72 _ = node.PipeE(yaml.Lookup("spec", "secretRef", "namespace"), yaml.Set(yaml.NewStringRNode(nf.Namespace))) 73 } 74 75 return nodes, nil 76 } 77 78 type TenantFilter struct { 79 TenantName string 80 } 81 82 func (t TenantFilter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) { 83 for _, node := range nodes { 84 switch node.GetKind() { 85 case "DataProduct": 86 if err := node.PipeE( 87 yaml.Lookup("spec", "defaultLabName"), 88 yaml.Set(yaml.NewStringRNode(t.TenantName+"-lab"))); err != nil { 89 return nil, err 90 } 91 92 if err := node.PipeE( 93 yaml.Lookup("spec", "defaultServingSiteName"), 94 yaml.Set(yaml.NewStringRNode(t.TenantName+"-serving-site"))); err != nil { 95 return nil, err 96 } 97 case "Lab": 98 if err := node.SetName(t.TenantName + "-lab"); err != nil { 99 return nil, err 100 } 101 case "ServingSite": 102 if err := node.SetName(t.TenantName + "-serving-site"); err != nil { 103 return nil, err 104 } 105 case "Tenant": 106 if err := node.SetName(t.TenantName); err != nil { 107 return nil, err 108 } 109 if err := node.SetNamespace("modela-system"); err != nil { 110 return nil, err 111 } 112 113 if err := node.PipeE( 114 yaml.Lookup("spec", "defaultLabName"), 115 yaml.Set(yaml.NewStringRNode(t.TenantName+"-lab"))); err != nil { 116 return nil, err 117 } 118 119 if err := node.PipeE( 120 yaml.Lookup("spec", "defaultServingSiteName"), 121 yaml.Set(yaml.NewStringRNode(t.TenantName+"-serving-site"))); err != nil { 122 return nil, err 123 } 124 125 } 126 } 127 return nodes, nil 128 } 129 130 type ManagedImageFilter struct { 131 Version string 132 } 133 134 func (mi ManagedImageFilter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) { 135 for _, node := range nodes { 136 if node.GetKind() == "ManagedImage" { 137 _ = node.PipeE(yaml.Lookup("spec", "tag"), yaml.Set(yaml.NewStringRNode(mi.Version))) 138 } 139 } 140 return nodes, nil 141 } 142 143 type JwtSecretFilter struct{} 144 145 func (j JwtSecretFilter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) { 146 for _, node := range nodes { 147 if node.GetName() == "modela-auth-token" { 148 str, _ := goutils.RandomAlphaNumeric(32) 149 b64 := base64.StdEncoding.EncodeToString([]byte(str)) 150 _ = node.PipeE(yaml.Lookup("data", "jwt-secret"), yaml.Set(yaml.NewStringRNode(b64))) 151 } 152 } 153 return nodes, nil 154 } 155 156 type RedisSecretFilter struct { 157 Password string 158 } 159 160 func (r RedisSecretFilter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) { 161 for _, node := range nodes { 162 if node.GetName() == "redis-secret" { 163 _ = node.PipeE( 164 yaml.Lookup("data", "redis-password"), 165 yaml.Set(yaml.NewStringRNode(base64.StdEncoding.EncodeToString([]byte(r.Password)))), 166 ) 167 } 168 } 169 170 return nodes, nil 171 } 172 173 type ModelaConfigFilter struct { 174 VaultAddress string 175 VaultMountPath string 176 } 177 178 func (m ModelaConfigFilter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) { 179 for _, node := range nodes { 180 if node.GetName() == "modela-config" { 181 _ = node.PipeE( 182 yaml.Lookup("spec", "vaultAddress"), 183 yaml.Set(yaml.NewStringRNode(m.VaultAddress)), 184 ) 185 _ = node.PipeE( 186 yaml.Lookup("spec", "vaultMountPath"), 187 yaml.Set(yaml.NewStringRNode(m.VaultMountPath)), 188 ) 189 } 190 } 191 192 return nodes, nil 193 } 194 195 type OwnerReferenceFilter struct { 196 Owner string 197 OwnerNamespace string 198 UID string 199 } 200 201 func (o OwnerReferenceFilter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) { 202 for _, node := range nodes { 203 if o.OwnerNamespace != node.GetNamespace() { 204 continue 205 } 206 ownerReference := yaml.NewMapRNode(&map[string]string{ 207 "apiVersion": "management.modela.ai/v1alpha1", 208 "kind": "Modela", 209 "name": o.Owner, 210 "uid": o.UID, 211 "blockOwnerDeletion": "true", 212 "controller": "true", 213 }) 214 _ = node.PipeE(yaml.LookupCreate(yaml.SequenceNode, "metadata", "ownerReferences"), 215 yaml.Append(ownerReference.YNode())) 216 } 217 return nodes, nil 218 } 219 220 type SkipCertManagerFilter struct{} 221 222 func (o SkipCertManagerFilter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) { 223 var outNodes []*yaml.RNode 224 _, err := GetCRDVersion("issuers.cert-manager.io") 225 var certManagerMissing = k8serr.IsNotFound(err) 226 for _, node := range nodes { 227 if certManagerMissing && node.GetApiVersion() == "cert-manager.io/v1" { 228 continue 229 } 230 outNodes = append(outNodes, node) 231 } 232 233 return outNodes, nil 234 } 235 236 type ConnectionFilter struct { 237 PgvectorEnabled bool 238 MongoEnabled bool 239 } 240 241 func (cf ConnectionFilter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) { 242 var outNodes []*yaml.RNode 243 for _, node := range nodes { 244 if node.GetName() == "postgres-vector-connection" && !cf.PgvectorEnabled { 245 continue 246 } 247 if node.GetName() == "mongodb-connection" && !cf.MongoEnabled { 248 continue 249 } 250 outNodes = append(outNodes, node) 251 } 252 253 return outNodes, nil 254 }