Skip to content

Commit

Permalink
Apply New Scoping to CP/CL (#7)
Browse files Browse the repository at this point in the history
These resources need to be scoped additionaly to a project in order to
be fully qualified for deletion and updates.  I've also modified the
listers to operate across the organization, so you can see all the
things easily.  To that end I've added some metadata to the status to
allow scoped preentation etc.
  • Loading branch information
spjmurray authored Feb 29, 2024
1 parent c912b96 commit 4ed60f6
Show file tree
Hide file tree
Showing 11 changed files with 977 additions and 1,250 deletions.
5 changes: 0 additions & 5 deletions pkg/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,3 @@ var (
func VersionString() string {
return fmt.Sprintf("%s/%s (revision/%s)", Application, Version, Revision)
}

const (
// NvidiaGPUType is used to indicate the GPU type for cluster-autoscaler.
NvidiaGPUType = "nvidia.com/gpu"
)
1,079 changes: 416 additions & 663 deletions pkg/server/generated/client.go

Large diffs are not rendered by default.

359 changes: 168 additions & 191 deletions pkg/server/generated/router.go

Large diffs are not rendered by default.

297 changes: 149 additions & 148 deletions pkg/server/generated/schema.go

Large diffs are not rendered by default.

90 changes: 46 additions & 44 deletions pkg/server/generated/types.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

61 changes: 30 additions & 31 deletions pkg/server/handler/cluster/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,21 @@ import (
"github.com/gophercloud/utils/openstack/clientconfig"

coreclient "github.com/unikorn-cloud/core/pkg/client"
"github.com/unikorn-cloud/core/pkg/constants"
unikornv1 "github.com/unikorn-cloud/unikorn/pkg/apis/unikorn/v1alpha1"
"github.com/unikorn-cloud/unikorn/pkg/provisioners/helmapplications/clusteropenstack"
"github.com/unikorn-cloud/unikorn/pkg/provisioners/helmapplications/vcluster"
"github.com/unikorn-cloud/unikorn/pkg/server/errors"
"github.com/unikorn-cloud/unikorn/pkg/server/generated"
"github.com/unikorn-cloud/unikorn/pkg/server/handler/controlplane"
"github.com/unikorn-cloud/unikorn/pkg/server/handler/organization"
"github.com/unikorn-cloud/unikorn/pkg/server/handler/providers/openstack"

corev1 "k8s.io/api/core/v1"
kerrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/selection"

"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/yaml"
Expand All @@ -62,15 +66,30 @@ func NewClient(client client.Client, request *http.Request, openstack *openstack
}

// List returns all clusters owned by the implicit control plane.
func (c *Client) List(ctx context.Context, controlPlaneName generated.ControlPlaneNameParameter) ([]*generated.KubernetesCluster, error) {
controlPlane, err := controlplane.NewClient(c.client).GetMetadata(ctx, controlPlaneName)
func (c *Client) List(ctx context.Context) ([]*generated.KubernetesCluster, error) {
selector := labels.NewSelector()

// TODO: a super-admin isn't scoped to a single organization!
// TODO: RBAC - filter projects based on user membership here.
organization, err := organization.NewClient(c.client).GetMetadata(ctx)
if err != nil {
return nil, err
}

organizationReq, err := labels.NewRequirement(constants.OrganizationLabel, selection.Equals, []string{organization.Name})
if err != nil {
return nil, err
}

selector = selector.Add(*organizationReq)

options := &client.ListOptions{
LabelSelector: selector,
}

result := &unikornv1.KubernetesClusterList{}

if err := c.client.List(ctx, result, &client.ListOptions{Namespace: controlPlane.Namespace}); err != nil {
if err := c.client.List(ctx, result, options); err != nil {
return nil, errors.OAuth2ServerError("failed to list control planes").WithError(err)
}

Expand Down Expand Up @@ -99,29 +118,9 @@ func (c *Client) get(ctx context.Context, namespace, name string) (*unikornv1.Ku
return result, nil
}

// Get returns the cluster.
func (c *Client) Get(ctx context.Context, controlPlaneName generated.ControlPlaneNameParameter, name generated.ClusterNameParameter) (*generated.KubernetesCluster, error) {
controlPlane, err := controlplane.NewClient(c.client).GetMetadata(ctx, controlPlaneName)
if err != nil {
return nil, err
}

result, err := c.get(ctx, controlPlane.Namespace, name)
if err != nil {
return nil, err
}

out, err := c.convert(ctx, result)
if err != nil {
return nil, err
}

return out, nil
}

// GetKubeconfig returns the kubernetes configuation associated with a cluster.
func (c *Client) GetKubeconfig(ctx context.Context, controlPlaneName generated.ControlPlaneNameParameter, name generated.ClusterNameParameter) ([]byte, error) {
controlPlane, err := controlplane.NewClient(c.client).GetMetadata(ctx, controlPlaneName)
func (c *Client) GetKubeconfig(ctx context.Context, projectName generated.ProjectNameParameter, controlPlaneName generated.ControlPlaneNameParameter, name generated.ClusterNameParameter) ([]byte, error) {
controlPlane, err := controlplane.NewClient(c.client).GetMetadata(ctx, projectName, controlPlaneName)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -240,8 +239,8 @@ func (c *Client) createServerGroup(controlPlane *controlplane.Meta, name, kind s
}

// Create creates the implicit cluster indentified by the JTW claims.
func (c *Client) Create(ctx context.Context, controlPlaneName generated.ControlPlaneNameParameter, options *generated.KubernetesCluster) error {
controlPlane, err := controlplane.NewClient(c.client).GetOrCreateMetadata(ctx, controlPlaneName)
func (c *Client) Create(ctx context.Context, projectName generated.ProjectNameParameter, controlPlaneName generated.ControlPlaneNameParameter, options *generated.KubernetesCluster) error {
controlPlane, err := controlplane.NewClient(c.client).GetOrCreateMetadata(ctx, projectName, controlPlaneName)
if err != nil {
return err
}
Expand Down Expand Up @@ -285,8 +284,8 @@ func (c *Client) Create(ctx context.Context, controlPlaneName generated.ControlP
}

// Delete deletes the implicit cluster indentified by the JTW claims.
func (c *Client) Delete(ctx context.Context, controlPlaneName generated.ControlPlaneNameParameter, name generated.ClusterNameParameter) error {
controlPlane, err := controlplane.NewClient(c.client).GetMetadata(ctx, controlPlaneName)
func (c *Client) Delete(ctx context.Context, projectName generated.ProjectNameParameter, controlPlaneName generated.ControlPlaneNameParameter, name generated.ClusterNameParameter) error {
controlPlane, err := controlplane.NewClient(c.client).GetMetadata(ctx, projectName, controlPlaneName)
if err != nil {
return err
}
Expand Down Expand Up @@ -314,8 +313,8 @@ func (c *Client) Delete(ctx context.Context, controlPlaneName generated.ControlP
}

// Update implements read/modify/write for the cluster.
func (c *Client) Update(ctx context.Context, controlPlaneName generated.ControlPlaneNameParameter, name generated.ClusterNameParameter, request *generated.KubernetesCluster) error {
controlPlane, err := controlplane.NewClient(c.client).GetMetadata(ctx, controlPlaneName)
func (c *Client) Update(ctx context.Context, projectName generated.ProjectNameParameter, controlPlaneName generated.ControlPlaneNameParameter, name generated.ClusterNameParameter, request *generated.KubernetesCluster) error {
controlPlane, err := controlplane.NewClient(c.client).GetMetadata(ctx, projectName, controlPlaneName)
if err != nil {
return err
}
Expand Down
40 changes: 28 additions & 12 deletions pkg/server/handler/cluster/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@ import (
"net"

unikornv1core "github.com/unikorn-cloud/core/pkg/apis/unikorn/v1alpha1"
coreconstants "github.com/unikorn-cloud/core/pkg/constants"
"github.com/unikorn-cloud/core/pkg/constants"
unikornv1 "github.com/unikorn-cloud/unikorn/pkg/apis/unikorn/v1alpha1"
"github.com/unikorn-cloud/unikorn/pkg/constants"
"github.com/unikorn-cloud/unikorn/pkg/server/errors"
"github.com/unikorn-cloud/unikorn/pkg/server/generated"
"github.com/unikorn-cloud/unikorn/pkg/server/handler/applicationbundle"
Expand Down Expand Up @@ -161,9 +160,21 @@ func convertFeatures(in *unikornv1.KubernetesCluster) *generated.KubernetesClust
return features
}

// convertStatus converts from a custom resource into the API definition.
func convertStatus(in *unikornv1.KubernetesCluster) *generated.KubernetesResourceStatus {
out := &generated.KubernetesResourceStatus{
// convertMetadata converts from a custom resource into the API definition.
func convertMetadata(in *unikornv1.KubernetesCluster) (*generated.ResourceMetadata, error) {
labels, err := in.ResourceLabels()
if err != nil {
return nil, err
}

// Validated to exist by ResourceLabels()
project := labels[constants.ProjectLabel]
controlplane := labels[constants.ControlPlaneLabel]

out := &generated.ResourceMetadata{
Project: &project,
Controlplane: &controlplane,
// TODO: fill in the region.
CreationTime: in.CreationTimestamp.Time,
Status: "Unknown",
}
Expand All @@ -177,17 +188,23 @@ func convertStatus(in *unikornv1.KubernetesCluster) *generated.KubernetesResourc
out.Status = string(condition.Reason)
}

return out
return out, nil
}

// convert converts from a custom resource into the API definition.
func (c *Client) convert(ctx context.Context, in *unikornv1.KubernetesCluster) (*generated.KubernetesCluster, error) {
metadata, err := convertMetadata(in)
if err != nil {
return nil, err
}

bundle, err := applicationbundle.NewClient(c.client).GetKubernetesCluster(ctx, *in.Spec.ApplicationBundle)
if err != nil {
return nil, err
}

out := &generated.KubernetesCluster{
Metadata: metadata,
Name: in.Name,
ApplicationBundle: *bundle,
ApplicationBundleAutoUpgrade: common.ConvertApplicationBundleAutoUpgrade(in.Spec.ApplicationBundleAutoUpgrade),
Expand All @@ -197,7 +214,6 @@ func (c *Client) convert(ctx context.Context, in *unikornv1.KubernetesCluster) (
ControlPlane: convertMachine(&in.Spec.ControlPlane.MachineGeneric),
WorkloadPools: convertWorkloadPools(in),
Features: convertFeatures(in),
Status: convertStatus(in),
}

return out, nil
Expand Down Expand Up @@ -417,7 +433,7 @@ func (c *Client) createWorkloadPools(clusterContext *createClusterContext, optio
}

if flavor.Gpus != nil {
t := constants.NvidiaGPUType
t := "nvidia.com/gpu"

workloadPool.Autoscaling.Scheduler.GPU = &unikornv1.MachineGenericAutoscalingSchedulerGPU{
Type: &t,
Expand Down Expand Up @@ -488,10 +504,10 @@ func (c *Client) createCluster(controlPlane *controlplane.Meta, options *generat
Name: options.Name,
Namespace: controlPlane.Namespace,
Labels: map[string]string{
coreconstants.VersionLabel: coreconstants.Version,
coreconstants.OrganizationLabel: controlPlane.Project.Organization.Name,
coreconstants.ProjectLabel: controlPlane.Project.Name,
coreconstants.ControlPlaneLabel: controlPlane.Name,
constants.VersionLabel: constants.Version,
constants.OrganizationLabel: controlPlane.Project.Organization.Name,
constants.ProjectLabel: controlPlane.Project.Name,
constants.ControlPlaneLabel: controlPlane.Name,
},
},
Spec: unikornv1.KubernetesClusterSpec{
Expand Down
Loading

0 comments on commit 4ed60f6

Please sign in to comment.