Skip to content

Commit 693f08e

Browse files
committed
feat: support create/modify operations with res without owner in adapter
This will allow controllers create/modify resources without owners. Signed-off-by: Artem Chernyshev <[email protected]>
1 parent b9b3e44 commit 693f08e

File tree

6 files changed

+86
-8
lines changed

6 files changed

+86
-8
lines changed

pkg/controller/runtime.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,14 @@ func WithOwner(owner string) DeleteOption {
150150
return owned.WithOwner(owner)
151151
}
152152

153+
// CreateOption for operation Create.
154+
type CreateOption = owned.CreateOption
155+
156+
// WithCreateNoOwner creates the resource without setting the owner.
157+
func WithCreateNoOwner() CreateOption {
158+
return owned.WithCreateNoOwner()
159+
}
160+
153161
// ModifyOption for operation Modify.
154162
type ModifyOption = owned.ModifyOption
155163

@@ -162,3 +170,8 @@ func WithExpectedPhase(phase resource.Phase) ModifyOption {
162170
func WithExpectedPhaseAny() ModifyOption {
163171
return owned.WithExpectedPhaseAny()
164172
}
173+
174+
// WithModifyNoOwner creates/updates the resource without setting the controller as the owner.
175+
func WithModifyNoOwner() ModifyOption {
176+
return owned.WithModifyNoOwner()
177+
}

pkg/controller/runtime/internal/controllerstate/adapter.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ func (adapter *StateAdapter) ContextWithTeardown(ctx context.Context, resourcePo
169169
}
170170

171171
// Create implements controller.Runtime interface.
172-
func (adapter *StateAdapter) Create(ctx context.Context, r resource.Resource) error {
172+
func (adapter *StateAdapter) Create(ctx context.Context, r resource.Resource, options ...controller.CreateOption) error {
173173
if err := adapter.UpdateLimiter.Wait(ctx); err != nil {
174174
return fmt.Errorf("create rate limited: %w", err)
175175
}
@@ -179,7 +179,7 @@ func (adapter *StateAdapter) Create(ctx context.Context, r resource.Resource) er
179179
r.Metadata().Namespace(), r.Metadata().Type(), adapter.Name, r.Metadata().ID())
180180
}
181181

182-
return adapter.OwnedState.Create(ctx, r)
182+
return adapter.OwnedState.Create(ctx, r, options...)
183183
}
184184

185185
// Update implements controller.Runtime interface.

pkg/controller/runtime/internal/rruntime/state.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ import (
99

1010
"github.com/cosi-project/runtime/pkg/controller"
1111
"github.com/cosi-project/runtime/pkg/resource"
12+
"github.com/cosi-project/runtime/pkg/state/owned"
1213
)
1314

1415
// Create augments StateAdapter Create with output tracking.
15-
func (adapter *Adapter) Create(ctx context.Context, r resource.Resource) error {
16-
err := adapter.StateAdapter.Create(ctx, r)
16+
func (adapter *Adapter) Create(ctx context.Context, r resource.Resource, options ...owned.CreateOption) error {
17+
err := adapter.StateAdapter.Create(ctx, r, options...)
1718

1819
if adapter.outputTracker != nil {
1920
adapter.outputTracker[makeOutputTrackingID(r.Metadata())] = struct{}{}

pkg/state/owned/owned.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ type Reader interface {
2626
//
2727
// Write methods enforce that the resources are owned by the designated owner.
2828
type Writer interface {
29-
Create(context.Context, resource.Resource) error
29+
Create(context.Context, resource.Resource, ...CreateOption) error
3030
Update(context.Context, resource.Resource) error
3131
Modify(context.Context, resource.Resource, func(resource.Resource) error, ...ModifyOption) error
3232
ModifyWithResult(context.Context, resource.Resource, func(resource.Resource) error, ...ModifyOption) (resource.Resource, error)
@@ -69,12 +69,28 @@ func ToDeleteOptions(opts ...DeleteOption) DeleteOptions {
6969
return options
7070
}
7171

72+
// CreateOptions for operation Create.
73+
type CreateOptions struct {
74+
WithNoOwner bool
75+
}
76+
77+
// WithCreateNoOwner creates the resource without setting the owner.
78+
func WithCreateNoOwner() CreateOption {
79+
return func(o *CreateOptions) {
80+
o.WithNoOwner = true
81+
}
82+
}
83+
84+
// CreateOption for operation Create.
85+
type CreateOption func(*CreateOptions)
86+
7287
// ModifyOption for operation Modify.
7388
type ModifyOption func(*ModifyOptions)
7489

7590
// ModifyOptions for operation Modify.
7691
type ModifyOptions struct {
7792
ExpectedPhase *resource.Phase
93+
WithNoOwner bool
7894
}
7995

8096
// WithExpectedPhase allows to specify expected phase of the resource.
@@ -91,6 +107,13 @@ func WithExpectedPhaseAny() ModifyOption {
91107
}
92108
}
93109

110+
// WithModifyNoOwner creates/updates the resource without setting the owner.
111+
func WithModifyNoOwner() ModifyOption {
112+
return func(o *ModifyOptions) {
113+
o.WithNoOwner = true
114+
}
115+
}
116+
94117
// ToModifyOptions converts variadic options to ModifyOptions.
95118
func ToModifyOptions(opts ...ModifyOption) ModifyOptions {
96119
phase := resource.PhaseRunning

pkg/state/owned/owned_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,26 @@ func TestOwned(t *testing.T) {
123123

124124
rtestutils.AssertNoResource[*A](ctx, t, st, r1.Metadata().ID())
125125
rtestutils.AssertNoResource[*A](ctx, t, st, r2.Metadata().ID())
126+
127+
r3 := NewA("r3")
128+
129+
err = ownedState1.Modify(ctx, r3, func(r resource.Resource) error {
130+
return nil
131+
}, owned.WithModifyNoOwner())
132+
require.NoError(t, err)
133+
134+
res, err := ownedState1.Get(ctx, r3.Metadata())
135+
136+
require.NoError(t, err)
137+
require.Empty(t, res.Metadata().Owner())
138+
139+
r4 := NewA("r4")
140+
141+
err = ownedState1.Create(ctx, r4, owned.WithCreateNoOwner())
142+
require.NoError(t, err)
143+
144+
res, err = ownedState1.Get(ctx, r4.Metadata())
145+
146+
require.NoError(t, err)
147+
require.Empty(t, res.Metadata().Owner())
126148
}

pkg/state/owned/state.go

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,20 @@ func (st *State) ContextWithTeardown(ctx context.Context, ptr resource.Pointer)
4343
// Create creates a resource in the state.
4444
//
4545
// Create enforces that the resource is owned by the designated owner.
46-
func (st *State) Create(ctx context.Context, res resource.Resource) error {
47-
return st.state.Create(ctx, res, state.WithCreateOwner(st.owner))
46+
func (st *State) Create(ctx context.Context, res resource.Resource, options ...CreateOption) error {
47+
var opts CreateOptions
48+
49+
for _, o := range options {
50+
o(&opts)
51+
}
52+
53+
owner := st.owner
54+
55+
if opts.WithNoOwner {
56+
owner = ""
57+
}
58+
59+
return st.state.Create(ctx, res, state.WithCreateOwner(owner))
4860
}
4961

5062
// Update updates a resource in the state.
@@ -67,9 +79,16 @@ func (st *State) Modify(ctx context.Context, emptyResource resource.Resource, up
6779
//
6880
// ModifyWithResult enforces that the resource is owned by the designated owner.
6981
func (st *State) ModifyWithResult(ctx context.Context, emptyResource resource.Resource, updateFunc func(resource.Resource) error, options ...ModifyOption) (resource.Resource, error) {
70-
updateOptions := []state.UpdateOption{state.WithUpdateOwner(st.owner)}
82+
owner := st.owner
7183

7284
modifyOptions := ToModifyOptions(options...)
85+
86+
if modifyOptions.WithNoOwner {
87+
owner = ""
88+
}
89+
90+
updateOptions := []state.UpdateOption{state.WithUpdateOwner(owner)}
91+
7392
if modifyOptions.ExpectedPhase != nil {
7493
updateOptions = append(updateOptions, state.WithExpectedPhase(*modifyOptions.ExpectedPhase))
7594
} else {

0 commit comments

Comments
 (0)