diff --git a/Dockerfile b/Dockerfile index 996afca..817efa8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,7 +9,7 @@ RUN curl -L -o /tmp/download-binaries.sh https://raw.githubusercontent.com/kuber && /tmp/download-binaries.sh /usr/local/kubebuilder/bin WORKDIR /go/src/github.com/summerwind/whitebox-controller -COPY go.mod go.sum . +COPY go.mod go.sum ./ RUN go mod download COPY . /workspace diff --git a/config/config.go b/config/config.go index d6014c7..a5959ee 100644 --- a/config/config.go +++ b/config/config.go @@ -149,6 +149,7 @@ func (c *DependentConfig) Validate() error { type ReferenceConfig struct { schema.GroupVersionKind NameFieldPath string `json:"nameFieldPath"` + NamespaceFieldPath string `json:"namespaceFieldPath,omitempty"` } func (c *ReferenceConfig) Validate() error { diff --git a/reconciler/reconciler.go b/reconciler/reconciler.go index 6358a88..ba9ebea 100644 --- a/reconciler/reconciler.go +++ b/reconciler/reconciler.go @@ -290,12 +290,29 @@ func (r *Reconciler) getReferences(res *unstructured.Unstructured) (map[string][ continue } + refNamespaces := []string{} + if len(ref.NamespaceFieldPath) > 0 { + refNss, err := getReferenceNames(res, ref.NamespaceFieldPath) + if err != nil { + return nil, fmt.Errorf("failed to get reference namespace list: %v", err) + } + if len(refNss) != len(refNames) { + return nil, fmt.Errorf("Reference name and namespace must match: %v", err) + } + refNamespaces = refNss + } + for i := range refNames { refRes := &unstructured.Unstructured{} refRes.SetGroupVersionKind(ref.GroupVersionKind) + refResNamespace := res.GetNamespace() + if len(refNamespaces) > 0 { + refResNamespace = refNamespaces[i] + } + nn := types.NamespacedName{ - Namespace: res.GetNamespace(), + Namespace: refResNamespace, Name: refNames[i], } err = r.Get(context.TODO(), nn, refRes) @@ -303,7 +320,7 @@ func (r *Reconciler) getReferences(res *unstructured.Unstructured) (map[string][ if apierrors.IsNotFound(err) { continue } - return nil, fmt.Errorf("failed to get a resource '%s/%s': %v", res.GetNamespace(), refNames[i], err) + return nil, fmt.Errorf("failed to get a resource '%s/%s': %v", refResNamespace, refNames[i], err) } refs[key] = append(refs[key], refRes) diff --git a/reconciler/reconciler_test.go b/reconciler/reconciler_test.go index 46b99c4..d6606fe 100644 --- a/reconciler/reconciler_test.go +++ b/reconciler/reconciler_test.go @@ -714,7 +714,7 @@ func TestIsDeleting(t *testing.T) { rc := newResourceConfig() object := newObject(rc.GroupVersionKind, "test") deleting := newObject(rc.GroupVersionKind, "test") - SetNestedField(deleting.Object, string(time.Now().Unix()), "metadata", "deletionTimestamp") + SetNestedField(deleting.Object, fmt.Sprint(time.Now().Unix()), "metadata", "deletionTimestamp") Expect(isDeleting(object)).To(BeFalse()) Expect(isDeleting(deleting)).To(BeTrue())