1
+ import { Configuration , WatchApi , EVENT_DATA } from '@gitlab/cluster-client' ;
1
2
import axios from '~/lib/utils/axios_utils' ;
2
3
import {
3
4
HELM_RELEASES_RESOURCE_TYPE ,
4
5
KUSTOMIZATIONS_RESOURCE_TYPE ,
5
6
} from '~/environments/constants' ;
7
+ import fluxKustomizationStatusQuery from '../queries/flux_kustomization_status.query.graphql' ;
8
+ import fluxHelmReleaseStatusQuery from '../queries/flux_helm_release_status.query.graphql' ;
6
9
7
10
const helmReleasesApiVersion = 'helm.toolkit.fluxcd.io/v2beta1' ;
8
11
const kustomizationsApiVersion = 'kustomize.toolkit.fluxcd.io/v1beta1' ;
9
12
13
+ const helmReleaseField = 'fluxHelmReleaseStatus' ;
14
+ const kustomizationField = 'fluxKustomizationStatus' ;
15
+
10
16
const handleClusterError = ( err ) => {
11
17
const error = err ?. response ?. data ?. message ? new Error ( err . response . data . message ) : err ;
12
18
throw error ;
@@ -22,14 +28,57 @@ const buildFluxResourceUrl = ({
22
28
return `${ basePath } /apis/${ apiVersion } /namespaces/${ namespace } /${ resourceType } /${ environmentName } ` ;
23
29
} ;
24
30
25
- const getFluxResourceStatus = ( configuration , url ) => {
26
- const { headers } = configuration ;
31
+ const buildFluxResourceWatchPath = ( { namespace, apiVersion, resourceType } ) => {
32
+ return `/apis/${ apiVersion } /namespaces/${ namespace } /${ resourceType } ` ;
33
+ } ;
34
+
35
+ const watchFluxResource = ( { watchPath, resourceName, query, variables, field, client } ) => {
36
+ const config = new Configuration ( variables . configuration ) ;
37
+ const watcherApi = new WatchApi ( config ) ;
38
+ const fieldSelector = `metadata.name=${ decodeURIComponent ( resourceName ) } ` ;
39
+
40
+ watcherApi
41
+ . subscribeToStream ( watchPath , { watch : true , fieldSelector } )
42
+ . then ( ( watcher ) => {
43
+ let result = [ ] ;
44
+
45
+ watcher . on ( EVENT_DATA , ( data ) => {
46
+ result = data [ 0 ] ?. status ?. conditions ;
47
+
48
+ client . writeQuery ( {
49
+ query,
50
+ variables,
51
+ data : { [ field ] : result } ,
52
+ } ) ;
53
+ } ) ;
54
+ } )
55
+ . catch ( ( err ) => {
56
+ handleClusterError ( err ) ;
57
+ } ) ;
58
+ } ;
59
+
60
+ const getFluxResourceStatus = ( { url, watchPath, query, variables, field, client } ) => {
61
+ const { headers } = variables . configuration ;
27
62
const withCredentials = true ;
28
63
29
64
return axios
30
65
. get ( url , { withCredentials, headers } )
31
66
. then ( ( res ) => {
32
- return res ?. data ?. status ?. conditions || [ ] ;
67
+ const fluxData = res ?. data ;
68
+ const resourceName = fluxData ?. metadata ?. name ;
69
+
70
+ if ( gon . features ?. k8sWatchApi && resourceName ) {
71
+ watchFluxResource ( {
72
+ watchPath,
73
+ resourceName,
74
+ query,
75
+ variables,
76
+ field,
77
+ client,
78
+ } ) ;
79
+ }
80
+
81
+ return fluxData ?. status ?. conditions || [ ] ;
33
82
} )
34
83
. catch ( ( err ) => {
35
84
handleClusterError ( err ) ;
@@ -62,7 +111,16 @@ const getFluxResources = (configuration, url) => {
62
111
} ;
63
112
64
113
export default {
65
- fluxKustomizationStatus ( _ , { configuration, namespace, environmentName, fluxResourcePath = '' } ) {
114
+ fluxKustomizationStatus (
115
+ _ ,
116
+ { configuration, namespace, environmentName, fluxResourcePath = '' } ,
117
+ { client } ,
118
+ ) {
119
+ const watchPath = buildFluxResourceWatchPath ( {
120
+ namespace,
121
+ apiVersion : kustomizationsApiVersion ,
122
+ resourceType : KUSTOMIZATIONS_RESOURCE_TYPE ,
123
+ } ) ;
66
124
let url ;
67
125
68
126
if ( fluxResourcePath ) {
@@ -76,9 +134,25 @@ export default {
76
134
environmentName,
77
135
} ) ;
78
136
}
79
- return getFluxResourceStatus ( configuration , url ) ;
137
+ return getFluxResourceStatus ( {
138
+ url,
139
+ watchPath,
140
+ query : fluxKustomizationStatusQuery ,
141
+ variables : { configuration, namespace, environmentName, fluxResourcePath } ,
142
+ field : kustomizationField ,
143
+ client,
144
+ } ) ;
80
145
} ,
81
- fluxHelmReleaseStatus ( _ , { configuration, namespace, environmentName, fluxResourcePath } ) {
146
+ fluxHelmReleaseStatus (
147
+ _ ,
148
+ { configuration, namespace, environmentName, fluxResourcePath } ,
149
+ { client } ,
150
+ ) {
151
+ const watchPath = buildFluxResourceWatchPath ( {
152
+ namespace,
153
+ apiVersion : helmReleasesApiVersion ,
154
+ resourceType : HELM_RELEASES_RESOURCE_TYPE ,
155
+ } ) ;
82
156
let url ;
83
157
84
158
if ( fluxResourcePath ) {
@@ -92,7 +166,14 @@ export default {
92
166
environmentName,
93
167
} ) ;
94
168
}
95
- return getFluxResourceStatus ( configuration , url ) ;
169
+ return getFluxResourceStatus ( {
170
+ url,
171
+ watchPath,
172
+ query : fluxHelmReleaseStatusQuery ,
173
+ variables : { configuration, namespace, environmentName, fluxResourcePath } ,
174
+ field : helmReleaseField ,
175
+ client,
176
+ } ) ;
96
177
} ,
97
178
fluxKustomizations ( _ , { configuration, namespace } ) {
98
179
const url = buildFluxResourceUrl ( {
0 commit comments