Skip to content

Commit c71e83f

Browse files
committed
Add global infrastructure values
- infra.Status.ControlPlaneTopology is how we can programmatically determine the type of cluster we're on. - External=HyperShift - SingleReplica/HighlyAvailable-Traditional/Normal - infra.Status.APIServerURL is how we can programmatically determine the api address of the cluster. - In the past we have gotten away with this because we could use the clusterDomain but HyperShift uses the DNS name of the ELB it provisions for the hosted cluster. - In addition to these changes, added a sample pattern crd for testing the operator.
1 parent 9990fff commit c71e83f

7 files changed

Lines changed: 75 additions & 121 deletions

File tree

cmd/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import (
4343
gitopsv1alpha1 "github.com/hybrid-cloud-patterns/patterns-operator/api/v1alpha1"
4444
controllers "github.com/hybrid-cloud-patterns/patterns-operator/internal/controller"
4545
"github.com/hybrid-cloud-patterns/patterns-operator/version"
46+
configv1 "github.com/openshift/api/config/v1"
4647
corev1 "k8s.io/api/core/v1"
4748
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
4849
"k8s.io/client-go/kubernetes"
@@ -58,6 +59,7 @@ func init() {
5859
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
5960

6061
utilruntime.Must(gitopsv1alpha1.AddToScheme(scheme))
62+
utilruntime.Must(configv1.AddToScheme(scheme))
6163
//+kubebuilder:scaffold:scheme
6264
}
6365

config/manager/kustomization.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ kind: Kustomization
1313
images:
1414
- name: controller
1515
newName: quay.io/validatedpatterns/patterns-operator
16-
newTag: 0.0.63
16+
newTag: 0.0.64

config/samples/test-pattern.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
apiVersion: gitops.hybrid-cloud-patterns.io/v1alpha1
2+
kind: Pattern
3+
metadata:
4+
name: test-pattern-infra-params
5+
namespace: default
6+
spec:
7+
clusterGroupName: test-group
8+
gitSpec:
9+
targetRepo: "https://github.com/validatedpatterns/multicloud-gitops"
10+
targetRevision: "main"
11+
multiSourceConfig:
12+
enabled: false
13+
helmRepoUrl: "https://charts.validatedpatterns.io/"

hack/operator-build-deploy.sh

Lines changed: 0 additions & 96 deletions
This file was deleted.

internal/controller/argo.go

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"strconv"
2525
"strings"
2626

27+
configv1 "github.com/openshift/api/config/v1"
2728
v1 "k8s.io/api/core/v1"
2829
"k8s.io/apimachinery/pkg/api/resource"
2930
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -347,7 +348,7 @@ func getArgoCD(client dynamic.Interface, name, namespace string) (*argooperator.
347348
return argo, err
348349
}
349350

350-
func newApplicationParameters(p *api.Pattern) []argoapi.HelmParameter {
351+
func newApplicationParameters(p *api.Pattern, infra *configv1.Infrastructure) []argoapi.HelmParameter {
351352
parameters := []argoapi.HelmParameter{
352353
{
353354
Name: "global.pattern",
@@ -411,6 +412,20 @@ func newApplicationParameters(p *api.Pattern) []argoapi.HelmParameter {
411412
Value: p.Spec.ExperimentalCapabilities,
412413
},
413414
}
415+
if infra != nil {
416+
log.Printf("Adding infrastructure parameters: clusterAPIServerURL=%s, controlPlaneTopology=%s", infra.Status.APIServerURL, infra.Status.ControlPlaneTopology)
417+
parameters = append(parameters, argoapi.HelmParameter{
418+
Name: "global.clusterAPIServerURL",
419+
Value: infra.Status.APIServerURL,
420+
},
421+
argoapi.HelmParameter{
422+
Name: "global.controlPlaneTopology",
423+
Value: string(infra.Status.ControlPlaneTopology),
424+
},
425+
)
426+
} else {
427+
log.Printf("Warning: infra is nil, skipping infrastructure parameters (global.clusterAPIServerURL and global.controlPlaneTopology)")
428+
}
414429
parameters = append(parameters, argoapi.HelmParameter{
415430
Name: "global.multiSourceTargetRevision",
416431
Value: getClusterGroupChartVersion(p),
@@ -491,7 +506,7 @@ func newApplicationValues(p *api.Pattern) string {
491506
// libraries. E.g. a string '/overrides/values-{{ $.Values.global.clusterPlatform }}.yaml'
492507
// will be converted to '/overrides/values-AWS.yaml'
493508
// 4. We return the list of templated strings back as an array
494-
func getSharedValueFiles(p *api.Pattern, prefix string) ([]string, error) {
509+
func getSharedValueFiles(p *api.Pattern, prefix string, infra *configv1.Infrastructure) ([]string, error) {
495510
gitDir := p.Status.LocalCheckoutPath
496511
if _, err := os.Stat(gitDir); err != nil {
497512
return nil, fmt.Errorf("%s path does not exist", gitDir)
@@ -521,7 +536,7 @@ func getSharedValueFiles(p *api.Pattern, prefix string) ([]string, error) {
521536
if !ok {
522537
return nil, fmt.Errorf("type assertion failed at index %d: Not a string", i)
523538
}
524-
valueMap := convertArgoHelmParametersToMap(newApplicationParameters(p))
539+
valueMap := convertArgoHelmParametersToMap(newApplicationParameters(p, infra))
525540
templatedString, err := helmTpl(str, valueFiles, valueMap)
526541

527542
// we only log an error, but try to keep going
@@ -595,9 +610,9 @@ func commonApplicationSpec(p *api.Pattern, sources []argoapi.ApplicationSource)
595610
return spec
596611
}
597612

598-
func commonApplicationSourceHelm(p *api.Pattern, prefix string) *argoapi.ApplicationSourceHelm {
613+
func commonApplicationSourceHelm(p *api.Pattern, prefix string, infra *configv1.Infrastructure) *argoapi.ApplicationSourceHelm {
599614
valueFiles := newApplicationValueFiles(p, prefix)
600-
sharedValueFiles, err := getSharedValueFiles(p, prefix)
615+
sharedValueFiles, err := getSharedValueFiles(p, prefix, infra)
601616
if err != nil {
602617
fmt.Printf("Could not fetch sharedValueFiles: %s", err)
603618
}
@@ -607,7 +622,7 @@ func commonApplicationSourceHelm(p *api.Pattern, prefix string) *argoapi.Applica
607622
ValueFiles: valueFiles,
608623

609624
// Parameters is a list of Helm parameters which are passed to the helm template command upon manifest generation
610-
Parameters: newApplicationParameters(p),
625+
Parameters: newApplicationParameters(p, infra),
611626

612627
// This is to be able to pass down the extraParams to the single applications
613628
Values: newApplicationValues(p),
@@ -644,7 +659,7 @@ func newArgoOperatorApplication(p *api.Pattern, spec *argoapi.ApplicationSpec) *
644659
return &app
645660
}
646661

647-
func newSourceApplication(p *api.Pattern) *argoapi.Application {
662+
func newSourceApplication(p *api.Pattern, infra *configv1.Infrastructure) *argoapi.Application {
648663
// Argo uses...
649664
// r := regexp.MustCompile("(/|:)")
650665
// root := filepath.Join(os.TempDir(), r.ReplaceAllString(NormalizeGitURL(rawRepoURL), "_"))
@@ -653,15 +668,15 @@ func newSourceApplication(p *api.Pattern) *argoapi.Application {
653668
RepoURL: p.Spec.GitConfig.TargetRepo,
654669
Path: "common/clustergroup",
655670
TargetRevision: p.Spec.GitConfig.TargetRevision,
656-
Helm: commonApplicationSourceHelm(p, ""),
671+
Helm: commonApplicationSourceHelm(p, "", infra),
657672
}
658673
spec := commonApplicationSpec(p, []argoapi.ApplicationSource{source})
659674

660675
spec.SyncPolicy = commonSyncPolicy(p)
661676
return newArgoOperatorApplication(p, spec)
662677
}
663678

664-
func newMultiSourceApplication(p *api.Pattern) *argoapi.Application {
679+
func newMultiSourceApplication(p *api.Pattern, infra *configv1.Infrastructure) *argoapi.Application {
665680
sources := []argoapi.ApplicationSource{}
666681
var baseSource *argoapi.ApplicationSource
667682

@@ -681,14 +696,14 @@ func newMultiSourceApplication(p *api.Pattern) *argoapi.Application {
681696
RepoURL: p.Spec.MultiSourceConfig.HelmRepoUrl,
682697
Chart: "clustergroup",
683698
TargetRevision: getClusterGroupChartVersion(p),
684-
Helm: commonApplicationSourceHelm(p, "$patternref"),
699+
Helm: commonApplicationSourceHelm(p, "$patternref", infra),
685700
}
686701
} else {
687702
baseSource = &argoapi.ApplicationSource{
688703
RepoURL: p.Spec.MultiSourceConfig.ClusterGroupGitRepoUrl,
689704
Path: ".",
690705
TargetRevision: p.Spec.MultiSourceConfig.ClusterGroupChartGitRevision,
691-
Helm: commonApplicationSourceHelm(p, "$patternref"),
706+
Helm: commonApplicationSourceHelm(p, "$patternref", infra),
692707
}
693708
}
694709
sources = append(sources, *baseSource)
@@ -712,14 +727,14 @@ func getClusterGroupChartVersion(p *api.Pattern) string {
712727
return clusterGroupChartVersion
713728
}
714729

715-
func newArgoApplication(p *api.Pattern) *argoapi.Application {
730+
func newArgoApplication(p *api.Pattern, infra *configv1.Infrastructure) *argoapi.Application {
716731
// -- ArgoCD Application
717732
var targetApp *argoapi.Application
718733

719734
if *p.Spec.MultiSourceConfig.Enabled {
720-
targetApp = newMultiSourceApplication(p)
735+
targetApp = newMultiSourceApplication(p, infra)
721736
} else {
722-
targetApp = newSourceApplication(p)
737+
targetApp = newSourceApplication(p, infra)
723738
}
724739

725740
return targetApp

internal/controller/argo_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ var _ = Describe("Argo Pattern", func() {
9494
TargetRevision: pattern.Spec.GitConfig.TargetRevision,
9595
Helm: &argoapi.ApplicationSourceHelm{
9696
ValueFiles: newApplicationValueFiles(pattern, ""),
97-
Parameters: newApplicationParameters(pattern),
97+
Parameters: newApplicationParameters(pattern, nil),
9898
Values: newApplicationValues(pattern),
9999
IgnoreMissingValueFiles: true,
100100
},
@@ -137,7 +137,7 @@ var _ = Describe("Argo Pattern", func() {
137137
// This is needed to debug any failures as gomega truncates the diff output
138138
format.MaxDepth = 100
139139
format.MaxLength = 0
140-
Expect(newArgoApplication(pattern)).To(Equal(argoApp))
140+
Expect(newArgoApplication(pattern, nil)).To(Equal(argoApp))
141141
})
142142
})
143143
Context("Default multi source", func() {
@@ -160,7 +160,7 @@ var _ = Describe("Argo Pattern", func() {
160160
*appSource,
161161
}
162162
multiSourceArgoApp.Spec.Sources[1].Helm.ValueFiles = newApplicationValueFiles(pattern, "$patternref")
163-
Expect(newMultiSourceApplication(pattern)).To(Equal(multiSourceArgoApp))
163+
Expect(newMultiSourceApplication(pattern, nil)).To(Equal(multiSourceArgoApp))
164164
})
165165
})
166166
Context("multiSource with MultiSourceClusterGroupChartGitRevision set", func() {
@@ -184,7 +184,7 @@ var _ = Describe("Argo Pattern", func() {
184184
*appSource,
185185
}
186186
multiSourceArgoApp.Spec.Sources[1].Helm.ValueFiles = newApplicationValueFiles(pattern, "$patternref")
187-
Expect(newMultiSourceApplication(pattern)).To(Equal(multiSourceArgoApp))
187+
Expect(newMultiSourceApplication(pattern, nil)).To(Equal(multiSourceArgoApp))
188188
})
189189
})
190190
})
@@ -405,7 +405,7 @@ var _ = Describe("Argo Pattern", func() {
405405
}
406406
})
407407
It("Test default newApplicationParameters", func() {
408-
Expect(newApplicationParameters(pattern)).To(Equal(append(appParameters,
408+
Expect(newApplicationParameters(pattern, nil)).To(Equal(append(appParameters,
409409
argoapi.HelmParameter{
410410
Name: "global.multiSourceSupport",
411411
Value: "false",
@@ -439,7 +439,7 @@ var _ = Describe("Argo Pattern", func() {
439439
Value: "test2value",
440440
},
441441
}
442-
Expect(newApplicationParameters(pattern)).To(Equal(append(appParameters,
442+
Expect(newApplicationParameters(pattern, nil)).To(Equal(append(appParameters,
443443
argoapi.HelmParameter{
444444
Name: "global.multiSourceSupport",
445445
Value: "false",
@@ -472,7 +472,7 @@ var _ = Describe("Argo Pattern", func() {
472472
It("Test newApplicationParameters with multiSource", func() {
473473
tmpBool := true
474474
pattern.Spec.MultiSourceConfig.Enabled = &tmpBool
475-
Expect(newApplicationParameters(pattern)).To(Equal(append(appParameters,
475+
Expect(newApplicationParameters(pattern, nil)).To(Equal(append(appParameters,
476476
argoapi.HelmParameter{
477477
Name: "global.multiSourceSupport",
478478
Value: "true",
@@ -500,7 +500,7 @@ var _ = Describe("Argo Pattern", func() {
500500
var sources []argoapi.ApplicationSource
501501

502502
BeforeEach(func() {
503-
multiSourceArgoApp = newMultiSourceApplication(pattern)
503+
multiSourceArgoApp = newMultiSourceApplication(pattern, nil)
504504
sources = multiSourceArgoApp.Spec.Sources
505505
})
506506
It("compareSource() function identical", func() {

internal/controller/pattern_controller.go

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
kerrors "k8s.io/apimachinery/pkg/api/errors"
3131
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3232
"k8s.io/apimachinery/pkg/runtime"
33+
"k8s.io/apimachinery/pkg/types"
3334
"k8s.io/client-go/dynamic"
3435
"k8s.io/client-go/rest"
3536
ctrl "sigs.k8s.io/controller-runtime"
@@ -40,6 +41,7 @@ import (
4041

4142
argoapi "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
4243
argoclient "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned"
44+
configv1 "github.com/openshift/api/config/v1"
4345
configclient "github.com/openshift/client-go/config/clientset/versioned"
4446
routeclient "github.com/openshift/client-go/route/clientset/versioned"
4547
olmclient "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned"
@@ -223,7 +225,17 @@ func (r *PatternReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
223225
return r.actionPerformed(qualifiedInstance, ret, err)
224226
}
225227

226-
targetApp := newArgoApplication(qualifiedInstance)
228+
// Fetch infrastructure for cluster API server URL and control plane topology
229+
infra := &configv1.Infrastructure{}
230+
if err := r.Get(ctx, types.NamespacedName{Name: "cluster"}, infra); err != nil {
231+
// If infrastructure cannot be fetched, continue with nil (handled in newApplicationParameters)
232+
log.Printf("Warning: Could not fetch infrastructure object: %v. Parameters global.clusterAPIServerURL and global.controlPlaneTopology will not be set.", err)
233+
infra = nil
234+
} else {
235+
log.Printf("Successfully fetched infrastructure: APIServerURL=%s, ControlPlaneTopology=%s", infra.Status.APIServerURL, infra.Status.ControlPlaneTopology)
236+
}
237+
238+
targetApp := newArgoApplication(qualifiedInstance, infra)
227239
_ = controllerutil.SetOwnerReference(qualifiedInstance, targetApp, r.Scheme)
228240
app, err := getApplication(r.argoClient, applicationName(qualifiedInstance), clusterWideNS)
229241
if app == nil {
@@ -510,7 +522,15 @@ func (r *PatternReconciler) finalizeObject(instance *api.Pattern) error {
510522
}
511523
ns := getClusterWideArgoNamespace()
512524

513-
targetApp := newArgoApplication(qualifiedInstance)
525+
// Fetch infrastructure for cluster API server URL and control plane topology
526+
infra := &configv1.Infrastructure{}
527+
if err := r.Get(context.TODO(), types.NamespacedName{Name: "cluster"}, infra); err != nil {
528+
// If infrastructure cannot be fetched, continue with nil (handled in newApplicationParameters)
529+
log.Printf("Warning: Could not fetch infrastructure object during finalization: %v. Parameters global.clusterAPIServerURL and global.controlPlaneTopology will not be set.", err)
530+
infra = nil
531+
}
532+
533+
targetApp := newArgoApplication(qualifiedInstance, infra)
514534
_ = controllerutil.SetOwnerReference(qualifiedInstance, targetApp, r.Scheme)
515535

516536
app, _ := getApplication(r.argoClient, applicationName(qualifiedInstance), ns)

0 commit comments

Comments
 (0)