@@ -3,21 +3,25 @@ package deploymentrepo
33import (
44 "context"
55 "fmt"
6+ "io"
67 "os"
78 "path/filepath"
9+ "strings"
810
911 "github.com/go-git/go-billy/v5"
1012 "github.com/go-git/go-git/v5"
13+ "github.com/openmcp-project/bootstrapper/internal/config"
1114 "github.com/openmcp-project/controller-utils/pkg/clusters"
1215 "sigs.k8s.io/kustomize/api/krusty"
1316 "sigs.k8s.io/kustomize/kyaml/filesys"
14-
15- "github.com/openmcp-project/bootstrapper/internal/config"
17+ "sigs.k8s.io/yaml"
1618
1719 gitconfig "github.com/openmcp-project/bootstrapper/internal/git-config"
1820 "github.com/openmcp-project/bootstrapper/internal/log"
1921 ocmcli "github.com/openmcp-project/bootstrapper/internal/ocm-cli"
2022 "github.com/openmcp-project/bootstrapper/internal/util"
23+
24+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
2125)
2226
2327const (
@@ -296,49 +300,94 @@ func (m *DeploymentRepoManager) ApplyCustomResourceDefinitions(ctx context.Conte
296300 return nil
297301 }
298302
303+ crdDirectory := filepath .Join (m .gitRepoDir , ResourcesDirectoryName , OpenMCPDirectoryName , CRDsDirectoryName )
304+
299305 logger .Infof ("Applying Custom Resource Definitions to deployment repository" )
300306
301- crdsDownloadDir := filepath . Join ( m . gitRepoDir , ResourcesDirectoryName , OpenMCPDirectoryName , CRDsDirectoryName )
307+ err := m . applyCRDsForComponentVersion ( ctx , m . openMCPOperatorCV , crdDirectory )
302308
303- // if the CRDs directory already exists, remove it to ensure a clean state
304- if _ , err := os .Stat (crdsDownloadDir ); err == nil {
305- err = os .RemoveAll (crdsDownloadDir )
309+ for _ , clusterProvider := range m .Config .Providers .ClusterProviders {
310+ clusterProviderCV , err := m .compGetter .GetReferencedComponentVersionRecursive (ctx , m .compGetter .RootComponentVersion (), "cluster-provider-" + clusterProvider )
306311 if err != nil {
307- return fmt .Errorf ("failed to remove existing CRD directory: %w" , err )
312+ return fmt .Errorf ("failed to get component version for cluster provider %s: %w" , clusterProvider , err )
313+ }
314+
315+ err = m .applyCRDsForComponentVersion (ctx , clusterProviderCV , crdDirectory )
316+ if err != nil {
317+ logger .Warnf ("Failed to apply CRDs for cluster provider %s: %v" , clusterProvider , err )
308318 }
309319 }
310320
311- err := os .Mkdir (crdsDownloadDir , 0o755 )
312- if err != nil {
313- return fmt .Errorf ("failed to create CRD download directory: %w" , err )
321+ for _ , serviceProvider := range m .Config .Providers .ServiceProviders {
322+ serviceProviderCV , err := m .compGetter .GetReferencedComponentVersionRecursive (ctx , m .compGetter .RootComponentVersion (), "service-provider-" + serviceProvider )
323+ if err != nil {
324+ return fmt .Errorf ("failed to get component version for service provider %s: %w" , serviceProvider , err )
325+ }
326+ err = m .applyCRDsForComponentVersion (ctx , serviceProviderCV , crdDirectory )
327+ if err != nil {
328+ logger .Warnf ("Failed to apply CRDs for service provider %s: %v" , serviceProvider , err )
329+ }
314330 }
315331
316- err = m .compGetter .DownloadDirectoryResource (ctx , m .openMCPOperatorCV , "openmcp-operator-crds" , crdsDownloadDir )
317- if err != nil {
318- return fmt .Errorf ("failed to download CRD resource: %w" , err )
332+ for _ , platformService := range m .Config .Providers .PlatformServices {
333+ platformServiceCV , err := m .compGetter .GetReferencedComponentVersionRecursive (ctx , m .compGetter .RootComponentVersion (), "platform-service-" + platformService )
334+ if err != nil {
335+ return fmt .Errorf ("failed to get component version for platform service %s: %w" , platformService , err )
336+ }
337+ err = m .applyCRDsForComponentVersion (ctx , platformServiceCV , crdDirectory )
338+ if err != nil {
339+ logger .Warnf ("Failed to apply CRDs for platform service %s: %v" , platformService , err )
340+ }
319341 }
320342
321- // List all YAML files in the CRDs download directory
322- entries , err := os .ReadDir (crdsDownloadDir )
343+ entries , err := os .ReadDir (crdDirectory )
323344 if err != nil {
324345 return fmt .Errorf ("failed to read CRD download directory: %w" , err )
325346 }
326347
327- m .crdFiles = make ([]string , 0 )
328348 for _ , entry := range entries {
329349 if ! entry .IsDir () {
330350 fileName := entry .Name ()
331- // Check if file has .yaml or .yml extension
332351 if filepath .Ext (fileName ) == ".yaml" || filepath .Ext (fileName ) == ".yml" {
333- filePath := filepath .Join (crdsDownloadDir , fileName )
334- m .crdFiles = append (m .crdFiles , filePath )
335- logger .Tracef ("Added CRD file: %s" , filePath )
352+ // parse file into unstructured object
353+ filePath := filepath .Join (crdDirectory , fileName )
354+ file , err := os .Open (filePath )
355+ if err != nil {
356+ return fmt .Errorf ("failed to open CRD file %s: %w" , filePath , err )
357+ }
358+ defer func (path string ) {
359+ err := file .Close ()
360+ if err != nil {
361+ _ , _ = fmt .Fprintf (os .Stderr , "failed to close CRD file %s: %v\n " , path , err )
362+ }
363+ }(filePath )
364+
365+ manifestBytes , err := io .ReadAll (file )
366+ if err != nil {
367+ return fmt .Errorf ("failed to read CRD file %s: %w" , filePath , err )
368+ }
369+
370+ var manifest unstructured.Unstructured
371+ err = yaml .Unmarshal (manifestBytes , & manifest )
372+ if err != nil {
373+ return fmt .Errorf ("failed to unmarshal CRD file %s: %w" , filePath , err )
374+ }
375+
376+ if ! crdIsForPlatformCluster (& manifest ) {
377+ // if the CRD is not for the platform cluster, remove it
378+ logger .Tracef ("Removing CRD file %s as it is not for the platform cluster" , filePath )
379+ err = os .Remove (filePath )
380+ if err != nil {
381+ return fmt .Errorf ("failed to remove CRD file %s: %w" , filePath , err )
382+ }
383+ } else {
384+ logger .Tracef ("Added CRD file: %s" , filePath )
385+ m .crdFiles = append (m .crdFiles , filePath )
386+ }
336387 }
337388 }
338389 }
339390
340- logger .Infof ("Found %d CRD files" , len (m .crdFiles ))
341-
342391 workTree , err := m .gitRepo .Worktree ()
343392 if err != nil {
344393 return fmt .Errorf ("failed to get worktree: %w" , err )
@@ -352,6 +401,37 @@ func (m *DeploymentRepoManager) ApplyCustomResourceDefinitions(ctx context.Conte
352401 return nil
353402}
354403
404+ func (m * DeploymentRepoManager ) applyCRDsForComponentVersion (ctx context.Context , cv * ocmcli.ComponentVersion , targetDirectory string ) error {
405+ logger := log .GetLogger ()
406+
407+ lastSlash := strings .LastIndex (cv .Component .Name , "/" )
408+ if lastSlash == - 1 {
409+ return fmt .Errorf ("invalid component name: %s" , cv .Component .Name )
410+ }
411+
412+ crdResourceName := cv .Component .Name [lastSlash + 1 :] + "-crds"
413+
414+ logger .Debugf ("Applying CRDs for component %s from resource %s to directory %s" , cv .Component .Name , crdResourceName , targetDirectory )
415+
416+ err := m .compGetter .DownloadDirectoryResource (ctx , cv , crdResourceName , targetDirectory )
417+ if err != nil {
418+ return fmt .Errorf ("failed to download CRD resource: %w" , err )
419+ }
420+
421+ return nil
422+ }
423+
424+ func crdIsForPlatformCluster (crd * unstructured.Unstructured ) bool {
425+ labels := crd .GetLabels ()
426+ if labels == nil {
427+ return false
428+ }
429+ if val , ok := labels ["openmcp.cloud/cluster" ]; ok && val == "platform" {
430+ return true
431+ }
432+ return false
433+ }
434+
355435// ApplyExtraManifests copies extra manifests from the specified directory to the deployment repository and stages them for commit.
356436func (m * DeploymentRepoManager ) ApplyExtraManifests (_ context.Context ) error {
357437 logger := log .GetLogger ()
@@ -405,7 +485,9 @@ func (m *DeploymentRepoManager) UpdateResourcesKustomization() error {
405485 len (m .extraManifests ))
406486
407487 for _ , crdFile := range m .crdFiles {
408- files = append (files , filepath .Join (CRDsDirectoryName , filepath .Base (crdFile )))
488+ // get the path relative to the git repo dir
489+ crdFile = strings .TrimPrefix (crdFile , filepath .Join (m .gitRepoDir , ResourcesDirectoryName , OpenMCPDirectoryName )+ string (os .PathSeparator ))
490+ files = append (files , crdFile )
409491 }
410492
411493 for _ , clusterProvider := range m .Config .Providers .ClusterProviders {
0 commit comments