Skip to content

Commit fd9b11b

Browse files
Merge pull request #51 from nunnatsa/auto_sync_upstream_2023-12-24-07-25
Auto sync upstream 2023-12-24 07:25 + update OWNER file
2 parents 31fd29a + b24379c commit fd9b11b

File tree

16 files changed

+437
-62
lines changed

16 files changed

+437
-62
lines changed

.github/workflows/test.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ jobs:
5454
uses: golangci/golangci-lint-action@v3
5555
with:
5656
args: --timeout=5m -v
57-
version: v1.54.2
57+
version: v1.55.2
5858

5959
check-gen:
6060
runs-on: ubuntu-latest

OWNERS

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
# See the OWNERS docs: https://git.k8s.io/community/contributors/guide/owners.md
22

33
approvers:
4-
- rmohr
54
- davidvossel
65
- nunnatsa
76
- nirarg
7+
- orenc1
88
options: {}
99
reviewers:
10-
- rmohr
1110
- davidvossel
1211
- nunnatsa
1312
- nirarg
13+
- orenc1
1414

api/v1alpha1/condition_consts.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ const (
3333
// WaitingForBootstrapDataReason (Severity=Info) documents a KubevirtMachine waiting for the bootstrap
3434
// script to be ready before starting to create the VM that provides the KubevirtMachine infrastructure.
3535
WaitingForBootstrapDataReason = "WaitingForBootstrapData"
36+
37+
// VMCreateFailed (Severity=Error) documents a KubevirtMachine that is unable to create the
38+
// corresponding VM object.
39+
VMCreateFailedReason = "VMCreateFailed"
3640
)
3741

3842
const (

api/v1alpha1/kubevirtmachine_types.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ type VirtualMachineBootstrapCheckSpec struct {
7171
// KubevirtMachineStatus defines the observed state of KubevirtMachine.
7272
type KubevirtMachineStatus struct {
7373
// Ready denotes that the machine is ready
74-
// +optional
74+
// +kubebuilder:default=false
7575
Ready bool `json:"ready"`
7676

7777
// LoadBalancerConfigured denotes that the machine has been
@@ -134,6 +134,8 @@ type KubevirtMachineStatus struct {
134134
// +kubebuilder:object:root=true
135135
// +kubebuilder:storageversion
136136
// +kubebuilder:subresource:status
137+
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
138+
// +kubebuilder:printcolumn:name="Ready",type="boolean",JSONPath=".status.ready",description="Is machine ready"
137139

138140
// KubevirtMachine is the Schema for the kubevirtmachines API.
139141
type KubevirtMachine struct {

clusterkubevirtadm/cmd/credentials/credentials.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ import (
2626
"k8s.io/apimachinery/pkg/api/errors"
2727
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2828
k8sclient "k8s.io/client-go/kubernetes"
29+
kubevirtcore "kubevirt.io/api/core"
30+
cdicore "kubevirt.io/containerized-data-importer-api/pkg/apis/core"
2931

3032
"sigs.k8s.io/cluster-api-provider-kubevirt/clusterkubevirtadm/common"
3133
)
@@ -148,10 +150,15 @@ func generateRole(cmdCtx cmdContext) *rbacv1.Role {
148150
},
149151
Rules: []rbacv1.PolicyRule{
150152
{
151-
APIGroups: []string{"kubevirt.io"},
153+
APIGroups: []string{kubevirtcore.GroupName},
152154
Resources: []string{"virtualmachines", "virtualmachineinstances"},
153155
Verbs: []string{rbacv1.VerbAll},
154156
},
157+
{
158+
APIGroups: []string{cdicore.GroupName},
159+
Resources: []string{"datavolumes"},
160+
Verbs: []string{"get", "list", "watch"},
161+
},
155162
{
156163
APIGroups: []string{""},
157164
Resources: []string{"secrets", "services"},

clusterkubevirtadm/cmd/credentials/credentials_test.go

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ package credentials
22

33
import (
44
"context"
5-
65
. "github.com/onsi/ginkgo/v2"
76
. "github.com/onsi/gomega"
87
corev1 "k8s.io/api/core/v1"
98
rbacv1 "k8s.io/api/rbac/v1"
109
"k8s.io/apimachinery/pkg/api/errors"
1110
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1211
"k8s.io/client-go/kubernetes/fake"
12+
kubevirtcore "kubevirt.io/api/core"
13+
cdicore "kubevirt.io/containerized-data-importer-api/pkg/apis/core"
1314

1415
"sigs.k8s.io/cluster-api-provider-kubevirt/clusterkubevirtadm/common"
1516
)
@@ -118,21 +119,18 @@ var _ = Describe("test credentials common function", func() {
118119
Expect(roles.Items).To(HaveLen(1))
119120

120121
Expect(roles.Items[0].Name).Should(Equal(roleName))
121-
Expect(roles.Items[0].Rules).Should(HaveLen(2))
122-
Expect(roles.Items[0].Rules[0].APIGroups).Should(HaveLen(1))
123-
Expect(roles.Items[0].Rules[0].APIGroups[0]).Should(Equal("kubevirt.io"))
124-
Expect(roles.Items[0].Rules[0].Resources).Should(HaveLen(2))
125-
Expect(roles.Items[0].Rules[0].Resources[0]).Should(Equal("virtualmachines"))
126-
Expect(roles.Items[0].Rules[0].Resources[1]).Should(Equal("virtualmachineinstances"))
127-
Expect(roles.Items[0].Rules[0].Verbs).Should(HaveLen(1))
128-
Expect(roles.Items[0].Rules[0].Verbs[0]).Should(Equal(rbacv1.VerbAll))
129-
Expect(roles.Items[0].Rules[1].APIGroups).Should(HaveLen(1))
130-
Expect(roles.Items[0].Rules[1].APIGroups[0]).Should(Equal(""))
131-
Expect(roles.Items[0].Rules[1].Resources).Should(HaveLen(2))
132-
Expect(roles.Items[0].Rules[1].Resources[0]).Should(Equal("secrets"))
133-
Expect(roles.Items[0].Rules[1].Resources[1]).Should(Equal("services"))
134-
Expect(roles.Items[0].Rules[1].Verbs).Should(HaveLen(1))
135-
Expect(roles.Items[0].Rules[1].Verbs[0]).Should(Equal(rbacv1.VerbAll))
122+
Expect(roles.Items[0].Rules).Should(HaveLen(3))
123+
Expect(roles.Items[0].Rules[0].APIGroups).Should(And(HaveLen(1), ContainElements(kubevirtcore.GroupName)))
124+
Expect(roles.Items[0].Rules[0].Resources).Should(And(HaveLen(2), ContainElements("virtualmachines", "virtualmachineinstances")))
125+
Expect(roles.Items[0].Rules[0].Verbs).Should(And(HaveLen(1), ContainElements(rbacv1.VerbAll)))
126+
127+
Expect(roles.Items[0].Rules[1].APIGroups).Should(And(HaveLen(1), ContainElements(cdicore.GroupName)))
128+
Expect(roles.Items[0].Rules[1].Resources).Should(And(HaveLen(1), ContainElements("datavolumes")))
129+
Expect(roles.Items[0].Rules[1].Verbs).Should(And(HaveLen(3), ContainElements("get", "list", "watch")))
130+
131+
Expect(roles.Items[0].Rules[2].APIGroups).Should(And(HaveLen(1), ContainElements("")))
132+
Expect(roles.Items[0].Rules[2].Resources).Should(And(HaveLen(2), ContainElements("secrets", "services")))
133+
Expect(roles.Items[0].Rules[2].Verbs).Should(And(HaveLen(1), ContainElements(rbacv1.VerbAll)))
136134
})
137135

138136
It("create should return error if the Role is already exist", func() {

config/crd/bases/infrastructure.cluster.x-k8s.io_kubevirtmachines.yaml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,15 @@ spec:
1818
singular: kubevirtmachine
1919
scope: Namespaced
2020
versions:
21-
- name: v1alpha1
21+
- additionalPrinterColumns:
22+
- jsonPath: .metadata.creationTimestamp
23+
name: Age
24+
type: date
25+
- description: Is machine ready
26+
jsonPath: .status.ready
27+
name: Ready
28+
type: boolean
29+
name: v1alpha1
2230
schema:
2331
openAPIV3Schema:
2432
description: KubevirtMachine is the Schema for the kubevirtmachines API.
@@ -4614,8 +4622,11 @@ spec:
46144622
Node of this KubevirtMachine
46154623
type: boolean
46164624
ready:
4625+
default: false
46174626
description: Ready denotes that the machine is ready
46184627
type: boolean
4628+
required:
4629+
- ready
46194630
type: object
46204631
type: object
46214632
served: true

config/rbac/role.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ rules:
4545
verbs:
4646
- delete
4747
- list
48+
- apiGroups:
49+
- cdi.kubevirt.io
50+
resources:
51+
- datavolumes
52+
verbs:
53+
- get
54+
- list
55+
- watch
4856
- apiGroups:
4957
- cluster.x-k8s.io
5058
resources:

controllers/kubevirtmachine_controller.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
gocontext "context"
2121
"fmt"
2222
"regexp"
23-
"sigs.k8s.io/controller-runtime/pkg/builder"
2423
"time"
2524

2625
"github.com/pkg/errors"
@@ -30,13 +29,6 @@ import (
3029
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3130
"k8s.io/apimachinery/pkg/types"
3231
utilerrors "k8s.io/apimachinery/pkg/util/errors"
33-
infrav1 "sigs.k8s.io/cluster-api-provider-kubevirt/api/v1alpha1"
34-
"sigs.k8s.io/cluster-api-provider-kubevirt/pkg/context"
35-
"sigs.k8s.io/cluster-api-provider-kubevirt/pkg/infracluster"
36-
"sigs.k8s.io/cluster-api-provider-kubevirt/pkg/kubevirt"
37-
kubevirthandler "sigs.k8s.io/cluster-api-provider-kubevirt/pkg/kubevirt"
38-
"sigs.k8s.io/cluster-api-provider-kubevirt/pkg/ssh"
39-
"sigs.k8s.io/cluster-api-provider-kubevirt/pkg/workloadcluster"
4032
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
4133
capierrors "sigs.k8s.io/cluster-api/errors"
4234
"sigs.k8s.io/cluster-api/util"
@@ -45,10 +37,19 @@ import (
4537
"sigs.k8s.io/cluster-api/util/patch"
4638
"sigs.k8s.io/cluster-api/util/predicates"
4739
ctrl "sigs.k8s.io/controller-runtime"
40+
"sigs.k8s.io/controller-runtime/pkg/builder"
4841
"sigs.k8s.io/controller-runtime/pkg/client"
4942
"sigs.k8s.io/controller-runtime/pkg/controller"
5043
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
5144
"sigs.k8s.io/controller-runtime/pkg/handler"
45+
46+
infrav1 "sigs.k8s.io/cluster-api-provider-kubevirt/api/v1alpha1"
47+
"sigs.k8s.io/cluster-api-provider-kubevirt/pkg/context"
48+
"sigs.k8s.io/cluster-api-provider-kubevirt/pkg/infracluster"
49+
"sigs.k8s.io/cluster-api-provider-kubevirt/pkg/kubevirt"
50+
kubevirthandler "sigs.k8s.io/cluster-api-provider-kubevirt/pkg/kubevirt"
51+
"sigs.k8s.io/cluster-api-provider-kubevirt/pkg/ssh"
52+
"sigs.k8s.io/cluster-api-provider-kubevirt/pkg/workloadcluster"
5253
)
5354

5455
// KubevirtMachineReconciler reconciles a KubevirtMachine object.
@@ -65,6 +66,7 @@ type KubevirtMachineReconciler struct {
6566
// +kubebuilder:rbac:groups="",resources=secrets;,verbs=get;list;watch;create;update;patch;delete
6667
// +kubebuilder:rbac:groups=kubevirt.io,resources=virtualmachines;,verbs=get;create;update;patch;delete
6768
// +kubebuilder:rbac:groups=kubevirt.io,resources=virtualmachineinstances;,verbs=get;delete
69+
// +kubebuilder:rbac:groups=cdi.kubevirt.io,resources=datavolumes;,verbs=get;list;watch
6870

6971
// Reconcile handles KubevirtMachine events.
7072
func (r *KubevirtMachineReconciler) Reconcile(goctx gocontext.Context, req ctrl.Request) (_ ctrl.Result, rerr error) {
@@ -264,6 +266,7 @@ func (r *KubevirtMachineReconciler) reconcileNormal(ctx *context.MachineContext)
264266
if !isTerminal && !externalMachine.Exists() {
265267
ctx.KubevirtMachine.Status.Ready = false
266268
if err := externalMachine.Create(ctx.Context); err != nil {
269+
conditions.MarkFalse(ctx.KubevirtMachine, infrav1.VMProvisionedCondition, infrav1.VMCreateFailedReason, clusterv1.ConditionSeverityError, fmt.Sprintf("Failed vm creation: %v", err))
267270
return ctrl.Result{}, errors.Wrap(err, "failed to create VM instance")
268271
}
269272
ctx.Logger.Info("VM Created, waiting on vm to be provisioned.")
@@ -275,6 +278,9 @@ func (r *KubevirtMachineReconciler) reconcileNormal(ctx *context.MachineContext)
275278
// Mark VMProvisionedCondition to indicate that the VM has successfully started
276279
conditions.MarkTrue(ctx.KubevirtMachine, infrav1.VMProvisionedCondition)
277280
} else {
281+
reason, message := externalMachine.GetVMNotReadyReason()
282+
conditions.MarkFalse(ctx.KubevirtMachine, infrav1.VMProvisionedCondition, reason, clusterv1.ConditionSeverityInfo, message)
283+
278284
// Waiting for VM to boot
279285
ctx.KubevirtMachine.Status.Ready = false
280286
ctx.Logger.Info("KubeVirt VM is not fully provisioned and running...")
@@ -474,7 +480,7 @@ func (r *KubevirtMachineReconciler) reconcileDelete(ctx *context.MachineContext)
474480

475481
// SetupWithManager will add watches for this controller.
476482
func (r *KubevirtMachineReconciler) SetupWithManager(goctx gocontext.Context, mgr ctrl.Manager, options controller.Options) error {
477-
clusterToKubevirtMachines, err := util.ClusterToObjectsMapper(mgr.GetClient(), &infrav1.KubevirtMachineList{}, mgr.GetScheme())
483+
clusterToKubevirtMachines, err := util.ClusterToTypedObjectsMapper(mgr.GetClient(), &infrav1.KubevirtMachineList{}, mgr.GetScheme())
478484
if err != nil {
479485
return err
480486
}

controllers/kubevirtmachine_controller_test.go

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import (
3838
ctrl "sigs.k8s.io/controller-runtime"
3939
"sigs.k8s.io/controller-runtime/pkg/client"
4040
"sigs.k8s.io/controller-runtime/pkg/client/fake"
41+
"sigs.k8s.io/controller-runtime/pkg/client/interceptor"
4142
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
4243

4344
machinemocks "sigs.k8s.io/cluster-api-provider-kubevirt/pkg/kubevirt/mock"
@@ -318,7 +319,7 @@ var _ = Describe("reconcile a kubevirt machine", func() {
318319

319320
})
320321

321-
setupClient := func(machineFactory kubevirt.MachineFactory, objects []client.Object) {
322+
setupClientWithInterceptors := func(machineFactory kubevirt.MachineFactory, objects []client.Object, interceptorFuncs interceptor.Funcs) {
322323
machineContext = &context.MachineContext{
323324
Context: gocontext.Background(),
324325
Cluster: cluster,
@@ -328,15 +329,21 @@ var _ = Describe("reconcile a kubevirt machine", func() {
328329
Logger: testLogger,
329330
}
330331

331-
fakeClient = fake.NewClientBuilder().WithScheme(testing.SetupScheme()).WithObjects(objects...).WithStatusSubresource(objects...).Build()
332+
fakeClient = fake.NewClientBuilder().WithScheme(testing.SetupScheme()).WithObjects(objects...).WithStatusSubresource(objects...).WithInterceptorFuncs(interceptorFuncs).Build()
332333
kubevirtMachineReconciler = KubevirtMachineReconciler{
333334
Client: fakeClient,
334335
WorkloadCluster: workloadClusterMock,
335336
InfraCluster: infraClusterMock,
336337
MachineFactory: machineFactory,
337338
}
339+
}
340+
341+
setupClient := func(machineFactory kubevirt.MachineFactory, objects []client.Object) {
342+
343+
setupClientWithInterceptors(machineFactory, objects, interceptor.Funcs{})
338344

339345
}
346+
340347
AfterEach(func() {})
341348

342349
It("should create KubeVirt VM", func() {
@@ -879,6 +886,43 @@ var _ = Describe("reconcile a kubevirt machine", func() {
879886
Expect(conditions[0].Type).To(Equal(infrav1.VMProvisionedCondition))
880887
Expect(conditions[0].Reason).To(Equal(infrav1.WaitingForBootstrapDataReason))
881888
})
889+
890+
It("adds a failed VMProvisionedCondition with reason VMCreateFailed when failng to create VM", func() {
891+
objects := []client.Object{
892+
cluster,
893+
kubevirtCluster,
894+
machine,
895+
kubevirtMachine,
896+
sshKeySecret,
897+
bootstrapSecret,
898+
}
899+
900+
injectErr := interceptor.Funcs{
901+
Create: func(ctx gocontext.Context, client client.WithWatch, obj client.Object, opts ...client.CreateOption) error {
902+
903+
_, ok := obj.(*kubevirtv1.VirtualMachine)
904+
if ok {
905+
return errors.New("vm create error")
906+
}
907+
return nil
908+
},
909+
}
910+
911+
setupClientWithInterceptors(kubevirt.DefaultMachineFactory{}, objects, injectErr)
912+
913+
infraClusterMock.EXPECT().GenerateInfraClusterClient(kubevirtMachine.Spec.InfraClusterSecretRef, kubevirtMachine.Namespace, machineContext.Context).Return(fakeClient, kubevirtMachine.Namespace, nil)
914+
915+
_, err := kubevirtMachineReconciler.reconcileNormal(machineContext)
916+
917+
Expect(err).Should(HaveOccurred())
918+
919+
// should expect condition
920+
conditions := machineContext.KubevirtMachine.GetConditions()
921+
Expect(conditions[0].Type).To(Equal(infrav1.VMProvisionedCondition))
922+
Expect(conditions[0].Status).To(Equal(corev1.ConditionFalse))
923+
Expect(conditions[0].Reason).To(Equal(infrav1.VMCreateFailedReason))
924+
})
925+
882926
It("adds a succeeded VMProvisionedCondition", func() {
883927
vmiReadyCondition := kubevirtv1.VirtualMachineInstanceCondition{
884928
Type: kubevirtv1.VirtualMachineInstanceReady,

0 commit comments

Comments
 (0)