Skip to content

Commit

Permalink
Merge pull request #507 from akrejcir/proxy-route
Browse files Browse the repository at this point in the history
feat: Add Route to expose vm-console-proxy
  • Loading branch information
kubevirt-bot committed Mar 1, 2023
2 parents ccf3d9f + 808aba8 commit 95d2f0f
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 5 deletions.
12 changes: 12 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,18 @@ rules:
- patch
- update
- watch
- apiGroups:
- route.openshift.io
resources:
- routes
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- security.openshift.io
resources:
Expand Down
12 changes: 12 additions & 0 deletions data/olm-catalog/ssp-operator.clusterserviceversion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,18 @@ spec:
- patch
- update
- watch
- apiGroups:
- route.openshift.io
resources:
- routes
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- security.openshift.io
resources:
Expand Down
46 changes: 45 additions & 1 deletion internal/operands/vm-console-proxy/reconcile.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@ import (
"fmt"
"strconv"

routev1 "github.com/openshift/api/route/v1"
apps "k8s.io/api/apps/v1"
core "k8s.io/api/core/v1"
rbac "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"kubevirt.io/ssp-operator/internal/common"
"kubevirt.io/ssp-operator/internal/operands"
vm_console_proxy_bundle "kubevirt.io/ssp-operator/internal/vm-console-proxy-bundle"
"sigs.k8s.io/controller-runtime/pkg/client"

vm_console_proxy_bundle "kubevirt.io/ssp-operator/internal/vm-console-proxy-bundle"
)

const (
Expand All @@ -25,12 +29,17 @@ const (
// +kubebuilder:rbac:groups=core,resources=services;serviceaccounts;configmaps,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterroles;clusterrolebindings,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=route.openshift.io,resources=routes,verbs=get;list;watch;create;update;patch;delete

// RBAC for created roles
// +kubebuilder:rbac:groups=kubevirt.io,resources=virtualmachineinstances,verbs=get;list;watch
// +kubebuilder:rbac:groups=authentication.k8s.io,resources=tokenreviews,verbs=create
// +kubebuilder:rbac:groups=authorization.k8s.io,resources=subjectaccessreviews,verbs=create

func init() {
utilruntime.Must(routev1.Install(common.Scheme))
}

func WatchClusterTypes() []operands.WatchType {
return []operands.WatchType{
{Object: &rbac.ClusterRole{}},
Expand All @@ -39,6 +48,7 @@ func WatchClusterTypes() []operands.WatchType {
{Object: &core.Service{}},
{Object: &apps.Deployment{}, WatchFullObject: true},
{Object: &core.ConfigMap{}},
{Object: &routev1.Route{}},
}
}

Expand Down Expand Up @@ -99,6 +109,7 @@ func (v *vmConsoleProxy) Reconcile(request *common.Request) ([]common.ReconcileR
reconcileFunc = append(reconcileFunc, reconcileConfigMapFuncs(*v.configMap.DeepCopy()))
reconcileFunc = append(reconcileFunc, reconcileServiceFuncs(*v.service.DeepCopy()))
reconcileFunc = append(reconcileFunc, reconcileDeploymentFuncs(*v.deployment.DeepCopy()))
reconcileFunc = append(reconcileFunc, reconcileRoute(v.service.GetName()))

reconcileBundleResults, err := common.CollectResourceStatus(request, reconcileFunc...)
if err != nil {
Expand All @@ -117,6 +128,7 @@ func (v *vmConsoleProxy) Cleanup(request *common.Request) ([]common.CleanupResul
objects = append(objects, v.configMap.DeepCopy())
objects = append(objects, v.service.DeepCopy())
objects = append(objects, v.deployment.DeepCopy())
objects = append(objects, newRoute(getVmConsoleProxyNamespace(request), v.service.GetName()))

return common.DeleteAll(request, objects...)
}
Expand Down Expand Up @@ -227,6 +239,18 @@ func reconcileDeploymentFuncs(deployment apps.Deployment) common.ReconcileFunc {
}
}

func reconcileRoute(serviceName string) common.ReconcileFunc {
return func(request *common.Request) (common.ReconcileResult, error) {
return common.CreateOrUpdate(request).
ClusterResource(newRoute(getVmConsoleProxyNamespace(request), serviceName)).
WithAppLabels(operandName, operandComponent).
UpdateFunc(func(newRes, foundRes client.Object) {
foundRes.(*routev1.Route).Spec = newRes.(*routev1.Route).Spec
}).
Reconcile()
}
}

func isEnabled(request *common.Request) bool {
if request.Instance.GetAnnotations() == nil {
return false
Expand Down Expand Up @@ -257,3 +281,23 @@ func getVmConsoleProxyNamespace(request *common.Request) string {
func getVmConsoleProxyImage() string {
return common.EnvOrDefault("VM_CONSOLE_PROXY_IMAGE", "quay.io/kubevirt/vm-console-proxy:v0.1.0")
}

func newRoute(namespace string, serviceName string) *routev1.Route {
return &routev1.Route{
ObjectMeta: metav1.ObjectMeta{
Name: "vm-console-proxy",
Namespace: namespace,
},
Spec: routev1.RouteSpec{
To: routev1.RouteTargetReference{
Kind: "Service",
Name: serviceName,
},
TLS: &routev1.TLSConfig{
Termination: routev1.TLSTerminationReencrypt,
InsecureEdgeTerminationPolicy: routev1.InsecureEdgeTerminationPolicyRedirect,
},
WildcardPolicy: routev1.WildcardPolicyNone,
},
}
}
2 changes: 1 addition & 1 deletion internal/operands/vm-console-proxy/reconcile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ var _ = Describe("VM Console Proxy Operand", func() {
It("should return functions from reconcile correclty", func() {
functions, err := v.Reconcile(mockedRequest)
Expect(err).ToNot(HaveOccurred(), "should not throw err")
Expect(len(functions)).To(Equal(6), "should return correct number of reconcile functions")
Expect(len(functions)).To(Equal(7), "should return correct number of reconcile functions")
})
})

Expand Down
5 changes: 2 additions & 3 deletions tests/tests_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
ginkgo_reporters "github.com/onsi/ginkgo/v2/reporters"
. "github.com/onsi/gomega"
osconfv1 "github.com/openshift/api/config/v1"
openshiftroutev1 "github.com/openshift/api/route/v1"
routev1 "github.com/openshift/api/route/v1"
secv1 "github.com/openshift/api/security/v1"
templatev1 "github.com/openshift/api/template/v1"
promv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
Expand Down Expand Up @@ -447,6 +447,7 @@ func setupApiClient() {
Expect(os.Setenv(kubevirtv1.KubeVirtClientGoSchemeRegistrationVersionEnvVar, "v1")).ToNot(HaveOccurred())
Expect(kubevirtv1.AddToScheme(testScheme)).ToNot(HaveOccurred())
Expect(instancetypev1alpha2.AddToScheme(testScheme)).ToNot(HaveOccurred())
Expect(routev1.Install(testScheme)).ToNot(HaveOccurred())

cfg, err := config.GetConfig()
Expect(err).ToNot(HaveOccurred())
Expand All @@ -455,8 +456,6 @@ func setupApiClient() {
coreClient, err = kubernetes.NewForConfig(cfg)
Expect(err).ToNot(HaveOccurred())

Expect(openshiftroutev1.AddToScheme(testScheme)).ToNot(HaveOccurred())

portForwarder = NewPortForwarder(cfg, coreClient.CoreV1().RESTClient())

ctx = context.Background()
Expand Down
61 changes: 61 additions & 0 deletions tests/vm_console_proxy_test.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
package tests

import (
"crypto/tls"
"io"
"net/http"
"net/url"
"reflect"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"

routev1 "github.com/openshift/api/route/v1"
apps "k8s.io/api/apps/v1"
core "k8s.io/api/core/v1"
rbac "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/utils/pointer"

ssp "kubevirt.io/ssp-operator/api/v1beta1"
vm_console_proxy "kubevirt.io/ssp-operator/internal/operands/vm-console-proxy"
)
Expand All @@ -22,6 +29,7 @@ var _ = Describe("VM Console Proxy Operand", func() {
serviceResource testResource
deploymentResource testResource
configMapResource testResource
routeResource testResource
)

BeforeEach(func() {
Expand Down Expand Up @@ -107,6 +115,18 @@ var _ = Describe("VM Console Proxy Operand", func() {
reflect.DeepEqual(old.BinaryData, new.BinaryData)
},
}
routeResource = testResource{
Name: "vm-console-proxy",
Namespace: strategy.GetVmConsoleProxyNamespace(),
Resource: &routev1.Route{},
ExpectedLabels: expectedLabels,
UpdateFunc: func(route *routev1.Route) {
route.Spec.TLS = nil
},
EqualsFunc: func(old, new *routev1.Route) bool {
return reflect.DeepEqual(old.Spec, new.Spec)
},
}

waitUntilDeployed()
})
Expand All @@ -128,6 +148,7 @@ var _ = Describe("VM Console Proxy Operand", func() {
Entry("[test_id:TODO] service", &serviceResource),
Entry("[test_id:TODO] deployment", &deploymentResource),
Entry("[test_id:TODO] config map", &configMapResource),
Entry("[test_id:TODO] route", &routeResource),
)

DescribeTable("should set app labels", expectAppLabels,
Expand All @@ -137,6 +158,7 @@ var _ = Describe("VM Console Proxy Operand", func() {
Entry("[test_id:TODO] service", &serviceResource),
Entry("[test_id:TODO] deployment", &deploymentResource),
Entry("[test_id:TODO] config map", &configMapResource),
Entry("[test_id:TODO] route", &routeResource),
)
})

Expand All @@ -148,6 +170,7 @@ var _ = Describe("VM Console Proxy Operand", func() {
Entry("[test_id:TODO] service", &serviceResource),
Entry("[test_id:TODO] deployment", &deploymentResource),
Entry("[test_id:TODO] config map", &configMapResource),
Entry("[test_id:TODO] route", &routeResource),
)
})

Expand All @@ -158,6 +181,7 @@ var _ = Describe("VM Console Proxy Operand", func() {
Entry("[test_id:TODO] service", &serviceResource),
Entry("[test_id:TODO] deployment", &deploymentResource),
Entry("[test_id:TODO] config map", &configMapResource),
Entry("[test_id:TODO] route", &routeResource),
)

Context("With pause", func() {
Expand All @@ -175,6 +199,7 @@ var _ = Describe("VM Console Proxy Operand", func() {
Entry("[test_id:TODO] service", &serviceResource),
Entry("[test_id:TODO] deployment", &deploymentResource),
Entry("[test_id:TODO] config map", &configMapResource),
Entry("[test_id:TODO] route", &routeResource),
)
})

Expand All @@ -185,6 +210,42 @@ var _ = Describe("VM Console Proxy Operand", func() {
Entry("[test_id:TODO] service", &serviceResource),
Entry("[test_id:TODO] deployment", &deploymentResource),
Entry("[test_id:TODO] config map", &configMapResource),
Entry("[test_id:TODO] route", &routeResource),
)
})

Context("Route to access proxy", func() {
var (
routeApiUrl string
httpClient *http.Client
)

BeforeEach(func() {
transport := http.DefaultTransport.(*http.Transport).Clone()
transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
httpClient = &http.Client{
Transport: transport,
}

route := &routev1.Route{}
Expect(apiClient.Get(ctx, routeResource.GetKey(), route)).To(Succeed())
routeApiUrl = "https://" + route.Spec.Host + "/api/v1alpha1"
})

It("[test_id:TODO] should be able to access /token endpoint", func() {
url, err := url.JoinPath(routeApiUrl, strategy.GetNamespace(), "non-existing-vm", "token")
Expect(err).ToNot(HaveOccurred())

response, err := httpClient.Get(url)
Expect(err).ToNot(HaveOccurred())
defer func() { _ = response.Body.Close() }()

Expect(response.StatusCode).To(Equal(http.StatusUnauthorized))

body, err := io.ReadAll(response.Body)
Expect(err).ToNot(HaveOccurred())

Expect(body).To(ContainSubstring("authenticating token cannot be empty"))
})
})
})

0 comments on commit 95d2f0f

Please sign in to comment.