Skip to content

Commit 2b14386

Browse files
committed
refactor: additional changes to support idling/unidling and stop/start/restart
1 parent 4441296 commit 2b14386

File tree

6 files changed

+138
-76
lines changed

6 files changed

+138
-76
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ UI_IMAGE_TAG = main
8080

8181
# OVERRIDE_REMOTE_CONTROLLER_IMAGETAG and OVERRIDE_REMOTE_CONTROLLER_IMAGE_REPOSITORY
8282
# set this to a particular remote-controller image if required, defaults to nothing to consume what the chart provides
83-
OVERRIDE_REMOTE_CONTROLLER_IMAGETAG=
83+
OVERRIDE_REMOTE_CONTROLLER_IMAGETAG=pr-245
8484
OVERRIDE_REMOTE_CONTROLLER_IMAGE_REPOSITORY=
8585

8686
# To build k3d with Calico instead of Flannel, set this to true. Note that the Calico install in lagoon-charts is always

node-packages/commons/src/tasks.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,11 +1353,11 @@ export const createMiscTask = async function(taskData: any) {
13531353
break;
13541354
case 'deploytarget:environment:idling':
13551355
// environment idling is used to handle idling or unidling of an an environment
1356-
miscTaskData.idling = taskData.data.idling
1356+
miscTaskData.misc.miscResource = encodeJSONBase64(taskData.data.idling)
13571357
break;
13581358
case 'deploytarget:environment:service':
13591359
// environment service is used to handle stop, start, or restarting of a service in an environment
1360-
miscTaskData.lagoonService = taskData.data.lagoonService
1360+
miscTaskData.misc.miscResource = encodeJSONBase64(taskData.data.lagoonService)
13611361
break;
13621362
default:
13631363
miscTaskData.misc = taskData.data.build

services/actions-handler/handler/controller_idling.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ type Idled struct {
2121

2222
func (m *Messenger) handleIdling(ctx context.Context, messageQueue *mq.MessageQueue, message *schema.LagoonMessage, messageID string) error {
2323
prefix := fmt.Sprintf("(messageid:%s) %s: ", messageID, message.Namespace)
24-
log.Println(fmt.Sprintf("%sreceived idling environment status update", prefix))
24+
log.Printf("%sreceived idling environment status update", prefix)
2525
// generate a lagoon token with a expiry of 60 seconds from now
2626
token, err := jwt.GenerateAdminToken(m.LagoonAPI.TokenSigningKey, m.LagoonAPI.JWTAudience, m.LagoonAPI.JWTSubject, m.LagoonAPI.JWTIssuer, time.Now().Unix(), 60)
2727
if err != nil {
2828
// the token wasn't generated
2929
if m.EnableDebug {
30-
log.Println(fmt.Sprintf("ERROR: unable to generate token: %v", err))
30+
log.Printf("ERROR: unable to generate token: %v", err)
3131
}
3232
return nil
3333
}
@@ -46,7 +46,7 @@ func (m *Messenger) handleIdling(ctx context.Context, messageQueue *mq.MessageQu
4646
"message": err.Error(),
4747
})
4848
if m.EnableDebug {
49-
log.Println(fmt.Sprintf("%sERROR: unable to get project - %v", prefix, err))
49+
log.Printf("%sERROR: unable to get project - %v", prefix, err)
5050
}
5151
return err
5252
}
@@ -60,7 +60,7 @@ func (m *Messenger) handleIdling(ctx context.Context, messageQueue *mq.MessageQu
6060
"message": err.Error(),
6161
})
6262
if m.EnableDebug {
63-
log.Println(fmt.Sprintf("%sERROR: unable to get environment - %v", prefix, err))
63+
log.Printf("%sERROR: unable to get environment - %v", prefix, err)
6464
}
6565
return err
6666
}
@@ -85,10 +85,10 @@ func (m *Messenger) handleIdling(ctx context.Context, messageQueue *mq.MessageQu
8585
"message": err.Error(),
8686
})
8787
if m.EnableDebug {
88-
log.Println(fmt.Sprintf("%sERROR: unable to update environment - %v", prefix, err))
88+
log.Printf("%sERROR: unable to update environment - %v", prefix, err)
8989
}
9090
return err
9191
}
92-
log.Println(fmt.Sprintf("%supdated environment", prefix))
92+
log.Printf("%supdated environment", prefix)
9393
return nil
9494
}

services/api/src/resolvers.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,8 @@ const {
128128
getEnvironmentByServiceId,
129129
getServiceContainersByServiceId,
130130
deleteEnvironmentService,
131-
environmentIdling,
131+
idleOrUnidleEnvironment,
132+
stopOrStartEnvironmentService,
132133
} = require('./resources/environment/resolvers');
133134

134135
const {
@@ -507,6 +508,11 @@ async function getResolvers() {
507508
Redirect: 'Redirect',
508509
None: 'None',
509510
},
511+
EnvironmentServiceAction: {
512+
STOP: 'stop',
513+
START: 'start',
514+
RESTART: 'restart',
515+
},
510516
Openshift: {
511517
projectUser: getProjectUser,
512518
token: getToken,
@@ -898,7 +904,8 @@ async function getResolvers() {
898904
updateAutogeneratedRouteConfigOnEnvironment,
899905
removeAutogeneratedRouteConfigFromProject,
900906
removeAutogeneratedRouteConfigFromEnvironment,
901-
environmentIdling,
907+
idleOrUnidleEnvironment,
908+
stopOrStartEnvironmentService
902909
},
903910
Subscription: {
904911
backupChanged: backupSubscriber,

services/api/src/resources/environment/resolvers.ts

Lines changed: 97 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,67 +1108,72 @@ export const getServiceContainersByServiceId: ResolverFn = async (
11081108
return await rows;
11091109
};
11101110

1111-
export const environmentIdling = async (
1111+
export const idleOrUnidleEnvironment = async (
11121112
root,
1113-
input,
1113+
{
1114+
input: {
1115+
environment,
1116+
project,
1117+
idle,
1118+
disableAutomaticUnidling
1119+
}
1120+
},
11141121
{ sqlClientPool, hasPermission, userActivityLogger }
11151122
) => {
1116-
const environment = await Helpers(sqlClientPool).getEnvironmentById(input.id);
1117-
if (!environment) {
1123+
const projectId = await projectHelpers(sqlClientPool).getProjectIdByName(project)
1124+
const projectData = await projectHelpers(sqlClientPool).getProjectById(projectId)
1125+
// @TODO: add permission to idle/unidle environment
1126+
await hasPermission('deployment', 'cancel', {
1127+
project: projectId
1128+
});
1129+
1130+
const env = await Helpers(sqlClientPool).getEnvironmentByNameAndProject(environment, projectId)
1131+
const environmentData = env[0]
1132+
if (!environmentData) {
11181133
throw new Error(
11191134
`Unauthorized: You don't have permission to "cancel" on "deployment"`
11201135
);
11211136
}
11221137

1123-
// @TODO: add permission to idle/unidle environment
1124-
await hasPermission('deployment', 'cancel', {
1125-
project: environment.project
1126-
});
1127-
11281138
// don't try idle if the environment is already idled or unidled
1129-
if (environment.idled && input.idle) {
1139+
if (environmentData.idled && idle) {
11301140
throw new Error(
11311141
`Environment is already idled`
11321142
);
11331143
}
1134-
if (!environment.idled && !input.idle) {
1144+
if (!environmentData.idled && !idle) {
11351145
throw new Error(
11361146
`Environment is already unidled`
11371147
);
11381148
}
11391149

1140-
const project = await projectHelpers(sqlClientPool).getProjectById(
1141-
environment.project
1142-
);
1143-
11441150
const data = {
1145-
environment,
1146-
project,
1151+
environment: environmentData,
1152+
project: projectData,
11471153
idling: {
1148-
idle: input.idle,
1149-
forceScale: input.disableAutomaticUnidling
1154+
idle: idle,
1155+
forceScale: disableAutomaticUnidling
11501156
}
11511157
};
1158+
11521159
const auditLog: AuditLog = {
11531160
resource: {
1154-
id: project.id.toString(),
1161+
id: projectData.id.toString(),
11551162
type: AuditType.PROJECT,
1156-
details: project.name,
1163+
details: projectData.name,
11571164
},
11581165
linkedResource: {
1159-
id: environment.id.toString(),
1166+
id: environmentData.id.toString(),
11601167
type: AuditType.ENVIRONMENT,
1161-
details: `${environment.name}, idled: ${input.idle}, unidlingDisabled: ${input.disableAutomaticUnidling}`,
1168+
details: `${environmentData.name}, idled: ${idle}, unidlingDisabled: ${disableAutomaticUnidling}`,
11621169
},
11631170
};
1164-
userActivityLogger(`User requested environment idling for '${environment.name}'`, {
1171+
userActivityLogger(`User requested environment idling for '${environmentData.name}'`, {
11651172
project: '',
1166-
event: 'api:environmentIdling',
1173+
event: 'api:idleOrUnidleEnvironment',
11671174
payload: {
1168-
project: project.name,
1169-
environment: environment.name,
1170-
idle: input.idle,
1171-
disableAutomaticUnidling: input.disableAutomaticUnidling,
1175+
project: projectData.name,
1176+
environment: environmentData.name,
11721177
...auditLog,
11731178
}
11741179
});
@@ -1181,8 +1186,8 @@ export const environmentIdling = async (
11811186
'error',
11821187
'',
11831188
'',
1184-
'api:environmentIdling',
1185-
{ environment: environment.id },
1189+
'api:idleOrUnidleEnvironment',
1190+
{ environment: environmentData.id },
11861191
`Environment idle attempt possibly failed, reason: ${error}`
11871192
);
11881193
throw new Error(
@@ -1191,67 +1196,95 @@ export const environmentIdling = async (
11911196
}
11921197
};
11931198

1194-
export const environmentService = async (
1199+
export const stopOrStartEnvironmentService = async (
11951200
root,
1196-
input,
1201+
{
1202+
input: {
1203+
environment,
1204+
project,
1205+
serviceName,
1206+
state
1207+
}
1208+
},
11971209
{ sqlClientPool, hasPermission, userActivityLogger }
11981210
) => {
1199-
const environment = await Helpers(sqlClientPool).getEnvironmentById(input.id);
1200-
if (!environment) {
1211+
const projectId = await projectHelpers(sqlClientPool).getProjectIdByName(project)
1212+
const projectData = await projectHelpers(sqlClientPool).getProjectById(projectId)
1213+
// @TODO: add permission to stop/start/restart environment
1214+
await hasPermission('deployment', 'cancel', {
1215+
project: projectId
1216+
});
1217+
1218+
const env = await Helpers(sqlClientPool).getEnvironmentByNameAndProject(environment, projectId)
1219+
const environmentData = env[0]
1220+
if (!environmentData) {
12011221
throw new Error(
12021222
`Unauthorized: You don't have permission to "cancel" on "deployment"`
12031223
);
12041224
}
12051225

1206-
// @TODO: add permission to restart service in environment
1207-
await hasPermission('deployment', 'cancel', {
1208-
project: environment.project
1209-
});
1210-
1211-
const rows = await Helpers(sqlClientPool).getEnvironmentServices(environment.id)
1226+
const rows = await Helpers(sqlClientPool).getEnvironmentServices(environmentData.id)
12121227
let serviceExists = false;
1213-
if (rows && rows.find(e => e.name === input.name)) {
1214-
serviceExists = true
1228+
if (rows) {
1229+
for (const service of rows) {
1230+
if (service.name != serviceName) {
1231+
continue;
1232+
}
1233+
switch (state) {
1234+
case 'stop':
1235+
if (service.state === 'stopped') {
1236+
throw new Error(
1237+
`Service ${serviceName} is already stopped`
1238+
);
1239+
}
1240+
break;
1241+
case 'start':
1242+
if (service.state === 'running') {
1243+
throw new Error(
1244+
`Service ${serviceName} is already running`
1245+
);
1246+
}
1247+
break;
1248+
default:
1249+
break;
1250+
}
1251+
serviceExists = true
1252+
}
12151253
}
12161254
if (!serviceExists) {
12171255
throw new Error(
1218-
`Service ${input.serviceName} doesn't exist on environment`
1256+
`Service ${serviceName} doesn't exist on environment`
12191257
);
12201258
}
12211259

1222-
const project = await projectHelpers(sqlClientPool).getProjectById(
1223-
environment.project
1224-
);
1225-
12261260
const data = {
1227-
environment,
1228-
project,
1261+
environment: environmentData,
1262+
project: projectData,
12291263
lagoonService: {
1230-
name: input.serviceName,
1231-
state: input.state
1264+
name: serviceName,
1265+
state: state
12321266
}
12331267
};
12341268

12351269
const auditLog: AuditLog = {
12361270
resource: {
1237-
id: project.id.toString(),
1271+
id: projectData.id.toString(),
12381272
type: AuditType.PROJECT,
1239-
details: project.name,
1273+
details: projectData.name,
12401274
},
12411275
linkedResource: {
1242-
id: environment.id.toString(),
1276+
id: environmentData.id.toString(),
12431277
type: AuditType.ENVIRONMENT,
1244-
details: `${environment.name}, service: ${input.serviceName}, state: ${input.state}`,
1278+
details: `${environmentData.name}, service: ${serviceName}, state: ${state}`,
12451279
},
12461280
};
1247-
userActivityLogger(`User requested environment service change for '${environment.name}'`, {
1281+
1282+
userActivityLogger(`User requested environment service change for '${environmentData.name}'`, {
12481283
project: '',
1249-
event: 'api:environmentService',
1284+
event: 'api:stopOrStartEnvironmentService',
12501285
payload: {
1251-
project: project.name,
1252-
environment: environment.name,
1253-
idle: input.idle,
1254-
disableAutomaticUnidling: input.disableAutomaticUnidling,
1286+
project: projectData.name,
1287+
environment: environmentData.name,
12551288
...auditLog
12561289
}
12571290
});
@@ -1264,8 +1297,8 @@ export const environmentService = async (
12641297
'error',
12651298
'',
12661299
'',
1267-
'api:environmentService',
1268-
{ environment: environment.id },
1300+
'api:stopOrStartEnvironmentService',
1301+
{ environment: environmentData.id },
12691302
`Environment idle attempt possibly failed, reason: ${error}`
12701303
);
12711304
throw new Error(

0 commit comments

Comments
 (0)