github.com/crossplane/upjet@v1.3.0/pkg/migration/configurationmetadata_steps.go (about) 1 // SPDX-FileCopyrightText: 2023 The Crossplane Authors <https://crossplane.io> 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 5 package migration 6 7 import ( 8 "fmt" 9 "strconv" 10 11 xpmetav1 "github.com/crossplane/crossplane/apis/pkg/meta/v1" 12 xpmetav1alpha1 "github.com/crossplane/crossplane/apis/pkg/meta/v1alpha1" 13 "github.com/pkg/errors" 14 ) 15 16 const ( 17 // configuration migration steps follow any existing API migration steps 18 stepBackupMRs = iota + stepAPIEnd + 1 19 stepBackupComposites 20 stepBackupClaims 21 stepOrphanMRs 22 stepNewFamilyProvider 23 stepCheckHealthFamilyProvider 24 stepNewServiceScopedProvider 25 stepCheckHealthNewServiceScopedProvider 26 stepConfigurationPackageDisableDepResolution 27 stepEditPackageLock 28 stepDeleteMonolithicProvider 29 stepActivateFamilyProviderRevision 30 stepCheckInstallationFamilyProviderRevision 31 stepActivateServiceScopedProviderRevision 32 stepCheckInstallationServiceScopedProviderRevision 33 stepEditConfigurationMetadata 34 stepBuildConfiguration 35 stepPushConfiguration 36 stepEditConfigurationPackage 37 stepConfigurationPackageEnableDepResolution 38 stepRevertOrphanMRs 39 stepConfigurationEnd 40 ) 41 42 func getConfigurationMigrationSteps() []step { 43 steps := make([]step, 0, stepConfigurationEnd-stepAPIEnd-1) 44 for i := stepAPIEnd + 1; i < stepConfigurationEnd; i++ { 45 steps = append(steps, i) 46 } 47 return steps 48 } 49 50 const ( 51 errConfigurationMetadataOutput = "failed to output configuration YAML document" 52 ) 53 54 func (pg *PlanGenerator) convertConfigurationMetadata(o UnstructuredWithMetadata) error { 55 isConverted := false 56 conf, err := toConfigurationMetadata(o.Object) 57 if err != nil { 58 return err 59 } 60 for _, confConv := range pg.registry.configurationMetaConverters { 61 if confConv.re == nil || confConv.converter == nil || !confConv.re.MatchString(o.Object.GetName()) { 62 continue 63 } 64 65 switch o.Object.GroupVersionKind().Version { 66 case "v1alpha1": 67 err = confConv.converter.ConfigurationMetadataV1Alpha1(conf.(*xpmetav1alpha1.Configuration)) 68 default: 69 err = confConv.converter.ConfigurationMetadataV1(conf.(*xpmetav1.Configuration)) 70 } 71 if err != nil { 72 return errors.Wrapf(err, "failed to call converter on Configuration: %s", conf.GetName()) 73 } 74 // TODO: if a configuration converter only converts a specific version, 75 // (or does not convert the given configuration), 76 // we will have a false positive. Better to compute and check 77 // a diff here. 78 isConverted = true 79 } 80 if !isConverted { 81 return nil 82 } 83 return pg.stepEditConfigurationMetadata(o, &UnstructuredWithMetadata{ 84 Object: ToSanitizedUnstructured(conf), 85 Metadata: o.Metadata, 86 }) 87 } 88 89 func (pg *PlanGenerator) stepConfiguration(s step) *Step { 90 return pg.stepConfigurationWithSubStep(s, false) 91 } 92 93 func (pg *PlanGenerator) configurationSubStep(s step) string { 94 ss := -1 95 subStep := pg.subSteps[s] 96 if subStep != "" { 97 s, err := strconv.Atoi(subStep) 98 if err == nil { 99 ss = s 100 } 101 } 102 pg.subSteps[s] = strconv.Itoa(ss + 1) 103 return pg.subSteps[s] 104 } 105 106 func (pg *PlanGenerator) stepConfigurationWithSubStep(s step, newSubStep bool) *Step { //nolint:gocyclo // easy to follow all steps here 107 stepKey := strconv.Itoa(int(s)) 108 if newSubStep { 109 stepKey = fmt.Sprintf("%s.%s", stepKey, pg.configurationSubStep(s)) 110 } 111 if pg.Plan.Spec.stepMap[stepKey] != nil { 112 return pg.Plan.Spec.stepMap[stepKey] 113 } 114 115 pg.Plan.Spec.stepMap[stepKey] = &Step{} 116 switch s { //nolint:exhaustive 117 case stepOrphanMRs: 118 setPatchStep("deletion-policy-orphan", pg.Plan.Spec.stepMap[stepKey]) 119 case stepRevertOrphanMRs: 120 setPatchStep("deletion-policy-delete", pg.Plan.Spec.stepMap[stepKey]) 121 case stepNewFamilyProvider: 122 setApplyStep("new-ssop", pg.Plan.Spec.stepMap[stepKey]) 123 case stepNewServiceScopedProvider: 124 setApplyStep("new-ssop", pg.Plan.Spec.stepMap[stepKey]) 125 case stepConfigurationPackageDisableDepResolution: 126 setPatchStep("disable-dependency-resolution", pg.Plan.Spec.stepMap[stepKey]) 127 case stepConfigurationPackageEnableDepResolution: 128 setPatchStep("enable-dependency-resolution", pg.Plan.Spec.stepMap[stepKey]) 129 case stepEditConfigurationPackage: 130 setPatchStep("edit-configuration-package", pg.Plan.Spec.stepMap[stepKey]) 131 case stepEditPackageLock: 132 setPatchStep("edit-package-lock", pg.Plan.Spec.stepMap[stepKey]) 133 case stepDeleteMonolithicProvider: 134 setDeleteStep("delete-monolithic-provider", pg.Plan.Spec.stepMap[stepKey]) 135 case stepActivateFamilyProviderRevision: 136 setPatchStep("activate-ssop", pg.Plan.Spec.stepMap[stepKey]) 137 case stepActivateServiceScopedProviderRevision: 138 setPatchStep("activate-ssop", pg.Plan.Spec.stepMap[stepKey]) 139 case stepEditConfigurationMetadata: 140 setExecStep("edit-configuration-metadata", pg.Plan.Spec.stepMap[stepKey]) 141 case stepBackupMRs: 142 setExecStep("backup-managed-resources", pg.Plan.Spec.stepMap[stepKey]) 143 case stepBackupComposites: 144 setExecStep("backup-composite-resources", pg.Plan.Spec.stepMap[stepKey]) 145 case stepBackupClaims: 146 setExecStep("backup-claim-resources", pg.Plan.Spec.stepMap[stepKey]) 147 case stepCheckHealthFamilyProvider: 148 setExecStep("wait-for-healthy", pg.Plan.Spec.stepMap[stepKey]) 149 case stepCheckHealthNewServiceScopedProvider: 150 setExecStep("wait-for-healthy", pg.Plan.Spec.stepMap[stepKey]) 151 case stepCheckInstallationFamilyProviderRevision: 152 setExecStep("wait-for-installed", pg.Plan.Spec.stepMap[stepKey]) 153 case stepCheckInstallationServiceScopedProviderRevision: 154 setExecStep("wait-for-installed", pg.Plan.Spec.stepMap[stepKey]) 155 case stepBuildConfiguration: 156 setExecStep("build-configuration", pg.Plan.Spec.stepMap[stepKey]) 157 case stepPushConfiguration: 158 setExecStep("push-configuration", pg.Plan.Spec.stepMap[stepKey]) 159 default: 160 panic(fmt.Sprintf(errInvalidStepFmt, s)) 161 } 162 return pg.Plan.Spec.stepMap[stepKey] 163 } 164 165 func (pg *PlanGenerator) stepEditConfigurationMetadata(source UnstructuredWithMetadata, target *UnstructuredWithMetadata) error { 166 s := pg.stepConfiguration(stepEditConfigurationMetadata) 167 target.Metadata.Path = fmt.Sprintf("%s/%s.yaml", s.Name, getVersionedName(target.Object)) 168 s.Exec.Args = []string{"-c", fmt.Sprintf("cp %s %s", target.Metadata.Path, source.Metadata.Path)} 169 return errors.Wrap(pg.target.Put(*target), errConfigurationMetadataOutput) 170 }