diff options
Diffstat (limited to 'app/assets/javascripts/environments/graphql/resolvers/flux.js')
-rw-r--r-- | app/assets/javascripts/environments/graphql/resolvers/flux.js | 116 |
1 files changed, 75 insertions, 41 deletions
diff --git a/app/assets/javascripts/environments/graphql/resolvers/flux.js b/app/assets/javascripts/environments/graphql/resolvers/flux.js index d39b1bed7b6..5cb5db5d752 100644 --- a/app/assets/javascripts/environments/graphql/resolvers/flux.js +++ b/app/assets/javascripts/environments/graphql/resolvers/flux.js @@ -1,35 +1,83 @@ +import { Configuration, WatchApi, EVENT_DATA } from '@gitlab/cluster-client'; import axios from '~/lib/utils/axios_utils'; import { HELM_RELEASES_RESOURCE_TYPE, KUSTOMIZATIONS_RESOURCE_TYPE, } from '~/environments/constants'; +import fluxKustomizationStatusQuery from '../queries/flux_kustomization_status.query.graphql'; +import fluxHelmReleaseStatusQuery from '../queries/flux_helm_release_status.query.graphql'; const helmReleasesApiVersion = 'helm.toolkit.fluxcd.io/v2beta1'; const kustomizationsApiVersion = 'kustomize.toolkit.fluxcd.io/v1beta1'; +const helmReleaseField = 'fluxHelmReleaseStatus'; +const kustomizationField = 'fluxKustomizationStatus'; + const handleClusterError = (err) => { const error = err?.response?.data?.message ? new Error(err.response.data.message) : err; throw error; }; -const buildFluxResourceUrl = ({ - basePath, - namespace, - apiVersion, - resourceType, - environmentName = '', -}) => { - return `${basePath}/apis/${apiVersion}/namespaces/${namespace}/${resourceType}/${environmentName}`; +const buildFluxResourceUrl = ({ basePath, namespace, apiVersion, resourceType }) => { + return `${basePath}/apis/${apiVersion}/namespaces/${namespace}/${resourceType}`; }; -const getFluxResourceStatus = (configuration, url) => { - const { headers } = configuration; +const buildFluxResourceWatchPath = ({ namespace, apiVersion, resourceType }) => { + return `/apis/${apiVersion}/namespaces/${namespace}/${resourceType}`; +}; + +const watchFluxResource = ({ watchPath, resourceName, query, variables, field, client }) => { + const config = new Configuration(variables.configuration); + const watcherApi = new WatchApi(config); + const fieldSelector = `metadata.name=${decodeURIComponent(resourceName)}`; + + watcherApi + .subscribeToStream(watchPath, { watch: true, fieldSelector }) + .then((watcher) => { + let result = []; + + watcher.on(EVENT_DATA, (data) => { + result = data[0]?.status?.conditions; + + client.writeQuery({ + query, + variables, + data: { [field]: result }, + }); + }); + }) + .catch((err) => { + handleClusterError(err); + }); +}; + +const getFluxResourceStatus = ({ query, variables, field, resourceType, client }) => { + const { headers } = variables.configuration; const withCredentials = true; + const url = `${variables.configuration.basePath}/apis/${variables.fluxResourcePath}`; return axios .get(url, { withCredentials, headers }) .then((res) => { - return res?.data?.status?.conditions || []; + const fluxData = res?.data; + const resourceName = fluxData?.metadata?.name; + const namespace = fluxData?.metadata?.namespace; + const apiVersion = fluxData?.apiVersion; + + if (gon.features?.k8sWatchApi && resourceName) { + const watchPath = buildFluxResourceWatchPath({ namespace, apiVersion, resourceType }); + + watchFluxResource({ + watchPath, + resourceName, + query, + variables, + field, + client, + }); + } + + return fluxData?.status?.conditions || []; }) .catch((err) => { handleClusterError(err); @@ -62,37 +110,23 @@ const getFluxResources = (configuration, url) => { }; export default { - fluxKustomizationStatus(_, { configuration, namespace, environmentName, fluxResourcePath = '' }) { - let url; - - if (fluxResourcePath) { - url = `${configuration.basePath}/apis/${fluxResourcePath}`; - } else { - url = buildFluxResourceUrl({ - basePath: configuration.basePath, - resourceType: KUSTOMIZATIONS_RESOURCE_TYPE, - apiVersion: kustomizationsApiVersion, - namespace, - environmentName, - }); - } - return getFluxResourceStatus(configuration, url); + fluxKustomizationStatus(_, { configuration, fluxResourcePath }, { client }) { + return getFluxResourceStatus({ + query: fluxKustomizationStatusQuery, + variables: { configuration, fluxResourcePath }, + field: kustomizationField, + resourceType: KUSTOMIZATIONS_RESOURCE_TYPE, + client, + }); }, - fluxHelmReleaseStatus(_, { configuration, namespace, environmentName, fluxResourcePath }) { - let url; - - if (fluxResourcePath) { - url = `${configuration.basePath}/apis/${fluxResourcePath}`; - } else { - url = buildFluxResourceUrl({ - basePath: configuration.basePath, - resourceType: HELM_RELEASES_RESOURCE_TYPE, - apiVersion: helmReleasesApiVersion, - namespace, - environmentName, - }); - } - return getFluxResourceStatus(configuration, url); + fluxHelmReleaseStatus(_, { configuration, fluxResourcePath }, { client }) { + return getFluxResourceStatus({ + query: fluxHelmReleaseStatusQuery, + variables: { configuration, fluxResourcePath }, + field: helmReleaseField, + resourceType: HELM_RELEASES_RESOURCE_TYPE, + client, + }); }, fluxKustomizations(_, { configuration, namespace }) { const url = buildFluxResourceUrl({ |