Skip to content

Commit 4f47217

Browse files
committed
globalize get dependency helper
- create a dependency helper replacing repetative parts of code - update template to use it
1 parent b8d62d3 commit 4f47217

File tree

2 files changed

+83
-25
lines changed

2 files changed

+83
-25
lines changed

cmd/scaffold-controller/data/controller/actuator.go.template

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@ import (
2525

2626
"{{ .GophercloudModule }}"
2727
corev1 "k8s.io/api/core/v1"
28-
{{- if len .ImportDependencies }}
29-
apierrors "k8s.io/apimachinery/pkg/api/errors"
30-
{{- end }}
3128
"k8s.io/utils/ptr"
3229
ctrl "sigs.k8s.io/controller-runtime"
3330
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -37,6 +34,9 @@ import (
3734
"github.com/k-orc/openstack-resource-controller/v2/internal/controllers/generic/progress"
3835
"github.com/k-orc/openstack-resource-controller/v2/internal/logging"
3936
"github.com/k-orc/openstack-resource-controller/v2/internal/osclients"
37+
{{- if len .ImportDependencies }}
38+
"github.com/k-orc/openstack-resource-controller/v2/internal/util/dependency"
39+
{{- end }}
4040
orcerrors "github.com/k-orc/openstack-resource-controller/v2/internal/util/errors"
4141
)
4242

@@ -106,41 +106,33 @@ func (actuator {{ .PackageName }}Actuator) ListOSResourcesForImport(ctx context.
106106
var reconcileStatus progress.ReconcileStatus
107107
{{- range .ImportDependencies }}
108108
{{ $depNameCamelCase := . | camelCase }}
109-
{{ $depNameCamelCase }} := &orcv1alpha1.{{ . }}{}
110-
if filter.{{ . }}Ref != nil {
111-
{{ $depNameCamelCase }}Key := client.ObjectKey{Name: string(*filter.{{ . }}Ref), Namespace: obj.Namespace}
112-
if err := actuator.k8sClient.Get(ctx, {{ $depNameCamelCase }}Key, {{ $depNameCamelCase }}); err != nil {
113-
if apierrors.IsNotFound(err) {
114-
reconcileStatus = reconcileStatus.WithReconcileStatus(
115-
progress.WaitingOnObject("{{ . }}", {{ $depNameCamelCase }}Key.Name, progress.WaitingOnCreation))
116-
} else {
117-
reconcileStatus = reconcileStatus.WithReconcileStatus(
118-
progress.WrapError(fmt.Errorf("fetching {{ $depNameCamelCase }} %s: %w", {{ $depNameCamelCase }}Key.Name, err)))
119-
}
120-
} else {
121-
if !orcv1alpha1.IsAvailable({{ $depNameCamelCase }}) || {{ $depNameCamelCase }}.Status.ID == nil {
122-
reconcileStatus = reconcileStatus.WithReconcileStatus(
123-
progress.WaitingOnObject("{{ . }}", {{ $depNameCamelCase }}Key.Name, progress.WaitingOnReady))
124-
}
125-
}
126-
}
109+
{{ $depNameCamelCase }}, rs := dependency.FetchDependency[*orcv1alpha1.{{ . }}, orcv1alpha1.{{ . }}](
110+
ctx, actuator.k8sClient, obj.Namespace,
111+
filter.{{ . }}Ref, "{{ . }}",
112+
func(dep *orcv1alpha1.{{ . }}) bool { return orcv1alpha1.IsAvailable(dep) && dep.Status.ID != nil },
113+
)
114+
reconcileStatus = reconcileStatus.WithReconcileStatus(rs)
127115
{{- end }}
128116

129-
if needsReschedule, _ := reconcileStatus.NeedsReschedule(); needsReschedule {
130-
return nil, reconcileStatus
117+
var {{ range $i, $dep := .ImportDependencies }}{{ if $i }}, {{ end }}{{ $dep | camelCase }}ID{{ end }} string
118+
{{- range .ImportDependencies }}
119+
{{ $depNameCamelCase := . | camelCase }}
120+
if {{ $depNameCamelCase }} != nil {
121+
{{ $depNameCamelCase }}ID = ptr.Deref({{ $depNameCamelCase }}.Status.ID, "")
131122
}
123+
{{- end }}
132124
{{- end }}
133125

134126
listOpts := {{ .GophercloudPackage }}.ListOpts{
135127
Name: string(ptr.Deref(filter.Name, "")),
136128
Description: string(ptr.Deref(filter.Description, "")),
137129
{{- range .ImportDependencies }}
138-
{{ . }}: ptr.Deref({{ . | camelCase }}.Status.ID, ""),
130+
{{ . }}ID: {{ . | camelCase }}ID,
139131
{{- end }}
140132
// TODO(scaffolding): Add more import filters
141133
}
142134

143-
return actuator.osClient.List{{ .Kind }}s(ctx, listOpts), nil
135+
return actuator.osClient.List{{ .Kind }}s(ctx, listOpts), {{ if len .ImportDependencies }}reconcileStatus{{ else }}nil{{ end }}
144136
}
145137

146138
func (actuator {{ .PackageName }}Actuator) CreateResource(ctx context.Context, obj orcObjectPT) (*osResourceT, progress.ReconcileStatus) {
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
Copyright 2025 The ORC Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package dependency
18+
19+
import (
20+
"context"
21+
"fmt"
22+
23+
apierrors "k8s.io/apimachinery/pkg/api/errors"
24+
"sigs.k8s.io/controller-runtime/pkg/client"
25+
26+
orcv1alpha1 "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1"
27+
"github.com/k-orc/openstack-resource-controller/v2/internal/controllers/generic/progress"
28+
)
29+
30+
// FetchDependency fetches a resource by name and checks if it's ready.
31+
// Unlike GetDependency on DeletionGuardDependency, this doesn't add finalizers
32+
// and is suitable for one-off lookups like resolving refs in import filters.
33+
//
34+
// If name is empty, returns (nil, nil) - no fetch is performed.
35+
//
36+
// Returns:
37+
// - The fetched object (nil if name is empty, not found, or not ready)
38+
// - ReconcileStatus indicating wait state or error (nil if name is empty)
39+
func FetchDependency[TP DependencyType[T], T any](
40+
ctx context.Context,
41+
k8sClient client.Client,
42+
namespace string,
43+
name *orcv1alpha1.KubernetesNameRef,
44+
kind string,
45+
isReady func(TP) bool,
46+
) (TP, progress.ReconcileStatus) {
47+
if name == nil {
48+
return nil, nil
49+
}
50+
51+
var obj TP = new(T)
52+
objectKey := client.ObjectKey{Name: string(*name), Namespace: namespace}
53+
54+
if err := k8sClient.Get(ctx, objectKey, obj); err != nil {
55+
if apierrors.IsNotFound(err) {
56+
return nil, progress.NewReconcileStatus().WaitingOnObject(kind, string(*name), progress.WaitingOnCreation)
57+
}
58+
return nil, progress.WrapError(fmt.Errorf("fetching %s %s: %w", kind, string(*name), err))
59+
}
60+
61+
if !isReady(obj) {
62+
return nil, progress.NewReconcileStatus().WaitingOnObject(kind, string(*name), progress.WaitingOnReady)
63+
}
64+
65+
return obj, nil
66+
}

0 commit comments

Comments
 (0)