Skip to content

Commit

Permalink
inject ClusterConfig to mutating-webhook
Browse files Browse the repository at this point in the history
Specifically, it is injected to VMIsMutator.

Signed-off-by: Arik Hadas <[email protected]>
  • Loading branch information
ahadas committed Apr 29, 2019
1 parent 02cc2a5 commit 5896d2c
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 48 deletions.
1 change: 1 addition & 0 deletions pkg/testutils/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/rand:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
Expand Down
31 changes: 30 additions & 1 deletion pkg/testutils/mock_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@ import (
v1 "k8s.io/api/core/v1"
v12 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/rand"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/tools/cache"

virtconfig "kubevirt.io/kubevirt/pkg/virt-config"
)

const (
configMapName = "kubevirt-config"
namespace = "kubevirt"
)

func MakeFakeClusterConfig(configMaps []v1.ConfigMap, stopChan chan struct{}) *virtconfig.ClusterConfig {
cmListWatch := &cache.ListWatch{
ListFunc: func(options v12.ListOptions) (runtime.Object, error) {
Expand All @@ -26,5 +32,28 @@ func MakeFakeClusterConfig(configMaps []v1.ConfigMap, stopChan chan struct{}) *v
cmInformer := cache.NewSharedIndexInformer(cmListWatch, &v1.ConfigMap{}, 0, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
go cmInformer.Run(stopChan)
cache.WaitForCacheSync(stopChan, cmInformer.HasSynced)
return virtconfig.NewClusterConfig(cmInformer.GetStore(), "kubevirt")
return virtconfig.NewClusterConfig(cmInformer.GetStore(), namespace)
}

func NewFakeClusterConfig(cfgMap *v1.ConfigMap) (*virtconfig.ClusterConfig, cache.Store) {
store := cache.NewStore(cache.DeletionHandlingMetaNamespaceKeyFunc)
copy := copy(cfgMap)
store.Add(copy)
return virtconfig.NewClusterConfig(store, namespace), store
}

func UpdateFakeClusterConfig(store cache.Store, cfgMap *v1.ConfigMap) {
copy := copy(cfgMap)
store.Update(copy)
}

func copy(cfgMap *v1.ConfigMap) *v1.ConfigMap {
copy := cfgMap.DeepCopy()
copy.ObjectMeta = v12.ObjectMeta{
Namespace: namespace,
Name: configMapName,
// Change the resource version, or the config will not be updated
ResourceVersion: rand.String(10),
}
return copy
}
1 change: 1 addition & 0 deletions pkg/virt-api/webhooks/mutating-webhook/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ go_test(
"//pkg/log:go_default_library",
"//pkg/testutils:go_default_library",
"//pkg/virt-api/webhooks:go_default_library",
"//pkg/virt-config:go_default_library",
"//vendor/github.com/onsi/ginkgo:go_default_library",
"//vendor/github.com/onsi/gomega:go_default_library",
"//vendor/k8s.io/api/admission/v1beta1:go_default_library",
Expand Down
13 changes: 7 additions & 6 deletions pkg/virt-api/webhooks/mutating-webhook/mutating-webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ func serve(resp http.ResponseWriter, req *http.Request, m mutator) {
}

type VMIsMutator struct {
clusterConfig *virtconfig.ClusterConfig
}

func (mutator *VMIsMutator) mutate(ar *v1beta1.AdmissionReview) *v1beta1.AdmissionResponse {
Expand All @@ -101,11 +102,7 @@ func (mutator *VMIsMutator) mutate(ar *v1beta1.AdmissionReview) *v1beta1.Admissi
}

informers := webhooks.GetInformers()
namespace, err := util.GetNamespace()
if err != nil {
return webhooks.ToAdmissionResponseError(err)
}
config := virtconfig.NewClusterConfig(informers.ConfigMapInformer.GetStore(), namespace)
config := mutator.clusterConfig

// Apply presets
err = applyPresets(&vmi, informers.VMIPresetInformer)
Expand Down Expand Up @@ -251,7 +248,11 @@ func setDefaultResourceRequests(vmi *v1.VirtualMachineInstance, defaultMemoryReq
}

func ServeVMIs(resp http.ResponseWriter, req *http.Request) {
serve(resp, req, &VMIsMutator{})
informers := webhooks.GetInformers()
namespace, _ := util.GetNamespace()
serve(resp, req, &VMIsMutator{
clusterConfig: virtconfig.NewClusterConfig(informers.ConfigMapInformer.GetStore(), namespace),
})
}

func ServeMigrationCreate(resp http.ResponseWriter, req *http.Request) {
Expand Down
71 changes: 42 additions & 29 deletions pkg/virt-api/webhooks/mutating-webhook/mutating-webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
v1 "kubevirt.io/kubevirt/pkg/api/v1"
"kubevirt.io/kubevirt/pkg/testutils"
"kubevirt.io/kubevirt/pkg/virt-api/webhooks"
virtconfig "kubevirt.io/kubevirt/pkg/virt-config"
)

var _ = Describe("Mutating Webhook", func() {
Expand All @@ -44,12 +45,14 @@ var _ = Describe("Mutating Webhook", func() {
var presetInformer cache.SharedIndexInformer
var namespaceLimit *k8sv1.LimitRange
var namespaceLimitInformer cache.SharedIndexInformer
var configMapStore cache.Store
var mutator *VMIsMutator

limitMemory, _ := resource.ParseQuantity("128M")
memoryLimit := "128M"
cpuModelFromConfig := "Haswell"
machineTypeFromConfig := "pc-q35-3.0"
cpuRequestFromConfig := resource.MustParse("800m")
memoryRequestFromConfig := resource.MustParse("256Mi")
cpuRequestFromConfig := "800m"
memoryRequestFromConfig := "256Mi"

getVMISpecMetaFromResponse := func() (*v1.VirtualMachineInstanceSpec, *k8smetav1.ObjectMeta) {
vmiBytes, err := json.Marshal(vmi)
Expand All @@ -64,7 +67,6 @@ var _ = Describe("Mutating Webhook", func() {
},
}
By("Mutating the VMI")
mutator := &VMIsMutator{}
resp := mutator.mutate(ar)
Expect(resp.Allowed).To(Equal(true))

Expand Down Expand Up @@ -115,7 +117,7 @@ var _ = Describe("Mutating Webhook", func() {
{
Type: k8sv1.LimitTypeContainer,
Default: k8sv1.ResourceList{
k8sv1.ResourceMemory: limitMemory,
k8sv1.ResourceMemory: resource.MustParse(memoryLimit),
},
},
},
Expand All @@ -131,6 +133,9 @@ var _ = Describe("Mutating Webhook", func() {
ConfigMapInformer: configMapInformer,
},
)

mutator = &VMIsMutator{}
mutator.clusterConfig, configMapStore = testutils.NewFakeClusterConfig(&k8sv1.ConfigMap{})
})

It("should apply presets on VMI create", func() {
Expand All @@ -141,7 +146,7 @@ var _ = Describe("Mutating Webhook", func() {

It("should apply namespace limit ranges on VMI create", func() {
vmiSpec, _ := getVMISpecMetaFromResponse()
Expect(vmiSpec.Domain.Resources.Limits.Memory().String()).To(Equal("128M"))
Expect(vmiSpec.Domain.Resources.Limits.Memory().String()).To(Equal(memoryLimit))
})

It("should apply defaults on VMI create", func() {
Expand All @@ -153,36 +158,44 @@ var _ = Describe("Mutating Webhook", func() {
})

It("should apply configurable defaults on VMI create", func() {
setDefaultCPUModel(vmi, cpuModelFromConfig)
setDefaultMachineType(vmi, machineTypeFromConfig)
setDefaultResourceRequests(vmi, memoryRequestFromConfig, cpuRequestFromConfig)
Expect(vmi.Spec.Domain.CPU.Model).To(Equal(cpuModelFromConfig))
Expect(vmi.Spec.Domain.Machine.Type).To(Equal(machineTypeFromConfig))
Expect(vmi.Spec.Domain.Resources.Requests.Cpu().String()).To(Equal("800m"))
Expect(vmi.Spec.Domain.Resources.Requests.Memory().String()).To(Equal("256Mi"))
testutils.UpdateFakeClusterConfig(configMapStore, &k8sv1.ConfigMap{
Data: map[string]string{
virtconfig.CpuModelKey: cpuModelFromConfig,
virtconfig.MachineTypeKey: machineTypeFromConfig,
virtconfig.MemoryRequestKey: memoryRequestFromConfig,
virtconfig.CpuRequestKey: cpuRequestFromConfig,
},
})

vmiSpec, _ := getVMISpecMetaFromResponse()
Expect(vmiSpec.Domain.CPU.Model).To(Equal(cpuModelFromConfig))
Expect(vmiSpec.Domain.Machine.Type).To(Equal(machineTypeFromConfig))
Expect(vmiSpec.Domain.Resources.Requests.Cpu().String()).To(Equal(cpuRequestFromConfig))
Expect(vmiSpec.Domain.Resources.Requests.Memory().String()).To(Equal(memoryRequestFromConfig))
})

It("should not override specified properties with defaults on VMI create", func() {
vmCPUModel := "EPYC"
vmMachineType := "q35"
cpu := "600m"
memory := "512Mi"
testutils.UpdateFakeClusterConfig(configMapStore, &k8sv1.ConfigMap{
Data: map[string]string{
virtconfig.CpuModelKey: cpuModelFromConfig,
virtconfig.MachineTypeKey: machineTypeFromConfig,
virtconfig.MemoryRequestKey: memoryRequestFromConfig,
virtconfig.CpuRequestKey: cpuRequestFromConfig,
},
})

vmi.Spec.Domain.Resources.Requests = k8sv1.ResourceList{
k8sv1.ResourceCPU: resource.MustParse(cpu),
k8sv1.ResourceMemory: resource.MustParse(memory),
}
vmi.Spec.Domain.CPU = &v1.CPU{
Model: vmCPUModel,
k8sv1.ResourceCPU: resource.MustParse("600m"),
k8sv1.ResourceMemory: resource.MustParse("512Mi"),
}
vmi.Spec.Domain.Machine.Type = vmMachineType
vmi.Spec.Domain.CPU = &v1.CPU{Model: "EPYC"}
vmi.Spec.Domain.Machine.Type = "q35"

vmiSpec, _ := getVMISpecMetaFromResponse()
setDefaultCPUModel(vmi, cpuModelFromConfig)
setDefaultMachineType(vmi, machineTypeFromConfig)
Expect(vmi.Spec.Domain.CPU.Model).To(Equal(vmCPUModel))
Expect(vmi.Spec.Domain.Machine.Type).To(Equal(vmMachineType))
Expect(vmiSpec.Domain.Resources.Requests.Cpu().String()).To(Equal(cpu))
Expect(vmiSpec.Domain.Resources.Requests.Memory().String()).To(Equal(memory))
Expect(vmiSpec.Domain.CPU.Model).To(Equal(vmi.Spec.Domain.CPU.Model))
Expect(vmiSpec.Domain.Machine.Type).To(Equal(vmi.Spec.Domain.Machine.Type))
Expect(vmiSpec.Domain.Resources.Requests.Cpu()).To(Equal(vmi.Spec.Domain.Resources.Requests.Cpu()))
Expect(vmiSpec.Domain.Resources.Requests.Memory()).To(Equal(vmi.Spec.Domain.Resources.Requests.Memory()))
})

It("should apply foreground finalizer on VMI create", func() {
Expand Down
16 changes: 8 additions & 8 deletions pkg/virt-config/config-map.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ const (
featureGateEnvVar = "FEATURE_GATES"
FeatureGatesKey = "feature-gates"
emulatedMachinesKey = "emulated-machines"
machineTypeKey = "machine-type"
MachineTypeKey = "machine-type"
useEmulationKey = "debug.useEmulation"
imagePullPolicyKey = "dev.imagePullPolicy"
migrationsConfigKey = "migrations"
cpuModelKey = "default-cpu-model"
cpuRequestKey = "cpu-request"
memoryRequestKey = "memory-request"
CpuModelKey = "default-cpu-model"
CpuRequestKey = "cpu-request"
MemoryRequestKey = "memory-request"

ParallelOutboundMigrationsPerNodeDefault uint32 = 2
ParallelMigrationsPerClusterDefault uint32 = 5
Expand Down Expand Up @@ -273,19 +273,19 @@ func setConfig(config *Config, configMap *k8sv1.ConfigMap) error {
}

// set machine type
if machineType := strings.TrimSpace(configMap.Data[machineTypeKey]); machineType != "" {
if machineType := strings.TrimSpace(configMap.Data[MachineTypeKey]); machineType != "" {
config.MachineType = machineType
}

if cpuModel := strings.TrimSpace(configMap.Data[cpuModelKey]); cpuModel != "" {
if cpuModel := strings.TrimSpace(configMap.Data[CpuModelKey]); cpuModel != "" {
config.CPUModel = cpuModel
}

if cpuRequest := strings.TrimSpace(configMap.Data[cpuRequestKey]); cpuRequest != "" {
if cpuRequest := strings.TrimSpace(configMap.Data[CpuRequestKey]); cpuRequest != "" {
config.CPURequest = resource.MustParse(cpuRequest)
}

if memoryRequest := strings.TrimSpace(configMap.Data[memoryRequestKey]); memoryRequest != "" {
if memoryRequest := strings.TrimSpace(configMap.Data[MemoryRequestKey]); memoryRequest != "" {
config.MemoryRequest = resource.MustParse(memoryRequest)
}

Expand Down
8 changes: 4 additions & 4 deletions pkg/virt-config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ var _ = Describe("ConfigMap", func() {
Namespace: "kubevirt",
Name: "kubevirt-config",
},
Data: map[string]string{machineTypeKey: value},
Data: map[string]string{MachineTypeKey: value},
}
clusterConfig, _ := MakeClusterConfig([]kubev1.ConfigMap{cfgMap}, stopChan)
Expect(clusterConfig.GetMachineType()).To(Equal(result))
Expand All @@ -89,7 +89,7 @@ var _ = Describe("ConfigMap", func() {
Namespace: "kubevirt",
Name: "kubevirt-config",
},
Data: map[string]string{cpuModelKey: value},
Data: map[string]string{CpuModelKey: value},
}
clusterConfig, _ := MakeClusterConfig([]kubev1.ConfigMap{cfgMap}, stopChan)
Expect(clusterConfig.GetCPUModel()).To(Equal(result))
Expand All @@ -105,7 +105,7 @@ var _ = Describe("ConfigMap", func() {
Namespace: "kubevirt",
Name: "kubevirt-config",
},
Data: map[string]string{cpuRequestKey: value},
Data: map[string]string{CpuRequestKey: value},
}
clusterConfig, _ := MakeClusterConfig([]kubev1.ConfigMap{cfgMap}, stopChan)
cpuRequest := clusterConfig.GetCPURequest()
Expand All @@ -122,7 +122,7 @@ var _ = Describe("ConfigMap", func() {
Namespace: "kubevirt",
Name: "kubevirt-config",
},
Data: map[string]string{memoryRequestKey: value},
Data: map[string]string{MemoryRequestKey: value},
}
clusterConfig, _ := MakeClusterConfig([]kubev1.ConfigMap{cfgMap}, stopChan)
memoryRequest := clusterConfig.GetMemoryRequest()
Expand Down

0 comments on commit 5896d2c

Please sign in to comment.