Skip to content

Commit

Permalink
Implement catalog schema (#1444)
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeljguarino authored Oct 8, 2024
1 parent 62a21cf commit 16b1471
Show file tree
Hide file tree
Showing 18 changed files with 599 additions and 17 deletions.
2 changes: 1 addition & 1 deletion assets/src/generated/graphql-kubernetes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11835,4 +11835,4 @@ export function useStatefulSetPodsSuspenseQuery(baseOptions?: Apollo.SuspenseQue
export type StatefulSetPodsQueryHookResult = ReturnType<typeof useStatefulSetPodsQuery>;
export type StatefulSetPodsLazyQueryHookResult = ReturnType<typeof useStatefulSetPodsLazyQuery>;
export type StatefulSetPodsSuspenseQueryHookResult = ReturnType<typeof useStatefulSetPodsSuspenseQuery>;
export type StatefulSetPodsQueryResult = Apollo.QueryResult<StatefulSetPodsQuery, StatefulSetPodsQueryVariables>;
export type StatefulSetPodsQueryResult = Apollo.QueryResult<StatefulSetPodsQuery, StatefulSetPodsQueryVariables>;
2 changes: 1 addition & 1 deletion assets/src/generated/graphql-plural.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5349,4 +5349,4 @@ export const namedOperations = {
Fragment: {
ChatMessage: 'ChatMessage'
}
}
}
89 changes: 82 additions & 7 deletions assets/src/generated/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,52 @@ export type CascadeAttributes = {
detach?: InputMaybe<Scalars['Boolean']['input']>;
};

/** A catalog is an organized collection of PR Automations used for permissioning and discovery */
export type Catalog = {
__typename?: 'Catalog';
/** the name of the author of this catalog */
author?: Maybe<Scalars['String']['output']>;
/** short category name used for browsing catalogs */
category?: Maybe<Scalars['String']['output']>;
/** longform description for the purpose of this catalog */
description?: Maybe<Scalars['String']['output']>;
id: Scalars['ID']['output'];
insertedAt?: Maybe<Scalars['DateTime']['output']>;
name: Scalars['String']['output'];
project?: Maybe<Project>;
/** read policy for this catalog */
readBindings?: Maybe<Array<Maybe<PolicyBinding>>>;
updatedAt?: Maybe<Scalars['DateTime']['output']>;
/** write policy for this catalog */
writeBindings?: Maybe<Array<Maybe<PolicyBinding>>>;
};

export type CatalogAttributes = {
/** the name of the author of this catalog, used for attribution only */
author: Scalars['String']['input'];
/** short category name for browsability */
category?: InputMaybe<Scalars['String']['input']>;
description?: InputMaybe<Scalars['String']['input']>;
name: Scalars['String']['input'];
/** owning project of the catalog, permissions will propagate down */
projectId?: InputMaybe<Scalars['ID']['input']>;
readBindings?: InputMaybe<Array<InputMaybe<PolicyBindingAttributes>>>;
tags?: InputMaybe<Array<InputMaybe<TagAttributes>>>;
writeBindings?: InputMaybe<Array<InputMaybe<PolicyBindingAttributes>>>;
};

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

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

export type Certificate = {
__typename?: 'Certificate';
events?: Maybe<Array<Maybe<Event>>>;
Expand Down Expand Up @@ -4037,6 +4083,8 @@ export type PrAutomation = {
__typename?: 'PrAutomation';
/** link to an add-on name if this can update it */
addon?: Maybe<Scalars['String']['output']>;
/** the catalog this pr automation belongs to */
catalog?: Maybe<Catalog>;
/** link to a cluster if this is to perform an upgrade */
cluster?: Maybe<Cluster>;
configuration?: Maybe<Array<Maybe<PrConfiguration>>>;
Expand Down Expand Up @@ -4074,6 +4122,8 @@ export type PrAutomationAttributes = {
/** link to an add-on name if this can update it */
addon?: InputMaybe<Scalars['String']['input']>;
branch?: InputMaybe<Scalars['String']['input']>;
/** the catalog this automation will belong to */
catalogId?: InputMaybe<Scalars['ID']['input']>;
/** link to a cluster if this is to perform an upgrade */
clusterId?: InputMaybe<Scalars['ID']['input']>;
configuration?: InputMaybe<Array<InputMaybe<PrConfigurationAttributes>>>;
Expand Down Expand Up @@ -4716,6 +4766,7 @@ export type RootMutationType = {
createUpgradePolicy?: Maybe<UpgradePolicy>;
createWebhook?: Maybe<Webhook>;
deleteAccessToken?: Maybe<AccessToken>;
deleteCatalog?: Maybe<Catalog>;
deleteCertificate?: Maybe<Scalars['Boolean']['output']>;
deleteCluster?: Maybe<Cluster>;
deleteClusterProvider?: Maybe<ClusterProvider>;
Expand Down Expand Up @@ -4843,6 +4894,7 @@ export type RootMutationType = {
updateStackDefinition?: Maybe<StackDefinition>;
updateStackRun?: Maybe<StackRun>;
updateUser?: Maybe<User>;
upsertCatalog?: Maybe<Catalog>;
upsertHelmRepository?: Maybe<HelmRepository>;
upsertNotificationRouter?: Maybe<NotificationRouter>;
upsertNotificationSink?: Maybe<NotificationSink>;
Expand Down Expand Up @@ -5106,6 +5158,11 @@ export type RootMutationTypeDeleteAccessTokenArgs = {
};


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


export type RootMutationTypeDeleteCertificateArgs = {
name: Scalars['String']['input'];
namespace: Scalars['String']['input'];
Expand Down Expand Up @@ -5709,6 +5766,11 @@ export type RootMutationTypeUpdateUserArgs = {
};


export type RootMutationTypeUpsertCatalogArgs = {
attributes?: InputMaybe<CatalogAttributes>;
};


export type RootMutationTypeUpsertHelmRepositoryArgs = {
attributes?: InputMaybe<HelmRepositoryAttributes>;
url: Scalars['String']['input'];
Expand Down Expand Up @@ -5762,6 +5824,8 @@ export type RootQueryType = {
builds?: Maybe<BuildConnection>;
cachedPods?: Maybe<Array<Maybe<Pod>>>;
canary?: Maybe<Canary>;
catalog?: Maybe<Catalog>;
catalogs?: Maybe<CatalogConnection>;
certificate?: Maybe<Certificate>;
/** fetches an individual cluster */
cluster?: Maybe<Cluster>;
Expand Down Expand Up @@ -5999,6 +6063,21 @@ export type RootQueryTypeCanaryArgs = {
};


export type RootQueryTypeCatalogArgs = {
id?: InputMaybe<Scalars['ID']['input']>;
name?: InputMaybe<Scalars['String']['input']>;
};


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


export type RootQueryTypeCertificateArgs = {
name: Scalars['String']['input'];
namespace: Scalars['String']['input'];
Expand Down Expand Up @@ -8915,7 +8994,7 @@ export type VClustersQueryVariables = Exact<{
}>;


export type VClustersQuery = { __typename?: 'RootQueryType', tags?: Array<string | null> | null, clusters?: { __typename?: 'ClusterConnection', pageInfo: { __typename?: 'PageInfo', hasNextPage: boolean, endCursor?: string | null, hasPreviousPage: boolean, startCursor?: string | null }, edges?: Array<{ __typename?: 'ClusterEdge', node?: { __typename?: 'Cluster', currentVersion?: string | null, id: string, self?: boolean | null, protect?: boolean | null, name: string, handle?: string | null, distro?: ClusterDistro | null, installed?: boolean | null, pingedAt?: string | null, deletedAt?: string | null, version?: string | null, kubeletVersion?: string | null, virtual?: boolean | null, nodes?: Array<{ __typename?: 'Node', status: { __typename?: 'NodeStatus', capacity?: Record<string, unknown> | null } } | null> | null, nodeMetrics?: Array<{ __typename?: 'NodeMetric', usage?: { __typename?: 'NodeUsage', cpu?: string | null, memory?: string | null } | null } | null> | null, provider?: { __typename?: 'ClusterProvider', id: string, cloud: string, name: string, namespace: string, supportedVersions?: Array<string | null> | null } | null, prAutomations?: Array<{ __typename?: 'PrAutomation', id: string, name: string, documentation?: string | null, addon?: string | null, identifier: string, role?: PrRole | null, cluster?: { __typename?: 'Cluster', handle?: string | null, protect?: boolean | null, deletedAt?: string | null, version?: string | null, currentVersion?: string | null, id: string, name: string, self?: boolean | null, distro?: ClusterDistro | null, virtual?: boolean | null, provider?: { __typename?: 'ClusterProvider', cloud: string } | null, upgradePlan?: { __typename?: 'ClusterUpgradePlan', compatibilities?: boolean | null, deprecations?: boolean | null, incompatibilities?: boolean | null } | null } | null, service?: { __typename?: 'ServiceDeployment', id: string, name: string } | null, repository?: { __typename?: 'GitRepository', url: string, refs?: Array<string> | null } | null, connection?: { __typename?: 'ScmConnection', id: string, name: string, insertedAt?: string | null, updatedAt?: string | null, type: ScmType, username?: string | null, baseUrl?: string | null, apiUrl?: string | null } | null, createBindings?: Array<{ __typename?: 'PolicyBinding', id?: string | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null, group?: { __typename?: 'Group', id: string, name: string } | null } | null> | null, writeBindings?: Array<{ __typename?: 'PolicyBinding', id?: string | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null, group?: { __typename?: 'Group', id: string, name: string } | null } | null> | null, configuration?: Array<{ __typename?: 'PrConfiguration', values?: Array<string | null> | null, default?: string | null, documentation?: string | null, longform?: string | null, name: string, optional?: boolean | null, placeholder?: string | null, type: ConfigurationType, condition?: { __typename?: 'PrConfigurationCondition', field: string, operation: Operation, value?: string | null } | null } | null> | null } | null> | null, service?: { __typename?: 'ServiceDeployment', id: string, repository?: { __typename?: 'GitRepository', url: string } | null } | null, status?: { __typename?: 'ClusterStatus', conditions?: Array<{ __typename?: 'ClusterCondition', lastTransitionTime?: string | null, message?: string | null, reason?: string | null, severity?: string | null, status?: string | null, type?: string | null } | null> | null } | null, tags?: Array<{ __typename?: 'Tag', name: string, value: string } | null> | null, upgradePlan?: { __typename?: 'ClusterUpgradePlan', compatibilities?: boolean | null, deprecations?: boolean | null, incompatibilities?: boolean | null } | null } | null } | null> | null } | null, clusterStatuses?: Array<{ __typename?: 'ClusterStatusInfo', count?: number | null, healthy?: boolean | null } | null> | null };
export type VClustersQuery = { __typename?: 'RootQueryType', tags?: Array<string | null> | null, clusters?: { __typename?: 'ClusterConnection', pageInfo: { __typename?: 'PageInfo', hasNextPage: boolean, endCursor?: string | null, hasPreviousPage: boolean, startCursor?: string | null }, edges?: Array<{ __typename?: 'ClusterEdge', node?: { __typename?: 'Cluster', currentVersion?: string | null, id: string, self?: boolean | null, protect?: boolean | null, name: string, handle?: string | null, distro?: ClusterDistro | null, installed?: boolean | null, pingedAt?: string | null, deletedAt?: string | null, version?: string | null, kubeletVersion?: string | null, virtual?: boolean | null, nodes?: Array<{ __typename?: 'Node', status: { __typename?: 'NodeStatus', capacity?: Record<string, unknown> | null } } | null> | null, nodeMetrics?: Array<{ __typename?: 'NodeMetric', usage?: { __typename?: 'NodeUsage', cpu?: string | null, memory?: string | null } | null } | null> | null, provider?: { __typename?: 'ClusterProvider', id: string, cloud: string, name: string, namespace: string, supportedVersions?: Array<string | null> | null } | null, prAutomations?: Array<{ __typename?: 'PrAutomation', id: string, name: string, documentation?: string | null, addon?: string | null, identifier: string, role?: PrRole | null, cluster?: { __typename?: 'Cluster', handle?: string | null, protect?: boolean | null, deletedAt?: string | null, version?: string | null, currentVersion?: string | null, id: string, name: string, self?: boolean | null, distro?: ClusterDistro | null, virtual?: boolean | null, provider?: { __typename?: 'ClusterProvider', cloud: string } | null, upgradePlan?: { __typename?: 'ClusterUpgradePlan', compatibilities?: boolean | null, deprecations?: boolean | null, incompatibilities?: boolean | null } | null } | null, service?: { __typename?: 'ServiceDeployment', id: string, name: string } | null, repository?: { __typename?: 'GitRepository', url: string, refs?: Array<string> | null } | null, connection?: { __typename?: 'ScmConnection', id: string, name: string, insertedAt?: string | null, updatedAt?: string | null, type: ScmType, username?: string | null, baseUrl?: string | null, apiUrl?: string | null } | null, createBindings?: Array<{ __typename?: 'PolicyBinding', id?: string | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null, group?: { __typename?: 'Group', id: string, name: string } | null } | null> | null, writeBindings?: Array<{ __typename?: 'PolicyBinding', id?: string | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null, group?: { __typename?: 'Group', id: string, name: string } | null } | null> | null, configuration?: Array<{ __typename?: 'PrConfiguration', values?: Array<string | null> | null, default?: string | null, documentation?: string | null, longform?: string | null, name: string, optional?: boolean | null, placeholder?: string | null, type: ConfigurationType, condition?: { __typename?: 'PrConfigurationCondition', field: string, operation: Operation, value?: string | null } | null } | null> | null } | null> | null, service?: { __typename?: 'ServiceDeployment', id: string, repository?: { __typename?: 'GitRepository', url: string } | null } | null, status?: { __typename?: 'ClusterStatus', conditions?: Array<{ __typename?: 'ClusterCondition', lastTransitionTime?: string | null, message?: string | null, reason?: string | null, severity?: string | null, status?: string | null, type?: string | null } | null> | null } | null, tags?: Array<{ __typename?: 'Tag', name: string, value: string } | null> | null, upgradePlan?: { __typename?: 'ClusterUpgradePlan', compatibilities?: boolean | null, deprecations?: boolean | null, incompatibilities?: boolean | null } | null } | null } | null> | null } | null };

export type ClusterSelectorQueryVariables = Exact<{
first?: InputMaybe<Scalars['Int']['input']>;
Expand Down Expand Up @@ -14701,14 +14780,10 @@ export const VClustersDocument = gql`
}
}
}
clusterStatuses {
...ClusterStatusInfo
}
tags
}
${PageInfoFragmentDoc}
${ClustersRowFragmentDoc}
${ClusterStatusInfoFragmentDoc}`;
${ClustersRowFragmentDoc}`;

/**
* __useVClustersQuery__
Expand Down Expand Up @@ -22848,4 +22923,4 @@ export const namedOperations = {
Manifest: 'Manifest',
RefreshToken: 'RefreshToken'
}
}
}
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.

34 changes: 33 additions & 1 deletion lib/console/deployments/git.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ defmodule Console.Deployments.Git do
PullRequest,
DependencyManagementService,
HelmRepository,
Observer
Observer,
Catalog
}

require Logger
Expand All @@ -31,6 +32,7 @@ defmodule Console.Deployments.Git do
@type automation_resp :: {:ok, PrAutomation.t} | Console.error
@type pull_request_resp :: {:ok, PullRequest.t} | Console.error
@type observer_resp :: {:ok, Observer.t} | Console.error
@type catalog_resp :: {:ok, Catalog.t} | Console.error

@decorate cacheable(cache: @cache, key: {:git_repo, id}, opts: [ttl: @ttl])
def cached!(id), do: Repo.get!(GitRepository, id)
Expand Down Expand Up @@ -66,6 +68,12 @@ defmodule Console.Deployments.Git do

def get_observer!(id), do: Repo.get!(Observer, id)

def get_catalog_by_name(name), do: Repo.get_by(Catalog, name: name)

def get_catalog_by_name!(name), do: Repo.get_by!(Catalog, name: name)

def get_catalog!(id), do: Repo.get!(Catalog, id)

def get_pr_automation_by_name(name), do: Repo.get_by(PrAutomation, name: name)

def deploy_url(), do: "https://github.com/pluralsh/deployment-operator.git"
Expand Down Expand Up @@ -403,6 +411,30 @@ defmodule Console.Deployments.Git do
|> when_ok(&Repo.insert_or_update/1)
end

@doc """
Upserts a new catalog instance, requires at least project write permissions
"""
@spec upsert_catalog(map, User.t) :: catalog_resp
def upsert_catalog(%{name: name} = attrs, %User{} = user) do
case get_catalog_by_name(name) do
%Catalog{} = catalog -> Repo.preload(catalog, [:read_bindings, :write_bindings])
nil -> %Catalog{project_id: attrs[:project_id] || Settings.default_project!().id}
end
|> allow(user, :write)
|> when_ok(&Catalog.changeset(&1, attrs))
|> when_ok(&Repo.insert_or_update/1)
end

@doc """
Deletes the given catalog, works if user has write permissions on the catalog on up
"""
@spec delete_catalog(binary, User.t) :: catalog_resp
def delete_catalog(id, %User{} = user) do
get_catalog!(id)
|> allow(user, :write)
|> when_ok(:delete)
end

@doc """
Upserts a new observer which can poll external registries and perform configurable actions
as a result.
Expand Down
Loading

0 comments on commit 16b1471

Please sign in to comment.