Skip to content

Commit

Permalink
Device registration APIs
Browse files Browse the repository at this point in the history
basic CRUD for device registrations, whihc will be used for the edge provisioning flow
  • Loading branch information
michaeljguarino committed Jan 15, 2025
1 parent e657871 commit 7f55b83
Show file tree
Hide file tree
Showing 15 changed files with 639 additions and 4 deletions.
84 changes: 84 additions & 0 deletions assets/src/generated/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1453,6 +1453,56 @@ export type ClusterRecommendationAttributes = {
type?: InputMaybe<ScalingRecommendationType>;
};

export type ClusterRegistration = {
__typename?: 'ClusterRegistration';
creator?: Maybe<User>;
/** the handle to apply to the cluster */
handle: Scalars['String']['output'];
id: Scalars['ID']['output'];
insertedAt?: Maybe<Scalars['DateTime']['output']>;
/** a unique machine id for the created cluster */
machineId: Scalars['String']['output'];
/** additional metadata to apply to the cluster */
metadata?: Maybe<Scalars['Map']['output']>;
/** the name to give to the cluster */
name: Scalars['String']['output'];
/** the project the cluster will live in */
project?: Maybe<Project>;
/** the tags to apply to the given cluster */
tags?: Maybe<Array<Maybe<Tag>>>;
updatedAt?: Maybe<Scalars['DateTime']['output']>;
};

export type ClusterRegistrationConnection = {
__typename?: 'ClusterRegistrationConnection';
edges?: Maybe<Array<Maybe<ClusterRegistrationEdge>>>;
pageInfo: PageInfo;
};

export type ClusterRegistrationCreateAttributes = {
/** a unique machine id for the created cluster */
machineId: Scalars['String']['input'];
/** the project this cluster will live in (can be inferred from bootstrap token) */
projectId?: InputMaybe<Scalars['ID']['input']>;
};

export type ClusterRegistrationEdge = {
__typename?: 'ClusterRegistrationEdge';
cursor?: Maybe<Scalars['String']['output']>;
node?: Maybe<ClusterRegistration>;
};

export type ClusterRegistrationUpdateAttributes = {
/** the handle to apply to the cluster */
handle?: InputMaybe<Scalars['String']['input']>;
/** additional metadata to apply to the cluster */
metadata?: InputMaybe<Scalars['Json']['input']>;
/** the name to give to the cluster */
name: Scalars['String']['input'];
/** the tags to apply to the given cluster */
tags?: InputMaybe<Array<InputMaybe<TagInput>>>;
};

export type ClusterRestore = {
__typename?: 'ClusterRestore';
backup?: Maybe<ClusterBackup>;
Expand Down Expand Up @@ -5302,6 +5352,7 @@ export type RootMutationType = {
/** upserts a cluster backup resource */
createClusterBackup?: Maybe<ClusterBackup>;
createClusterProvider?: Maybe<ClusterProvider>;
createClusterRegistration?: Maybe<ClusterRegistration>;
createClusterRestore?: Maybe<ClusterRestore>;
createCustomStackRun?: Maybe<CustomStackRun>;
createGitRepository?: Maybe<GitRepository>;
Expand Down Expand Up @@ -5343,6 +5394,7 @@ export type RootMutationType = {
deleteChat?: Maybe<Chat>;
deleteCluster?: Maybe<Cluster>;
deleteClusterProvider?: Maybe<ClusterProvider>;
deleteClusterRegistration?: Maybe<ClusterRegistration>;
deleteCustomStackRun?: Maybe<CustomStackRun>;
deleteGitRepository?: Maybe<GitRepository>;
deleteGlobalService?: Maybe<GlobalService>;
Expand Down Expand Up @@ -5437,6 +5489,7 @@ export type RootMutationType = {
triggerRun?: Maybe<StackRun>;
updateCluster?: Maybe<Cluster>;
updateClusterProvider?: Maybe<ClusterProvider>;
updateClusterRegistration?: Maybe<ClusterRegistration>;
updateClusterRestore?: Maybe<ClusterRestore>;
updateCustomStackRun?: Maybe<CustomStackRun>;
updateDeploymentSettings?: Maybe<DeploymentSettings>;
Expand Down Expand Up @@ -5585,6 +5638,11 @@ export type RootMutationTypeCreateClusterProviderArgs = {
};


export type RootMutationTypeCreateClusterRegistrationArgs = {
attributes: ClusterRegistrationCreateAttributes;
};


export type RootMutationTypeCreateClusterRestoreArgs = {
backupId: Scalars['ID']['input'];
};
Expand Down Expand Up @@ -5785,6 +5843,11 @@ export type RootMutationTypeDeleteClusterProviderArgs = {
};


export type RootMutationTypeDeleteClusterRegistrationArgs = {
id: Scalars['ID']['input'];
};


export type RootMutationTypeDeleteCustomStackRunArgs = {
id: Scalars['ID']['input'];
};
Expand Down Expand Up @@ -6175,6 +6238,12 @@ export type RootMutationTypeUpdateClusterProviderArgs = {
};


export type RootMutationTypeUpdateClusterRegistrationArgs = {
attributes: ClusterRegistrationUpdateAttributes;
id: Scalars['ID']['input'];
};


export type RootMutationTypeUpdateClusterRestoreArgs = {
attributes: RestoreAttributes;
id: Scalars['ID']['input'];
Expand Down Expand Up @@ -6433,6 +6502,8 @@ export type RootQueryType = {
clusterProvider?: Maybe<ClusterProvider>;
/** a relay connection of all providers visible to the current user */
clusterProviders?: Maybe<ClusterProviderConnection>;
clusterRegistration?: Maybe<ClusterRegistration>;
clusterRegistrations?: Maybe<ClusterRegistrationConnection>;
clusterRestore?: Maybe<ClusterRestore>;
clusterRestores?: Maybe<ClusterRestoreConnection>;
/** the services deployed in the current cluster, to be polled by the deploy operator */
Expand Down Expand Up @@ -6746,6 +6817,19 @@ export type RootQueryTypeClusterProvidersArgs = {
};


export type RootQueryTypeClusterRegistrationArgs = {
id: Scalars['ID']['input'];
};


export type RootQueryTypeClusterRegistrationsArgs = {
after?: InputMaybe<Scalars['String']['input']>;
before?: InputMaybe<Scalars['String']['input']>;
first?: InputMaybe<Scalars['Int']['input']>;
last?: InputMaybe<Scalars['Int']['input']>;
};


export type RootQueryTypeClusterRestoreArgs = {
id: Scalars['ID']['input'];
};
Expand Down
47 changes: 47 additions & 0 deletions go/client/models_gen.go

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

49 changes: 48 additions & 1 deletion lib/console/deployments/clusters.ex
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ defmodule Console.Deployments.Clusters do
PinnedCustomResource,
UpgradeInsight,
ClusterInsightComponent,
ClusterUsage
ClusterUsage,
ClusterRegistration
}
alias Console.Deployments.Compatibilities
require Logger
Expand All @@ -38,6 +39,7 @@ defmodule Console.Deployments.Clusters do
@type credential_resp :: {:ok, ProviderCredential.t} | Console.error
@type runtime_service_resp :: {:ok, RuntimeService.t} | Console.error
@type pinned_resp :: {:ok, PinnedCustomResource.t} | Console.error
@type reg_resp :: {:ok, ClusterRegistration.t} | Console.error

@doc """
True if there's been one cluster that's successfully pinged in the fleet
Expand Down Expand Up @@ -72,6 +74,8 @@ defmodule Console.Deployments.Clusters do

def get_cluster_usage!(id), do: Repo.get!(ClusterUsage, id) |> Repo.preload([:cluster])

def get_cluster_registration(id), do: Repo.get!(ClusterRegistration, id)

def get_runtime_service(id) do
Console.Repo.get(RuntimeService, id)
|> with_addon()
Expand Down Expand Up @@ -781,6 +785,49 @@ defmodule Console.Deployments.Clusters do
|> notify(:update, user)
end

@doc """
Creates a new cluster registration, with inferred project id if necessary
"""
@spec create_cluster_registration(map, User.t) :: reg_resp
def create_cluster_registration(attrs, %User{} = user) do
%ClusterRegistration{creator_id: user.id}
|> ClusterRegistration.changeset(Settings.add_project_id(attrs, user))
|> allow(user, :create)
|> when_ok(:insert)
end

@doc """
Adds cluster data to the registration, eg name/handle/tags and tests for validity
"""
@spec update_cluster_registration(map, binary, %User{}) :: reg_resp
def update_cluster_registration(attrs, id, %User{} = user) do
start_transaction()
|> add_operation(:update, fn _ ->
Repo.get!(ClusterRegistration, id)
|> ClusterRegistration.changeset(attrs)
|> ClusterRegistration.update_changeset()
|> allow(user, :write)
|> when_ok(:update)
end)
|> add_operation(:test, fn %{update: %ClusterRegistration{handle: handle} = reg} ->
case get_cluster_by_handle(handle) do
%Cluster{} -> {:error, "a cluster already exists with handle #{handle}"}
_ -> {:ok, reg}
end
end)
|> execute(extract: :update)
end

@doc """
Removes the registration if allowed
"""
@spec delete_cluster_registration(binary, User.t) :: reg_resp
def delete_cluster_registration(id, %User{} = user) do
Repo.get!(ClusterRegistration, id)
|> allow(user, :write)
|> when_ok(:delete)
end

def create_agent_migration(attrs, %User{} = user) do
%AgentMigration{}
|> AgentMigration.changeset(attrs)
Expand Down
4 changes: 3 additions & 1 deletion lib/console/deployments/policies/bootstrap_policies.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
defmodule Console.Deployments.BootstrapPolicies do
use Piazza.Policy
alias Console.Schema.{User, BootstrapToken, Project, Cluster}
alias Console.Schema.{User, BootstrapToken, Project, Cluster, ClusterRegistration}

def can?(%User{id: id}, %ClusterRegistration{creator_id: id}, _), do: :pass

def can?(%User{bootstrap: %BootstrapToken{project_id: id}}, %Project{id: id}, :read), do: :pass

Expand Down
7 changes: 6 additions & 1 deletion lib/console/deployments/policies/rbac.ex
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ defmodule Console.Deployments.Policies.Rbac do
Observer,
Catalog,
ClusterInsightComponent,
VulnerabilityReport
VulnerabilityReport,
ClusterRegistration
}

def globally_readable(query, %User{roles: %{admin: true}}, _), do: query
Expand Down Expand Up @@ -84,6 +85,8 @@ defmodule Console.Deployments.Policies.Rbac do
do: recurse(comp, user, action, & &1.cluster)
def evaluate(%VulnerabilityReport{} = comp, user, action),
do: recurse(comp, user, action, & &1.cluster)
def evaluate(%ClusterRegistration{} = reg, user, action),
do: recurse(reg, user, action, & &1.project)
def evaluate(%GlobalService{} = global, %User{} = user, action) do
recurse(global, user, action, fn
%{project: %Project{} = project} -> project
Expand Down Expand Up @@ -158,6 +161,8 @@ defmodule Console.Deployments.Policies.Rbac do
do: Repo.preload(pcr, [stack: @stack_preloads])
def preload(%GlobalService{} = global),
do: Repo.preload(global, [project: @bindings])
def preload(%ClusterRegistration{} = reg),
do: Repo.preload(reg, [project: @bindings])
def preload(%ManagedNamespace{} = ns),
do: Repo.preload(ns, [project: @bindings])
def preload(%CustomStackRun{} = pcr),
Expand Down
Loading

0 comments on commit 7f55b83

Please sign in to comment.