Skip to content

Commit

Permalink
Merge pull request kubevirt#11718 from fossedihelm/allow-proxy-for-se…
Browse files Browse the repository at this point in the history
…v-requests

Allow SEV requests in proxied servers
  • Loading branch information
kubevirt-bot authored Apr 24, 2024
2 parents 1f4e36c + 110752e commit ee0144c
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -125,28 +125,28 @@ func (c *FakeVirtualMachineInstances) VSOCK(name string, options *v1.VSOCKOption
return nil, nil
}

func (c *FakeVirtualMachineInstances) SEVFetchCertChain(name string) (v1.SEVPlatformInfo, error) {
func (c *FakeVirtualMachineInstances) SEVFetchCertChain(ctx context.Context, name string) (v1.SEVPlatformInfo, error) {
_, err := c.Fake.
Invokes(testing.NewGetSubresourceAction(virtualmachineinstancesResource, c.ns, "sev/fetchcertchain", name), &v1.SEVPlatformInfo{})

return v1.SEVPlatformInfo{}, err
}

func (c *FakeVirtualMachineInstances) SEVQueryLaunchMeasurement(name string) (v1.SEVMeasurementInfo, error) {
func (c *FakeVirtualMachineInstances) SEVQueryLaunchMeasurement(ctx context.Context, name string) (v1.SEVMeasurementInfo, error) {
_, err := c.Fake.
Invokes(testing.NewGetSubresourceAction(virtualmachineinstancesResource, c.ns, "sev/querylaunchmeasurement", name), &v1.SEVMeasurementInfo{})

return v1.SEVMeasurementInfo{}, err
}

func (c *FakeVirtualMachineInstances) SEVSetupSession(name string, sevSessionOptions *v1.SEVSessionOptions) error {
func (c *FakeVirtualMachineInstances) SEVSetupSession(ctx context.Context, name string, sevSessionOptions *v1.SEVSessionOptions) error {
_, err := c.Fake.
Invokes(fake2.NewPutSubresourceAction(virtualmachineinstancesResource, c.ns, "sev/setupsession", name, sevSessionOptions), nil)

return err
}

func (c *FakeVirtualMachineInstances) SEVInjectLaunchSecret(name string, sevSecretOptions *v1.SEVSecretOptions) error {
func (c *FakeVirtualMachineInstances) SEVInjectLaunchSecret(ctx context.Context, name string, sevSecretOptions *v1.SEVSecretOptions) error {
_, err := c.Fake.
Invokes(fake2.NewPutSubresourceAction(virtualmachineinstancesResource, c.ns, "sev/injectlaunchsecret", name, sevSecretOptions), nil)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ type VirtualMachineInstanceExpansion interface {
AddVolume(ctx context.Context, name string, addVolumeOptions *v1.AddVolumeOptions) error
RemoveVolume(ctx context.Context, name string, removeVolumeOptions *v1.RemoveVolumeOptions) error
VSOCK(name string, options *v1.VSOCKOptions) (StreamInterface, error)
SEVFetchCertChain(name string) (v1.SEVPlatformInfo, error)
SEVQueryLaunchMeasurement(name string) (v1.SEVMeasurementInfo, error)
SEVSetupSession(name string, sevSessionOptions *v1.SEVSessionOptions) error
SEVInjectLaunchSecret(name string, sevSecretOptions *v1.SEVSecretOptions) error
SEVFetchCertChain(ctx context.Context, name string) (v1.SEVPlatformInfo, error)
SEVQueryLaunchMeasurement(ctx context.Context, name string) (v1.SEVMeasurementInfo, error)
SEVSetupSession(ctx context.Context, name string, sevSessionOptions *v1.SEVSessionOptions) error
SEVInjectLaunchSecret(ctx context.Context, name string, sevSecretOptions *v1.SEVSecretOptions) error
}

func (c *virtualMachineInstances) SerialConsole(name string, options *SerialConsoleOptions) (StreamInterface, error) {
Expand Down Expand Up @@ -133,22 +133,22 @@ func (c *virtualMachineInstances) VSOCK(name string, options *v1.VSOCKOptions) (
return nil, nil
}

func (c *virtualMachineInstances) SEVFetchCertChain(name string) (v1.SEVPlatformInfo, error) {
func (c *virtualMachineInstances) SEVFetchCertChain(ctx context.Context, name string) (v1.SEVPlatformInfo, error) {
// TODO not implemented yet
return v1.SEVPlatformInfo{}, nil
}

func (c *virtualMachineInstances) SEVQueryLaunchMeasurement(name string) (v1.SEVMeasurementInfo, error) {
func (c *virtualMachineInstances) SEVQueryLaunchMeasurement(ctx context.Context, name string) (v1.SEVMeasurementInfo, error) {
// TODO not implemented yet
return v1.SEVMeasurementInfo{}, nil
}

func (c *virtualMachineInstances) SEVSetupSession(name string, sevSessionOptions *v1.SEVSessionOptions) error {
func (c *virtualMachineInstances) SEVSetupSession(ctx context.Context, name string, sevSessionOptions *v1.SEVSessionOptions) error {
// TODO not implemented yet
return nil
}

func (c *virtualMachineInstances) SEVInjectLaunchSecret(name string, sevSecretOptions *v1.SEVSecretOptions) error {
func (c *virtualMachineInstances) SEVInjectLaunchSecret(ctx context.Context, name string, sevSecretOptions *v1.SEVSecretOptions) error {
// TODO not implemented yet
return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -1258,46 +1258,46 @@ func (_mr *_MockVirtualMachineInstanceInterfaceRecorder) VSOCK(arg0, arg1 interf
return _mr.mock.ctrl.RecordCall(_mr.mock, "VSOCK", arg0, arg1)
}

func (_m *MockVirtualMachineInstanceInterface) SEVFetchCertChain(name string) (v120.SEVPlatformInfo, error) {
ret := _m.ctrl.Call(_m, "SEVFetchCertChain", name)
func (_m *MockVirtualMachineInstanceInterface) SEVFetchCertChain(ctx context.Context, name string) (v120.SEVPlatformInfo, error) {
ret := _m.ctrl.Call(_m, "SEVFetchCertChain", ctx, name)
ret0, _ := ret[0].(v120.SEVPlatformInfo)
ret1, _ := ret[1].(error)
return ret0, ret1
}

func (_mr *_MockVirtualMachineInstanceInterfaceRecorder) SEVFetchCertChain(arg0 interface{}) *gomock.Call {
return _mr.mock.ctrl.RecordCall(_mr.mock, "SEVFetchCertChain", arg0)
func (_mr *_MockVirtualMachineInstanceInterfaceRecorder) SEVFetchCertChain(arg0, arg1 interface{}) *gomock.Call {
return _mr.mock.ctrl.RecordCall(_mr.mock, "SEVFetchCertChain", arg0, arg1)
}

func (_m *MockVirtualMachineInstanceInterface) SEVQueryLaunchMeasurement(name string) (v120.SEVMeasurementInfo, error) {
ret := _m.ctrl.Call(_m, "SEVQueryLaunchMeasurement", name)
func (_m *MockVirtualMachineInstanceInterface) SEVQueryLaunchMeasurement(ctx context.Context, name string) (v120.SEVMeasurementInfo, error) {
ret := _m.ctrl.Call(_m, "SEVQueryLaunchMeasurement", ctx, name)
ret0, _ := ret[0].(v120.SEVMeasurementInfo)
ret1, _ := ret[1].(error)
return ret0, ret1
}

func (_mr *_MockVirtualMachineInstanceInterfaceRecorder) SEVQueryLaunchMeasurement(arg0 interface{}) *gomock.Call {
return _mr.mock.ctrl.RecordCall(_mr.mock, "SEVQueryLaunchMeasurement", arg0)
func (_mr *_MockVirtualMachineInstanceInterfaceRecorder) SEVQueryLaunchMeasurement(arg0, arg1 interface{}) *gomock.Call {
return _mr.mock.ctrl.RecordCall(_mr.mock, "SEVQueryLaunchMeasurement", arg0, arg1)
}

func (_m *MockVirtualMachineInstanceInterface) SEVSetupSession(name string, sevSessionOptions *v120.SEVSessionOptions) error {
ret := _m.ctrl.Call(_m, "SEVSetupSession", name, sevSessionOptions)
func (_m *MockVirtualMachineInstanceInterface) SEVSetupSession(ctx context.Context, name string, sevSessionOptions *v120.SEVSessionOptions) error {
ret := _m.ctrl.Call(_m, "SEVSetupSession", ctx, name, sevSessionOptions)
ret0, _ := ret[0].(error)
return ret0
}

func (_mr *_MockVirtualMachineInstanceInterfaceRecorder) SEVSetupSession(arg0, arg1 interface{}) *gomock.Call {
return _mr.mock.ctrl.RecordCall(_mr.mock, "SEVSetupSession", arg0, arg1)
func (_mr *_MockVirtualMachineInstanceInterfaceRecorder) SEVSetupSession(arg0, arg1, arg2 interface{}) *gomock.Call {
return _mr.mock.ctrl.RecordCall(_mr.mock, "SEVSetupSession", arg0, arg1, arg2)
}

func (_m *MockVirtualMachineInstanceInterface) SEVInjectLaunchSecret(name string, sevSecretOptions *v120.SEVSecretOptions) error {
ret := _m.ctrl.Call(_m, "SEVInjectLaunchSecret", name, sevSecretOptions)
func (_m *MockVirtualMachineInstanceInterface) SEVInjectLaunchSecret(ctx context.Context, name string, sevSecretOptions *v120.SEVSecretOptions) error {
ret := _m.ctrl.Call(_m, "SEVInjectLaunchSecret", ctx, name, sevSecretOptions)
ret0, _ := ret[0].(error)
return ret0
}

func (_mr *_MockVirtualMachineInstanceInterfaceRecorder) SEVInjectLaunchSecret(arg0, arg1 interface{}) *gomock.Call {
return _mr.mock.ctrl.RecordCall(_mr.mock, "SEVInjectLaunchSecret", arg0, arg1)
func (_mr *_MockVirtualMachineInstanceInterfaceRecorder) SEVInjectLaunchSecret(arg0, arg1, arg2 interface{}) *gomock.Call {
return _mr.mock.ctrl.RecordCall(_mr.mock, "SEVInjectLaunchSecret", arg0, arg1, arg2)
}

// Mock of ReplicaSetInterface interface
Expand Down
16 changes: 8 additions & 8 deletions staging/src/kubevirt.io/client-go/kubecli/vmi.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,34 +324,34 @@ func (v *vmis) VSOCK(name string, options *v1.VSOCKOptions) (kvcorev1.StreamInte
return kvcorev1.AsyncSubresourceHelper(v.config, v.resource, v.namespace, name, "vsock", queryParams)
}

func (v *vmis) SEVFetchCertChain(name string) (v1.SEVPlatformInfo, error) {
func (v *vmis) SEVFetchCertChain(ctx context.Context, name string) (v1.SEVPlatformInfo, error) {
sevPlatformInfo := v1.SEVPlatformInfo{}
uri := fmt.Sprintf(vmiSubresourceURL, v1.ApiStorageVersion, v.namespace, name, "sev/fetchcertchain")
err := v.restClient.Get().RequestURI(uri).Do(context.Background()).Into(&sevPlatformInfo)
err := v.restClient.Get().AbsPath(uri).Do(ctx).Into(&sevPlatformInfo)
return sevPlatformInfo, err
}

func (v *vmis) SEVQueryLaunchMeasurement(name string) (v1.SEVMeasurementInfo, error) {
func (v *vmis) SEVQueryLaunchMeasurement(ctx context.Context, name string) (v1.SEVMeasurementInfo, error) {
sevMeasurementInfo := v1.SEVMeasurementInfo{}
uri := fmt.Sprintf(vmiSubresourceURL, v1.ApiStorageVersion, v.namespace, name, "sev/querylaunchmeasurement")
err := v.restClient.Get().RequestURI(uri).Do(context.Background()).Into(&sevMeasurementInfo)
err := v.restClient.Get().AbsPath(uri).Do(ctx).Into(&sevMeasurementInfo)
return sevMeasurementInfo, err
}

func (v *vmis) SEVSetupSession(name string, sevSessionOptions *v1.SEVSessionOptions) error {
func (v *vmis) SEVSetupSession(ctx context.Context, name string, sevSessionOptions *v1.SEVSessionOptions) error {
body, err := json.Marshal(sevSessionOptions)
if err != nil {
return fmt.Errorf("Cannot Marshal to json: %s", err)
}
uri := fmt.Sprintf(vmiSubresourceURL, v1.ApiStorageVersion, v.namespace, name, "sev/setupsession")
return v.restClient.Put().RequestURI(uri).Body(body).Do(context.Background()).Error()
return v.restClient.Put().AbsPath(uri).Body(body).Do(ctx).Error()
}

func (v *vmis) SEVInjectLaunchSecret(name string, sevSecretOptions *v1.SEVSecretOptions) error {
func (v *vmis) SEVInjectLaunchSecret(ctx context.Context, name string, sevSecretOptions *v1.SEVSecretOptions) error {
body, err := json.Marshal(sevSecretOptions)
if err != nil {
return fmt.Errorf("Cannot Marshal to json: %s", err)
}
uri := fmt.Sprintf(vmiSubresourceURL, v1.ApiStorageVersion, v.namespace, name, "sev/injectlaunchsecret")
return v.restClient.Put().RequestURI(uri).Body(body).Do(context.Background()).Error()
return v.restClient.Put().AbsPath(uri).Body(body).Do(ctx).Error()
}
44 changes: 28 additions & 16 deletions staging/src/kubevirt.io/client-go/kubecli/vmi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ var _ = Describe("Kubevirt VirtualMachineInstance Client", func() {
Entry("with proxied server URL", proxyPath),
)

It("should fetch SEV platform info via subresource", func() {
DescribeTable("should fetch SEV platform info via subresource", func(proxyPath string) {
client, err := GetKubevirtClientFromFlags(server.URL()+proxyPath, "")
Expect(err).ToNot(HaveOccurred())

Expand All @@ -442,16 +442,19 @@ var _ = Describe("Kubevirt VirtualMachineInstance Client", func() {
}

server.AppendHandlers(ghttp.CombineHandlers(
ghttp.VerifyRequest("GET", path.Join(subVMIPath, "sev/fetchcertchain")),
ghttp.VerifyRequest("GET", path.Join(proxyPath, subVMIPath, "sev/fetchcertchain")),
ghttp.RespondWithJSONEncoded(http.StatusOK, sevPlatformIfo),
))
fetchedInfo, err := client.VirtualMachineInstance(k8sv1.NamespaceDefault).SEVFetchCertChain("testvm")
fetchedInfo, err := client.VirtualMachineInstance(k8sv1.NamespaceDefault).SEVFetchCertChain(context.Background(), "testvm")

Expect(err).ToNot(HaveOccurred(), "should fetch info normally")
Expect(fetchedInfo).To(Equal(sevPlatformIfo), "fetched info should be the same as passed in")
})
},
Entry("with regular server URL", ""),
Entry("with proxied server URL", proxyPath),
)

It("should query SEV launch measurement info via subresource", func() {
DescribeTable("should query SEV launch measurement info via subresource", func(proxyPath string) {
client, err := GetKubevirtClientFromFlags(server.URL()+proxyPath, "")
Expect(err).ToNot(HaveOccurred())

Expand All @@ -464,42 +467,51 @@ var _ = Describe("Kubevirt VirtualMachineInstance Client", func() {
}

server.AppendHandlers(ghttp.CombineHandlers(
ghttp.VerifyRequest("GET", path.Join(subVMIPath, "sev/querylaunchmeasurement")),
ghttp.VerifyRequest("GET", path.Join(proxyPath, subVMIPath, "sev/querylaunchmeasurement")),
ghttp.RespondWithJSONEncoded(http.StatusOK, sevMeasurementInfo),
))
fetchedInfo, err := client.VirtualMachineInstance(k8sv1.NamespaceDefault).SEVQueryLaunchMeasurement("testvm")
fetchedInfo, err := client.VirtualMachineInstance(k8sv1.NamespaceDefault).SEVQueryLaunchMeasurement(context.Background(), "testvm")

Expect(err).ToNot(HaveOccurred(), "should fetch info normally")
Expect(fetchedInfo).To(Equal(sevMeasurementInfo), "fetched info should be the same as passed in")
})
},
Entry("with regular server URL", ""),
Entry("with proxied server URL", proxyPath),
)

It("should setup SEV session for a VirtualMachineInstance", func() {
DescribeTable("should setup SEV session for a VirtualMachineInstance", func(proxyPath string) {
client, err := GetKubevirtClientFromFlags(server.URL()+proxyPath, "")
Expect(err).ToNot(HaveOccurred())

server.AppendHandlers(ghttp.CombineHandlers(
ghttp.VerifyRequest("PUT", path.Join(subVMIPath, "sev/setupsession")),
ghttp.VerifyRequest("PUT", path.Join(proxyPath, subVMIPath, "sev/setupsession")),
ghttp.RespondWithJSONEncoded(http.StatusOK, nil),
))
err = client.VirtualMachineInstance(k8sv1.NamespaceDefault).SEVSetupSession("testvm", &v1.SEVSessionOptions{})
err = client.VirtualMachineInstance(k8sv1.NamespaceDefault).SEVSetupSession(context.Background(), "testvm", &v1.SEVSessionOptions{})

Expect(server.ReceivedRequests()).To(HaveLen(1))
Expect(err).ToNot(HaveOccurred())
})
},
Entry("with regular server URL", ""),
Entry("with proxied server URL", proxyPath),
)

It("should inject SEV launch secret into a VirtualMachineInstance", func() {
DescribeTable("should inject SEV launch secret into a VirtualMachineInstance", func(proxyPath string) {
client, err := GetKubevirtClientFromFlags(server.URL()+proxyPath, "")
Expect(err).ToNot(HaveOccurred())

server.AppendHandlers(ghttp.CombineHandlers(
ghttp.VerifyRequest("PUT", path.Join(subVMIPath, "sev/injectlaunchsecret")),
ghttp.VerifyRequest("PUT", path.Join(proxyPath, subVMIPath, "sev/injectlaunchsecret")),
ghttp.RespondWithJSONEncoded(http.StatusOK, nil),
))
err = client.VirtualMachineInstance(k8sv1.NamespaceDefault).SEVInjectLaunchSecret("testvm", &v1.SEVSecretOptions{})
err = client.VirtualMachineInstance(k8sv1.NamespaceDefault).SEVInjectLaunchSecret(context.Background(), "testvm", &v1.SEVSecretOptions{})

Expect(server.ReceivedRequests()).To(HaveLen(1))
Expect(err).ToNot(HaveOccurred())
})
},
Entry("with regular server URL", ""),
Entry("with proxied server URL", proxyPath),
)

AfterEach(func() {
server.Close()
Expand Down
8 changes: 4 additions & 4 deletions tests/launchsecurity/sev.go
Original file line number Diff line number Diff line change
Expand Up @@ -366,15 +366,15 @@ var _ = Describe("[sig-compute]AMD Secure Encrypted Virtualization (SEV)", decor
expectedSEVPlatformInfo.CertChain = entries["cert-chain"]

By("Fetching platform certificates")
sevPlatformInfo, err := virtClient.VirtualMachineInstance(vmi.Namespace).SEVFetchCertChain(vmi.Name)
sevPlatformInfo, err := virtClient.VirtualMachineInstance(vmi.Namespace).SEVFetchCertChain(context.Background(), vmi.Name)
Expect(err).ToNot(HaveOccurred())
Expect(sevPlatformInfo).To(Equal(expectedSEVPlatformInfo))

By("Setting up session parameters")
vmi, err = ThisVMI(vmi)()
Expect(err).ToNot(HaveOccurred())
sevSessionOptions, tikBase64, tekBase64 := prepareSession(virtClient, vmi.Status.NodeName, sevPlatformInfo.PDH)
err = virtClient.VirtualMachineInstance(vmi.Namespace).SEVSetupSession(vmi.Name, sevSessionOptions)
err = virtClient.VirtualMachineInstance(vmi.Namespace).SEVSetupSession(context.Background(), vmi.Name, sevSessionOptions)
Expect(err).ToNot(HaveOccurred())
Eventually(ThisVMI(vmi), 60).Should(And(BeRunning(), HaveConditionTrue(v1.VirtualMachineInstancePaused)))

Expand Down Expand Up @@ -403,14 +403,14 @@ var _ = Describe("[sig-compute]AMD Secure Encrypted Virtualization (SEV)", decor
Expect(expectedSEVMeasurementInfo.LoaderSHA).To(HaveLen(64))

By("Querying launch measurement")
sevMeasurementInfo, err := virtClient.VirtualMachineInstance(vmi.Namespace).SEVQueryLaunchMeasurement(vmi.Name)
sevMeasurementInfo, err := virtClient.VirtualMachineInstance(vmi.Namespace).SEVQueryLaunchMeasurement(context.Background(), vmi.Name)
Expect(err).ToNot(HaveOccurred())
Expect(sevMeasurementInfo).To(Equal(expectedSEVMeasurementInfo))
measure := verifyMeasurement(&sevMeasurementInfo, tikBase64)
sevSecretOptions := encryptSecret(diskSecret, measure, tikBase64, tekBase64)

By("Injecting launch secret")
err = virtClient.VirtualMachineInstance(vmi.Namespace).SEVInjectLaunchSecret(vmi.Name, sevSecretOptions)
err = virtClient.VirtualMachineInstance(vmi.Namespace).SEVInjectLaunchSecret(context.Background(), vmi.Name, sevSecretOptions)
Expect(err).ToNot(HaveOccurred())

By("Unpausing the VirtualMachineInstance")
Expand Down

0 comments on commit ee0144c

Please sign in to comment.