@agilecustoms/envctl 0.30.2 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,8 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
import { KnownException } from '../exceptions.js';
|
|
2
|
+
import { TerraformBackend } from './TerraformBackend.js';
|
|
3
|
+
export class S3Backend extends TerraformBackend {
|
|
2
4
|
getType() {
|
|
3
5
|
return 's3';
|
|
4
6
|
}
|
|
5
|
-
getKey(
|
|
6
|
-
|
|
7
|
+
getKey() {
|
|
8
|
+
const key = this.config['key'];
|
|
9
|
+
if (!key) {
|
|
10
|
+
throw new KnownException(`Terraform backend config does not contain 'key' attribute`);
|
|
11
|
+
}
|
|
12
|
+
return key;
|
|
13
|
+
}
|
|
14
|
+
validateAndGetStateFileContent() {
|
|
15
|
+
return this.stateFileContent;
|
|
7
16
|
}
|
|
8
17
|
}
|
|
@@ -11,6 +11,7 @@ export class TerraformAdapter {
|
|
|
11
11
|
processRunner;
|
|
12
12
|
cliHelper;
|
|
13
13
|
backends;
|
|
14
|
+
backend = undefined;
|
|
14
15
|
constructor(processRunner, cliHelper, backends) {
|
|
15
16
|
this.processRunner = processRunner;
|
|
16
17
|
this.cliHelper = cliHelper;
|
|
@@ -19,21 +20,6 @@ export class TerraformAdapter {
|
|
|
19
20
|
return acc;
|
|
20
21
|
}, new Map());
|
|
21
22
|
}
|
|
22
|
-
getStateFile(cwd) {
|
|
23
|
-
const dir = cwd ?? process.cwd();
|
|
24
|
-
const statePath = path.join(dir, '.terraform', 'terraform.tfstate');
|
|
25
|
-
if (!fs.existsSync(statePath)) {
|
|
26
|
-
throw new KnownException(`Terraform state file not found at: ${statePath}`);
|
|
27
|
-
}
|
|
28
|
-
let content;
|
|
29
|
-
try {
|
|
30
|
-
content = fs.readFileSync(statePath, 'utf8');
|
|
31
|
-
}
|
|
32
|
-
catch (err) {
|
|
33
|
-
throw new KnownException(`Failed to read terraform state file: ${statePath}`, { cause: err });
|
|
34
|
-
}
|
|
35
|
-
return content;
|
|
36
|
-
}
|
|
37
23
|
getLockFile(cwd) {
|
|
38
24
|
const dir = cwd ?? process.cwd();
|
|
39
25
|
const lockPath = path.join(dir, '.terraform.lock.hcl');
|
|
@@ -47,11 +33,25 @@ export class TerraformAdapter {
|
|
|
47
33
|
throw new KnownException(`Failed to read terraform lock file: ${lockPath}`, { cause: err });
|
|
48
34
|
}
|
|
49
35
|
}
|
|
50
|
-
|
|
51
|
-
|
|
36
|
+
getTerraformBackend(cwd) {
|
|
37
|
+
if (this.backend) {
|
|
38
|
+
return this.backend;
|
|
39
|
+
}
|
|
40
|
+
const dir = cwd ?? process.cwd();
|
|
41
|
+
const statePath = path.join(dir, '.terraform', 'terraform.tfstate');
|
|
42
|
+
if (!fs.existsSync(statePath)) {
|
|
43
|
+
throw new KnownException(`Terraform state file not found at: ${statePath}`);
|
|
44
|
+
}
|
|
45
|
+
let stateFileContent;
|
|
46
|
+
try {
|
|
47
|
+
stateFileContent = fs.readFileSync(statePath, 'utf8');
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
throw new KnownException(`Failed to read terraform state file: ${statePath}`, { cause: err });
|
|
51
|
+
}
|
|
52
52
|
let tfstate;
|
|
53
53
|
try {
|
|
54
|
-
tfstate = JSON.parse(
|
|
54
|
+
tfstate = JSON.parse(stateFileContent);
|
|
55
55
|
}
|
|
56
56
|
catch (err) {
|
|
57
57
|
throw new KnownException(`Failed to parse terraform state file: .terraform/terraform.tfstate`, { cause: err });
|
|
@@ -63,12 +63,9 @@ export class TerraformAdapter {
|
|
|
63
63
|
const supportedBackends = Array.from(this.backends.keys()).join(',');
|
|
64
64
|
throw new KnownException(`Unsupported terraform backend type: ${type}. Supported types: ${supportedBackends}`);
|
|
65
65
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
throw new KnownException(`Terraform backend config does not contain 'key' attribute`);
|
|
70
|
-
}
|
|
71
|
-
return key;
|
|
66
|
+
backend.setState(stateFileContent, backendJson.config);
|
|
67
|
+
this.backend = backend;
|
|
68
|
+
return backend;
|
|
72
69
|
}
|
|
73
70
|
async lockProviders(cwd) {
|
|
74
71
|
console.log('Update lock file');
|
package/dist/service/EnvCtl.js
CHANGED
|
@@ -14,7 +14,7 @@ export class EnvCtl {
|
|
|
14
14
|
getKey(key, cwd) {
|
|
15
15
|
if (!key) {
|
|
16
16
|
console.log('Key is not provided, inferring from .terraform/terraform.tfstate file');
|
|
17
|
-
key = this.terraformAdapter.
|
|
17
|
+
key = this.terraformAdapter.getTerraformBackend(cwd).getKey();
|
|
18
18
|
}
|
|
19
19
|
return key;
|
|
20
20
|
}
|
|
@@ -80,7 +80,7 @@ export class EnvCtl {
|
|
|
80
80
|
throw new KnownException(`Env ${env.key} status is ${env.status}, can not run this command`);
|
|
81
81
|
}
|
|
82
82
|
async plan(tfArgs, cwd) {
|
|
83
|
-
const key = this.terraformAdapter.
|
|
83
|
+
const key = this.terraformAdapter.getTerraformBackend(cwd).getKey();
|
|
84
84
|
const userName = this.configService.getUserName();
|
|
85
85
|
const env = await this.tryGetEnv(key);
|
|
86
86
|
let vars = undefined;
|
|
@@ -106,11 +106,11 @@ export class EnvCtl {
|
|
|
106
106
|
}
|
|
107
107
|
async lockTerraform(env, cwd) {
|
|
108
108
|
await this.terraformAdapter.lockProviders(cwd);
|
|
109
|
-
env.stateFile = this.terraformAdapter.
|
|
109
|
+
env.stateFile = this.terraformAdapter.getTerraformBackend(cwd).validateAndGetStateFileContent();
|
|
110
110
|
env.lockFile = this.terraformAdapter.getLockFile(cwd);
|
|
111
111
|
}
|
|
112
112
|
async deploy(tfArgs, cwd) {
|
|
113
|
-
const key = this.terraformAdapter.
|
|
113
|
+
const key = this.terraformAdapter.getTerraformBackend(cwd).getKey();
|
|
114
114
|
let env = await this.tryGetEnv(key);
|
|
115
115
|
if (env === null) {
|
|
116
116
|
const kind = this.cliHelper.getKind(cwd);
|
|
@@ -191,7 +191,7 @@ export class EnvCtl {
|
|
|
191
191
|
console.log(message);
|
|
192
192
|
}
|
|
193
193
|
async destroy(tfArgs, force, cwd) {
|
|
194
|
-
const key = this.terraformAdapter.
|
|
194
|
+
const key = this.terraformAdapter.getTerraformBackend(cwd).getKey();
|
|
195
195
|
const env = await this.get(key);
|
|
196
196
|
this.checkStatus(env);
|
|
197
197
|
if (env.status === EnvStatus.Init) {
|