Skip to content

Commit a57831b

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 a57831b

2 files changed

Lines changed: 78 additions & 23 deletions

File tree

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

Lines changed: 11 additions & 23 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,24 +106,12 @@ 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(
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

129117
if needsReschedule, _ := reconcileStatus.NeedsReschedule(); needsReschedule {
@@ -135,12 +123,12 @@ func (actuator {{ .PackageName }}Actuator) ListOSResourcesForImport(ctx context.
135123
Name: string(ptr.Deref(filter.Name, "")),
136124
Description: string(ptr.Deref(filter.Description, "")),
137125
{{- range .ImportDependencies }}
138-
{{ . }}: ptr.Deref({{ . | camelCase }}.Status.ID, ""),
126+
{{ . }}ID: ptr.Deref({{ . | camelCase }}.Status.ID, ""),
139127
{{- end }}
140128
// TODO(scaffolding): Add more import filters
141129
}
142130

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

146134
func (actuator {{ .PackageName }}Actuator) CreateResource(ctx context.Context, obj orcObjectPT) (*osResourceT, progress.ReconcileStatus) {
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
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+
// Always returns an object (empty struct if not found/ready/error) for safe field access.
35+
//
36+
// Returns:
37+
// - The fetched object (empty struct if name is nil, not found, not ready, or on error)
38+
// - ReconcileStatus indicating wait state or error (nil only if name is nil or object is ready)
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+
var obj TP = new(T)
48+
49+
if name == nil {
50+
return obj, nil
51+
}
52+
53+
objectKey := client.ObjectKey{Name: string(*name), Namespace: namespace}
54+
55+
if err := k8sClient.Get(ctx, objectKey, obj); err != nil {
56+
if apierrors.IsNotFound(err) {
57+
return obj, progress.NewReconcileStatus().WaitingOnObject(kind, string(*name), progress.WaitingOnCreation)
58+
}
59+
return obj, progress.WrapError(fmt.Errorf("fetching %s %s: %w", kind, string(*name), err))
60+
}
61+
62+
if !isReady(obj) {
63+
return obj, progress.NewReconcileStatus().WaitingOnObject(kind, string(*name), progress.WaitingOnReady)
64+
}
65+
66+
return obj, nil
67+
}

0 commit comments

Comments
 (0)