Skip to content

Commit

Permalink
feat(script): Script for rolling out env vars to render runners (#2984)
Browse files Browse the repository at this point in the history
## Describe your changes

To roll out providers updating in runners we needed to be able to ship
some new env vars to existing runners. I went ahead and ran this against
staging with the new variables we needed to ensure it was working
correctly.

Usage:

```
ENVIRONMENT=staging \
OWNER_ID=<OWNER_ID> \
RENDER_API_KEY=<RENDER_API_KEY> \
KEY=PROVIDERS_RELOAD_INTERVAL \
VALUE=60000 \
node ./scripts/runner-env.js
```

## Issue ticket number and link

https://linear.app/nango/issue/NAN-2105/dynamically-reload-providersyaml

## Checklist before requesting a review (skip if just adding/editing
APIs & templates)
- [ ] I added tests, otherwise the reason is: 
- [ ] I added observability, otherwise the reason is:
- [ ] I added analytics, otherwise the reason is:
  • Loading branch information
nalanj authored Nov 14, 2024
1 parent a81fe2b commit be33cf8
Showing 1 changed file with 99 additions and 0 deletions.
99 changes: 99 additions & 0 deletions scripts/runner-update-env.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!/usr/bin/env node

// Update environment variables for all runners in the given environment

const apiUrl = 'https://api.render.com/v1';

if (!process.env.ENVIRONMENT || !process.env.OWNER_ID || !process.env.RENDER_API_KEY || !process.env.KEY || !process.env.VALUE) {
help();
process.exit(1);
}

console.log('Listing runners...');
const runners = await fetchRunners();
console.log(`Found ${runners.length} runners`);
console.log('Updating env vars...');

for (let i = 0; i < runners.length; i++) {
const runner = runners[i];
await updateEnvVar(runner.id, process.env.KEY, process.env.VALUE);
console.log(`${i + 1} of ${runners.length}: ${runner.name}`);
}

console.log();
console.log('Remember: these changes will not take effect until the runner is restarted.');
console.log();

function help() {
console.log();
console.log(
'Usage: ENVIRONMENT=<env> OWNER_ID=<OWNER_ID> RENDER_API_KEY=<RENDER_API_KEY> KEY=<ENV-KEY> VALUE=<ENV-VALUE> node ./scripts/runner-update-env.js'
);
console.log();
}

function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}

async function fetchRunners() {
let services = [];
let cursor = '';

// eslint-disable-next-line no-constant-condition
while (true) {
const params = new URLSearchParams({
limit: 100,
cursor,
type: 'private_service',
ownerId: process.env.OWNER_ID
});

const response = await fetch(`${apiUrl}/services?${params.toString()}`, {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${process.env.RENDER_API_KEY}`
}
});

const fetched = await response.json();
if (fetched.length === 0) {
break;
}

cursor = fetched[fetched.length - 1].cursor;
console.log(cursor);

// eslint-disable-next-line prettier/prettier
const filteredServices = fetched
.map((item) => item.service)
.filter((service) =>
service.name.startsWith(`${process.env.ENVIRONMENT}-runner-`));

services = services.concat(filteredServices);

await sleep(1000);
}

return services;
}

async function updateEnvVar(serviceId, key, value) {
const response = await fetch(`${apiUrl}/services/${serviceId}/env-vars/${key}`, {
method: 'PUT',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${process.env.RENDER_API_KEY}`
},
body: JSON.stringify({
value
})
});

if (!response.ok) {
const body = await response.text();
throw new Error(`Failed to update env var ${key} for service ${serviceId}\n${body}`);
}
}

0 comments on commit be33cf8

Please # to comment.