Skip to content

Commit 51ba1a9

Browse files
ybettank8s-ci-robot
authored andcommitted
Adding the mic package.
This package will be used by the `Module` reconciler in the following commits. Signed-off-by: Yoni Bettan <[email protected]>
1 parent 2d5580f commit 51ba1a9

File tree

4 files changed

+274
-0
lines changed

4 files changed

+274
-0
lines changed

internal/mic/mic.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package mic
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
kmmv1beta1 "github.com/kubernetes-sigs/kernel-module-management/api/v1beta1"
8+
v1 "k8s.io/api/core/v1"
9+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10+
"k8s.io/apimachinery/pkg/runtime"
11+
"sigs.k8s.io/controller-runtime/pkg/client"
12+
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
13+
"sigs.k8s.io/controller-runtime/pkg/log"
14+
)
15+
16+
//go:generate mockgen -source=mic.go -package=mic -destination=mock_mic.go
17+
18+
type MIC interface {
19+
ApplyMIC(ctx context.Context, name, ns string, images []kmmv1beta1.ModuleImageSpec,
20+
imageRepoSecret *v1.LocalObjectReference, owner metav1.Object) error
21+
}
22+
23+
type micImpl struct {
24+
client client.Client
25+
scheme *runtime.Scheme
26+
}
27+
28+
func NewModuleImagesConfigAPI(client client.Client, scheme *runtime.Scheme) MIC {
29+
return &micImpl{
30+
client: client,
31+
scheme: scheme,
32+
}
33+
}
34+
35+
func (mici *micImpl) ApplyMIC(ctx context.Context, name, ns string, images []kmmv1beta1.ModuleImageSpec,
36+
imageRepoSecret *v1.LocalObjectReference, owner metav1.Object) error {
37+
38+
logger := log.FromContext(ctx)
39+
40+
mic := &kmmv1beta1.ModuleImagesConfig{
41+
ObjectMeta: metav1.ObjectMeta{
42+
Name: name,
43+
Namespace: ns,
44+
},
45+
}
46+
47+
opRes, err := controllerutil.CreateOrPatch(ctx, mici.client, mic, func() error {
48+
49+
mic.Spec = kmmv1beta1.ModuleImagesConfigSpec{
50+
Images: images,
51+
ImageRepoSecret: imageRepoSecret,
52+
}
53+
54+
return controllerutil.SetOwnerReference(owner, mic, mici.scheme)
55+
})
56+
if err != nil {
57+
return fmt.Errorf("failed to create or patch %s/%s: %v", ns, name, err)
58+
}
59+
60+
logger.Info("Applied MIC", "name", name, "namespace", ns, "result", opRes)
61+
62+
return nil
63+
}

internal/mic/mic_test.go

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package mic
2+
3+
import (
4+
"context"
5+
6+
kmmv1beta1 "github.com/kubernetes-sigs/kernel-module-management/api/v1beta1"
7+
v1beta1 "github.com/kubernetes-sigs/kernel-module-management/api/v1beta1"
8+
"github.com/kubernetes-sigs/kernel-module-management/internal/client"
9+
. "github.com/onsi/ginkgo/v2"
10+
. "github.com/onsi/gomega"
11+
gomock "go.uber.org/mock/gomock"
12+
v1 "k8s.io/api/core/v1"
13+
k8serrors "k8s.io/apimachinery/pkg/api/errors"
14+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
15+
"k8s.io/apimachinery/pkg/runtime/schema"
16+
"k8s.io/apimachinery/pkg/types"
17+
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
18+
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
19+
)
20+
21+
var _ = Describe("ApplyMIC", func() {
22+
23+
const (
24+
micName = "my-name"
25+
micNamespace = "my-namespace"
26+
)
27+
28+
var (
29+
ctx context.Context
30+
ctrl *gomock.Controller
31+
mockClient *client.MockClient
32+
micAPI MIC
33+
)
34+
35+
BeforeEach(func() {
36+
ctx = context.Background()
37+
ctrl = gomock.NewController(GinkgoT())
38+
mockClient = client.NewMockClient(ctrl)
39+
micAPI = NewModuleImagesConfigAPI(mockClient, scheme)
40+
utilruntime.Must(v1beta1.AddToScheme(scheme))
41+
})
42+
43+
It("should fail if we failed to create or patch", func() {
44+
45+
mockClient.EXPECT().Get(ctx, gomock.Any(), gomock.Any()).Return(nil)
46+
47+
err := micAPI.ApplyMIC(ctx, micName, micNamespace, []v1beta1.ModuleImageSpec{}, nil, nil)
48+
49+
Expect(err).To(HaveOccurred())
50+
Expect(err.Error()).To(ContainSubstring("failed to create or patch"))
51+
Expect(err.Error()).To(ContainSubstring("cannot call SetOwnerReference"))
52+
})
53+
54+
It("should create the MIC if it doesn't exist", func() {
55+
56+
gomock.InOrder(
57+
mockClient.EXPECT().Get(ctx, types.NamespacedName{Name: micName, Namespace: micNamespace},
58+
gomock.Any()).Return(k8serrors.NewNotFound(schema.GroupResource{}, micName)),
59+
mockClient.EXPECT().Create(ctx, gomock.Any()).Return(nil),
60+
)
61+
62+
images := []kmmv1beta1.ModuleImageSpec{
63+
{
64+
Image: "example.registry.com/org/user/image1:tag",
65+
},
66+
{
67+
Image: "example.registry.com/org/user/image2:tag",
68+
},
69+
}
70+
71+
imageRepoSecret :=
72+
&v1.LocalObjectReference{
73+
Name: "some-secret",
74+
}
75+
76+
owner := &kmmv1beta1.Module{
77+
ObjectMeta: metav1.ObjectMeta{
78+
Name: "my-module",
79+
Namespace: micNamespace,
80+
},
81+
}
82+
83+
err := micAPI.ApplyMIC(ctx, micName, micNamespace, images, imageRepoSecret, owner)
84+
85+
Expect(err).NotTo(HaveOccurred())
86+
})
87+
88+
It("should patch the MIC if it exists", func() {
89+
90+
gomock.InOrder(
91+
mockClient.EXPECT().Get(ctx, types.NamespacedName{Name: micName, Namespace: micNamespace}, gomock.Any()).DoAndReturn(
92+
func(_ interface{}, _ interface{}, mic *kmmv1beta1.ModuleImagesConfig, _ ...ctrlclient.GetOption) error {
93+
mic.ObjectMeta = metav1.ObjectMeta{
94+
Name: micName,
95+
Namespace: micNamespace,
96+
}
97+
mic.Spec = kmmv1beta1.ModuleImagesConfigSpec{
98+
Images: []kmmv1beta1.ModuleImageSpec{
99+
{
100+
Image: "example.registry.com/org/user/image1:tag",
101+
},
102+
{
103+
Image: "example.registry.com/org/user/image2:tag",
104+
},
105+
},
106+
ImageRepoSecret: &v1.LocalObjectReference{
107+
Name: "some-secret",
108+
},
109+
}
110+
return nil
111+
},
112+
),
113+
mockClient.EXPECT().Patch(ctx, gomock.Any(), gomock.Any()),
114+
)
115+
116+
images := []kmmv1beta1.ModuleImageSpec{
117+
{
118+
Image: "example.registry.com/org/user/image3:tag",
119+
},
120+
}
121+
122+
owner := &kmmv1beta1.Module{
123+
ObjectMeta: metav1.ObjectMeta{
124+
Name: "my-module",
125+
Namespace: micNamespace,
126+
},
127+
}
128+
129+
err := micAPI.ApplyMIC(ctx, micName, micNamespace, images, nil, owner)
130+
131+
Expect(err).NotTo(HaveOccurred())
132+
})
133+
})

internal/mic/mock_mic.go

Lines changed: 56 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/mic/suite_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package mic
2+
3+
import (
4+
"testing"
5+
6+
"github.com/kubernetes-sigs/kernel-module-management/internal/test"
7+
. "github.com/onsi/ginkgo/v2"
8+
. "github.com/onsi/gomega"
9+
"k8s.io/apimachinery/pkg/runtime"
10+
)
11+
12+
var scheme *runtime.Scheme
13+
14+
func TestSuite(t *testing.T) {
15+
RegisterFailHandler(Fail)
16+
17+
var err error
18+
scheme, err = test.TestScheme()
19+
Expect(err).NotTo(HaveOccurred())
20+
21+
RunSpecs(t, "MIC Suite")
22+
}

0 commit comments

Comments
 (0)