@kumologica/sdk 3.4.0 → 3.5.0-beta2

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.
Files changed (51) hide show
  1. package/cli/commands/create-commands/openapi.js +42 -0
  2. package/cli/commands/create.js +17 -8
  3. package/cli/commands/login.js +87 -0
  4. package/package.json +18 -7
  5. package/src/app/lib/ai/layout.js +75 -0
  6. package/src/app/lib/ai/openai.js +108 -0
  7. package/src/app/lib/ai/prompt.txt +583 -0
  8. package/src/app/lib/aws/ca-cloudwatch-api.js +2 -10
  9. package/src/app/lib/aws/ca-dynamodb-api.js +6 -10
  10. package/src/app/lib/aws/ca-elb-api.js +4 -24
  11. package/src/app/lib/aws/ca-events-api.js +5 -12
  12. package/src/app/lib/aws/ca-iot-api.js +3 -87
  13. package/src/app/lib/aws/ca-s3-api.js +17 -62
  14. package/src/app/lib/aws/ca-sns-api.js +6 -15
  15. package/src/app/lib/aws/ca-sqs-api.js +9 -6
  16. package/src/app/lib/aws/index.js +70 -86
  17. package/src/app/lib/aws/kl-apigw-api.js +40 -0
  18. package/src/app/lib/aws/kl-iam-api.js +5 -5
  19. package/src/app/lib/github/index.js +0 -17
  20. package/src/app/lib/serverless/index.js +1 -1
  21. package/src/app/lib/stores/settings-cloud-store.js +35 -2
  22. package/src/app/main.js +34 -32
  23. package/src/app/preload.js +36 -28
  24. package/src/app/ui/editor-client/public/red/red.js +924 -458
  25. package/src/app/ui/editor-client/public/red/red.min.js +2 -2
  26. package/src/app/ui/editor-client/public/red/style.min.css +1 -1
  27. package/src/app/ui/editor-client/src/js/nodes.js +19 -18
  28. package/src/app/ui/editor-client/src/js/red.js +6 -3
  29. package/src/app/ui/editor-client/src/js/ui/editor.js +70 -70
  30. package/src/app/ui/editor-client/src/js/ui/footer.js +143 -0
  31. package/src/app/ui/editor-client/src/js/ui/search.js +43 -34
  32. package/src/app/ui/editor-client/src/js/ui/sidebar.js +26 -24
  33. package/src/app/ui/editor-client/src/js/ui/signup.js +56 -0
  34. package/src/app/ui/editor-client/src/js/ui/tab-ai.js +210 -0
  35. package/src/app/ui/editor-client/src/js/ui/tab-awsDeploy.js +30 -5
  36. package/src/app/ui/editor-client/src/js/ui/tab-test.js +120 -99
  37. package/src/app/ui/editor-client/src/js/ui/update-panel.js +0 -1
  38. package/src/app/ui/editor-client/src/js/ui/view.js +201 -202
  39. package/src/app/ui/editor-client/src/sass/editor.scss +715 -645
  40. package/src/app/ui/editor-client/src/sass/sidebar.scss +21 -12
  41. package/src/app/ui/editor-client/src/sass/style.scss +101 -0
  42. package/src/app/ui/editor-client/src/sass/tab-ai.scss +68 -0
  43. package/src/app/ui/editor-client/src/sass/workspace.scss +12 -2
  44. package/src/app/ui/editor-client/templates/index.mst +41 -7
  45. package/src/server/DesignerServer.js +2 -1
  46. package/cli/.DS_Store +0 -0
  47. package/fixtures/.DS_Store +0 -0
  48. package/src/app/lib/aws/ca-apigw-api.js +0 -216
  49. package/src/app/lib/aws/ca-codecommit-api.js +0 -63
  50. package/src/app/lib/aws/kl-rekognition-api.js +0 -66
  51. package/src/app/lib/aws/kl-ssm-api.js +0 -24
@@ -1,18 +1,19 @@
1
1
  const fs = require('fs-extra');
2
2
  const path = require('path');
3
- const AWS = require('aws-sdk');
4
3
  const CAAWSCloudWatch = require('./ca-cloudwatch-api');
5
4
  const CAS3 = require('./ca-s3-api');
6
5
  const CASNS = require('./ca-sns-api');
7
6
  const CASQS = require('./ca-sqs-api');
8
- const CAAWSApiGateway = require('./ca-apigw-api');
7
+ const KLAWSApiGateway = require('./kl-apigw-api');
8
+ const KLIAM = require('./kl-iam-api');
9
9
  const CADynamoDb = require('./ca-dynamodb-api');
10
10
  const CAEvents = require('./ca-events-api');
11
11
  const AWSProfile = require('./aws-profile');
12
12
  const { openFileOnEditor } = require('../utils/editor');
13
13
  const { exp } = require('@kumologica/builder');
14
14
  const { build } = require('@kumologica/builder');
15
-
15
+ const { CloudFormationClient } = require("@aws-sdk/client-cloudformation");
16
+ //const { IoTJobsDataPlane } = require('aws-sdk');
16
17
  /**
17
18
  * sample events:
18
19
  * https://docs.aws.amazon.com/lambda/latest/dg/lambda-services.html
@@ -21,32 +22,29 @@ class AWSDeployer {
21
22
  constructor(terminal) {
22
23
  this.term = terminal;
23
24
  this.awsProfile = new AWSProfile();
24
-
25
- AWS.config.apiVersions = {
26
- cloudformation: '2010-05-15',
27
- };
28
25
  }
29
26
 
30
27
  async initAWS(profile) {
31
- AWS.config.credentials = new AWS.SharedIniFileCredentials({profile: profile});
32
- AWS.config.profile = profile; // this is not AWS property
28
+ const { fromIni } = require("@aws-sdk/credential-providers");
29
+ const config = {
30
+ credentials: fromIni({profile: profile})
31
+ };
33
32
 
34
- const region = await this.awsProfile.getRegion(profile);
35
- AWS.config.update({region: region});
36
-
33
+ this.region = await this.awsProfile.getRegion(profile);
34
+
37
35
  this.cw = false;
38
36
 
39
- this.apiGateway = new CAAWSApiGateway(this.log.bind(this));
40
- this.dynamoDb = new CADynamoDb(this.log.bind(this));
41
- this.cf = new AWS.CloudFormation();
42
- this.s3 = new CAS3(this.log.bind(this));
43
- this.sns = new CASNS(this.log.bind(this));
44
- this.sqs = new CASQS(this.log.bind(this));
45
- this.lambdaApi = new AWS.Lambda();
46
- this.cwLogs = new CAAWSCloudWatch(this.logCloud.bind(this));
47
- this.cwevents = new AWS.CloudWatchEvents();
48
- this.cognito = new AWS.CognitoIdentityServiceProvider();
49
- this.events = new CAEvents(this.log.bind(this));
37
+ this.apiGateway = new KLAWSApiGateway(config, this.log.bind(this));
38
+ this.iam = new KLIAM(config, this.log.bind(this));
39
+ this.dynamoDb = new CADynamoDb(config, this.log.bind(this));
40
+
41
+ this.cf = new CloudFormationClient(config);
42
+
43
+ this.s3 = new CAS3(config, this.log.bind(this));
44
+ this.sns = new CASNS(config, this.log.bind(this));
45
+ this.sqs = new CASQS(config, this.log.bind(this));
46
+ this.cwLogs = new CAAWSCloudWatch(config, this.logCloud.bind(this));
47
+ this.events = new CAEvents(config, this.log.bind(this));
50
48
  }
51
49
 
52
50
  chalk(c, t) {
@@ -158,10 +156,10 @@ class AWSDeployer {
158
156
  this.log(` ${this.chalk('#F5DEB3', 'flow:')} ${this.chalk('whiteBright', projectInfo.projectFlowName)}`, false);
159
157
  this.log(` ${this.chalk('#F5DEB3', 'working directory:')} ${this.chalk('whiteBright', projectInfo.projectDir + "/deploy")}`, false);
160
158
  this.log(` ${this.chalk('#F5DEB3', 'lambda parameters:')} ${this.chalk('whiteBright', JSON.stringify(params))}`, false);
161
- this.log(` ${this.chalk('#F5DEB3', 'AWS profile:')} ${this.chalk('whiteBright', AWS.config.profile)}`, false);
159
+ this.log(` ${this.chalk('#F5DEB3', 'AWS profile:')} ${this.chalk('whiteBright', profile)}`, false);
162
160
 
163
161
  await this.initAWS(profile);
164
- this.log(` ${this.chalk('#F5DEB3', 'AWS region:')} ${this.chalk('whiteBright', AWS.config.region)}`, false);
162
+ this.log(` ${this.chalk('#F5DEB3', 'AWS region:')} ${this.chalk('whiteBright', this.region)}`, false);
165
163
  this.log('', false);
166
164
 
167
165
  const settings = this.prepare(
@@ -177,6 +175,7 @@ class AWSDeployer {
177
175
  settings.flowName
178
176
  );
179
177
 
178
+ // calls builder
180
179
  await this.buildLambda(settings, projectInfo);
181
180
 
182
181
  const nodes = this.loadJsonFile(
@@ -185,6 +184,7 @@ class AWSDeployer {
185
184
 
186
185
  flowListeners = this.processFlow(nodes);
187
186
 
187
+ // calls exp cf
188
188
  const stackDetails = await this.executeStack(
189
189
  settings,
190
190
  params,
@@ -263,7 +263,7 @@ if (s.api && s.api.length > 0) {
263
263
  apiId = output.RestApiId || "unknown api gateway";
264
264
  }
265
265
 
266
- let url = `https://${apiId}.execute-api.${AWS.config.region}.amazonaws.com/${stage}`;
266
+ let url = `https://${apiId}.execute-api.${this.region}.amazonaws.com/${stage}`;
267
267
  s.api.forEach(a => this.log(` ${(' ' + a.verb.toUpperCase()).slice(-6)} ${url}${a.url}`), this);
268
268
  this.log('');
269
269
  }
@@ -356,17 +356,6 @@ if (s.cwevents && s.cwevents.length > 0) {
356
356
  // api
357
357
  const apis = listener.filter(i => i.eventSource == 'api' && i.provider == 'aws')
358
358
  .map(a => {return {url: a.apiUrl, verb: a.apiMethod}});
359
-
360
- // validate if aws nodes got explicit credentials only
361
- /*const awsNodes = flow.filter(i => ['Rekognition', 'S3', 'SQS', 'Cloudwatch', 'Dynamo DB', 'SNS', 'SES', 'SSM'].includes(i.type));
362
- if (awsNodes && awsNodes.length > 0) {
363
- awsNodes.forEach(n => {
364
- if (!n.securitytype || n.securitytype != 'Credentials') {
365
- throw new Error (`AWS Node ${n.name} must have explicit credentials set. Open this node and choose Credentials option.`);
366
- }
367
- });
368
- }*/
369
-
370
359
  const dynamodb = listener.filter(i => i.eventSource == 'dynamodb')
371
360
  .map(a => {return {stream: a.stream, startingPosition: a.startingPosition}});
372
361
  const s3 = listener.filter(i => i.eventSource == 's3')
@@ -510,14 +499,11 @@ if (s.cwevents && s.cwevents.length > 0) {
510
499
 
511
500
  try {
512
501
  this.log('Generating cloud formation script');
513
- this.log(
514
- ` ${this.chalk('#F5DEB3', 'AWS profile:')} ${this.chalk('whiteBright', AWS.config.profile)}`,
515
- false
516
- );
502
+ this.log(` ${this.chalk('#F5DEB3', 'AWS profile:')} ${this.chalk('whiteBright', profile)}`, false);
517
503
 
518
504
  await this.initAWS(profile);
519
505
 
520
- this.log(` ${this.chalk('#F5DEB3', 'AWS region:')} ${this.chalk('whiteBright', AWS.config.region)}`, false);
506
+ this.log(` ${this.chalk('#F5DEB3', 'AWS region:')} ${this.chalk('whiteBright', this.region)}`, false);
521
507
 
522
508
  const settings = this.prepare(projectInfo.projectDir, projectInfo.projectFlowName, params.functionName, params.description);
523
509
 
@@ -527,7 +513,7 @@ if (s.cwevents && s.cwevents.length > 0) {
527
513
 
528
514
  // NEW
529
515
  const args = this.mapParams(params);
530
- args.region = AWS.config.region;
516
+ args.region = this.region;
531
517
  args["bucket-name"] = settings.deploymentBucketName;
532
518
  args["project-directory"] = projectInfo.projectDir;
533
519
  args["flow-file-name"] = projectInfo.projectFlowName;
@@ -535,6 +521,7 @@ if (s.cwevents && s.cwevents.length > 0) {
535
521
 
536
522
  console.log(`args: ${JSON.stringify(args)}`);
537
523
  const scriptFileName = exp("cloudformation", "aws", args);
524
+
538
525
  this.log(`Cloudformation script has been created: ${scriptFileName}`);
539
526
  console.log(`Cloudformation script has been created: ${scriptFileName}`);
540
527
 
@@ -565,7 +552,7 @@ if (s.cwevents && s.cwevents.length > 0) {
565
552
  */
566
553
  async executeStack(settings, params, deploymentStartTimestamp, nodes, projectInfo) {
567
554
  this.log(`Uploading zip file to bucket...`);
568
- var body = fs.createReadStream(
555
+ const body = fs.createReadStream(
569
556
  path.join(settings.deployDir, settings.zipFileName)
570
557
  );
571
558
 
@@ -576,7 +563,7 @@ if (s.cwevents && s.cwevents.length > 0) {
576
563
  });
577
564
 
578
565
  const args = this.mapParams(params);
579
- args.region = AWS.config.region;
566
+ args.region = this.region;
580
567
  args["bucket-name"] = settings.deploymentBucketName;
581
568
  args["project-directory"] = projectInfo.projectDir;
582
569
  args["flow-file-name"] = projectInfo.projectFlowName;
@@ -597,33 +584,28 @@ if (s.cwevents && s.cwevents.length > 0) {
597
584
 
598
585
  let stack = {};
599
586
  try {
600
- stack = await this.cf.createStack(stackParams).promise();
587
+ const { CreateStackCommand, waitUntilStackCreateComplete, AlreadyExistsException } = require("@aws-sdk/client-cloudformation");
588
+ stack = await this.cf.send(new CreateStackCommand(stackParams));
589
+
601
590
  this.log('Waiting for stack create complete...');
602
- await this.cf
603
- .waitFor('stackCreateComplete', { StackName: stackParams.StackName })
604
- .promise();
605
-
606
- } catch (error) {
607
-
608
- if (error.code == 'AlreadyExistsException') {
609
- stack = await this.cf.updateStack(stackParams).promise();
610
- this.log('Waiting for stack update complete...');
611
-
612
- try {
613
- await this.cf
614
- .waitFor('stackUpdateComplete', {
615
- StackName: stackParams.StackName,
616
- })
617
- .promise();
618
- } catch (error) {
591
+ const client = this.cf;
592
+ await waitUntilStackCreateComplete(
593
+ { client, maxWaitTime: 600 },
594
+ { StackName: stackParams.StackName })
619
595
 
620
- await this.describeStackEvents(
621
- stackParams.StackName,
622
- deploymentStartTimestamp
623
- );
624
- throw Error(error);
625
- }
626
- } else {
596
+ } catch (AlreadyExistsException) {
597
+ const { UpdateStackCommand, waitUntilStackUpdateComplete } = require("@aws-sdk/client-cloudformation");
598
+ stack = await this.cf.send(new UpdateStackCommand(stackParams));
599
+
600
+ this.log('Waiting for stack update complete...');
601
+
602
+ try {
603
+ await waitUntilStackUpdateComplete(
604
+ { client, maxWaitTime: 600 },
605
+ { StackName: stackParams.StackName })
606
+
607
+ } catch (error) {
608
+
627
609
  await this.describeStackEvents(
628
610
  stackParams.StackName,
629
611
  deploymentStartTimestamp
@@ -636,7 +618,8 @@ if (s.cwevents && s.cwevents.length > 0) {
636
618
  }
637
619
 
638
620
  async describeStack(stackName) {
639
- return this.cf.describeStacks({ StackName: stackName }).promise();
621
+ const { DescribeStacksCommand } = require("@aws-sdk/client-cloudformation");
622
+ return this.cf.send(new DescribeStacksCommand({ StackName: stackName }));
640
623
  }
641
624
 
642
625
  /*
@@ -647,9 +630,9 @@ if (s.cwevents && s.cwevents.length > 0) {
647
630
  let events;
648
631
 
649
632
  try {
650
- events = await this.cf
651
- .describeStackEvents({ StackName: stackName })
652
- .promise();
633
+ const { DescribeStackEventsCommand } = require("@aws-sdk/client-cloudformation");
634
+
635
+ events = await this.cf.send(new DescribeStackEventsCommand({ StackName: stackName }));
653
636
  } catch (error) {
654
637
  //this.log(`de: ${error}`);
655
638
  // may throw stack does not exists for the first ever call
@@ -659,9 +642,11 @@ if (s.cwevents && s.cwevents.length > 0) {
659
642
  return;
660
643
  }
661
644
 
662
- var deploymentEvents = events.StackEvents.filter(
663
- (event) => event.Timestamp > deploymentStartTimestamp
664
- ).sort((a, b) => a.Timestamp - b.Timestamp);
645
+ var deploymentEvents =
646
+ events.StackEvents
647
+ .filter((event) => event.Timestamp > deploymentStartTimestamp)
648
+ .sort((a, b) => a.Timestamp - b.Timestamp);
649
+
665
650
  if (deploymentEvents == undefined || deploymentEvents.length == 0) {
666
651
  return;
667
652
  }
@@ -694,24 +679,26 @@ if (s.cwevents && s.cwevents.length > 0) {
694
679
  return JSON.parse(fs.readFileSync(flowFileName));
695
680
  }
696
681
 
697
- createFile(baseDir, fileName, content) {
698
- fs.outputFileSync(path.join(baseDir, fileName), content, 'utf-8');
699
- }
700
-
701
- async listServices(type, profile) {
682
+ async listServices(type, profile, id) {
702
683
  if (!profile) {
703
684
  throw new Error(
704
685
  `AWS profile has not been provided, unable to return list of ${type}. Select correct profile from list.`
705
686
  );
706
687
  }
707
688
 
708
- await this.initAWS(profile);
689
+ await this.initAWS(profile);
709
690
 
710
691
  let res = null;
711
692
  switch (type) {
712
693
  case 'api':
713
694
  res = await this.apiGateway.getApiGateways();
714
695
  break;
696
+ case 'api-resources':
697
+ res = await this.apiGateway.getResources(id);
698
+ break;
699
+ case 'api-stages':
700
+ res = await this.apiGateway.getStages(id);
701
+ break;
715
702
  case 's3':
716
703
  res = await this.s3.getBuckets();
717
704
  break;
@@ -724,9 +711,6 @@ if (s.cwevents && s.cwevents.length > 0) {
724
711
  case 'dynamodb':
725
712
  res = await this.dynamoDb.listStreams();
726
713
  break;
727
- case 'cwlogs':
728
- res = await this.cwLogs.listLogGroups();
729
- break;
730
714
  case 'alb':
731
715
  res = await this.elb.listElbs();
732
716
  break;
@@ -0,0 +1,40 @@
1
+ const jp = require('jsonpath');
2
+
3
+ class KLAWSApiGateway {
4
+
5
+ constructor(config, log) {
6
+ this.log = log;
7
+ this.triggerStage = "";
8
+
9
+ const { APIGatewayClient } = require("@aws-sdk/client-api-gateway");
10
+ this.apigateway = new APIGatewayClient(config);
11
+ }
12
+
13
+ async getResources(apiId) {
14
+ const { GetResourcesCommand } = require("@aws-sdk/client-api-gateway");
15
+ const res = this.apigateway.send(new GetResourcesCommand({ restApiId: apiId }));
16
+
17
+ return res.items.map(v => {
18
+ return {id: v.id, path: v.path, parentId: v.parentId}
19
+ });
20
+ }
21
+
22
+ async getStages(apiId) {
23
+ const { GetStagesCommand } = require("@aws-sdk/client-api-gateway");
24
+ const st = this.apigateway.send(new GetStagesCommand({ restApiId: apiId }));
25
+ return st.items.map(v => {
26
+ return {id: v.deploymentId, name: v.stageName}
27
+ });
28
+ }
29
+
30
+ async getApiGateways() {
31
+ const { GetRestApisCommand } = require("@aws-sdk/client-api-gateway");
32
+ const api = await this.apigateway.send(new GetRestApisCommand({}));
33
+
34
+ return api.items.map(v => {
35
+ return {id: v.id, name: v.name, arn: `arn-ccc`}
36
+ });
37
+ }
38
+ }
39
+
40
+ module.exports = KLAWSApiGateway;
@@ -1,14 +1,13 @@
1
- const AWS = require('aws-sdk');
2
-
3
1
  /*
4
2
  * AWS JS API:
5
3
  * https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/SNS.html
6
4
  */
7
5
  class KLIAM {
8
6
 
9
- constructor(log) {
7
+ constructor(config, log) {
10
8
  this.log = log;
11
- this.iam = new AWS.IAM();
9
+ const { IAMClient } = require("@aws-sdk/client-iam");
10
+ this.iam = new IAMClient(config);
12
11
  }
13
12
 
14
13
  /**
@@ -16,7 +15,8 @@ class KLIAM {
16
15
  */
17
16
  async listRoles() {
18
17
 
19
- const response = await this.iam.listRoles({}).promise();
18
+ const { ListRolesCommand } = require("@aws-sdk/client-iam");
19
+ const response = await this.iam.send(new ListRolesCommand({}));
20
20
 
21
21
  return response.Roles.map(function(r) {
22
22
  return {id: r.Arn, name: r.RoleName, arn: r.Arn};
@@ -1,5 +1,4 @@
1
1
  const path = require('path');
2
- const AWS = require('aws-sdk');
3
2
  const { exp } = require('@kumologica/builder');
4
3
  const AWSProfile = require('../aws/aws-profile');
5
4
  const { openFileOnEditor } = require('../utils/editor');
@@ -9,28 +8,12 @@ class GithubDeployer {
9
8
  this.term = terminal;
10
9
  this.awsProfile = new AWSProfile();
11
10
 
12
- AWS.config.apiVersions = {
13
- cloudformation: '2010-05-15',
14
- };
15
11
  }
16
12
 
17
13
  async initAWS(profile) {
18
- AWS.config.credentials = new AWS.SharedIniFileCredentials({profile: profile});
19
14
 
20
15
  const r = await this.awsProfile.getRegion(profile);
21
- let s3 = new AWS.S3();
22
16
  let bucketName = "CHANGE_IT_TO_REAL_BUCKET_NAME";
23
-
24
- // find bucket
25
- const buckets = await s3.listBuckets({}).promise();
26
-
27
- if (buckets && buckets.Buckets) {
28
- const bucket = buckets.Buckets.find(b => b.Name.startsWith('kumologica-designer-deploy'));
29
- if (bucket) {
30
- bucketName = bucket.Name;
31
- }
32
- }
33
-
34
17
  return {region: r, bucket: bucketName};
35
18
  }
36
19
 
@@ -1,6 +1,6 @@
1
1
  const fs = require('fs-extra');
2
2
  const path = require('path');
3
- const AWS = require('aws-sdk');
3
+ //const AWS = require('aws-sdk');
4
4
  const yaml = require('js-yaml');
5
5
  const AWSProfile = require('../aws/aws-profile');
6
6
  const CASQS = require('../aws/ca-sqs-api');
@@ -52,7 +52,6 @@ class CloudConfigStore {
52
52
  fsx.ensureDirSync(path.join(homedir, credsDir));
53
53
  fs.writeFileSync(this.cloudConfigFileFullPath, defaultContent);
54
54
  }
55
-
56
55
  }
57
56
 
58
57
  parseCloudConfigFile() {
@@ -81,6 +80,10 @@ class CloudConfigStore {
81
80
  return this.getAliases('kumohub') || [];
82
81
  }
83
82
 
83
+ getKumologicaDevAliases() {
84
+ return this.getAliases('kumologica.dev') || [];
85
+ }
86
+
84
87
  getAWSAliases() {
85
88
  return this.getAliases('aws') || [];
86
89
  }
@@ -89,13 +92,18 @@ class CloudConfigStore {
89
92
  return this.getAliases('azure') || [];
90
93
  }
91
94
 
92
- getKumohubAliasInfo(alias){
95
+ getKumohubAliasInfo(alias){
93
96
  return this.getAliasInfo('kumohub', alias);
94
97
  }
95
98
 
99
+ getKumologicaDevAliasInfo(alias){
100
+ return this.getAliasInfo('kumologica.dev', alias);
101
+ }
102
+
96
103
  getAWSAliasInfo(alias){
97
104
  return this.getAliasInfo('aws', alias);
98
105
  }
106
+
99
107
  getAzureAliasInfo(alias){
100
108
  return this.getAliasInfo('azure', alias);
101
109
  }
@@ -104,9 +112,34 @@ class CloudConfigStore {
104
112
  return this.cloudConfigFileFullPath;
105
113
  }
106
114
 
115
+ saveKumologicaDevAlias(tokens) {
116
+ let lines = this.readCloudConfigFile().split(/\n/).map(l=> l.trim());
117
+
118
+ // find [kumologica.dev]
119
+ const d = lines.indexOf("[kumologica.dev]");
120
+
121
+ if (d != -1) {
122
+ // if found then delete lines until next [ or the end
123
+ //ignore first [ it belongs to kumologica.dev
124
+ for (let i = d; i<lines.length; ) { // splice works like i++
125
+ if (lines[i].trim().startsWith("[") && i > d) {
126
+ break;
127
+ }
128
+ lines.splice(i, 1);
129
+ }
130
+ }
131
+
132
+ // add [kumologica.dev]
133
+ lines.push("[kumologica.dev]");
134
+ tokens.forEach(t => lines.push(t));
135
+
136
+ this.writeCloudConfigFile(lines.join('\n'));
137
+ }
138
+
107
139
  writeCloudConfigFile(content){
108
140
  fs.writeFileSync(this.cloudConfigFileFullPath, content);
109
141
  }
142
+
110
143
  readCloudConfigFile(){
111
144
  const data = fs.readFileSync(this.cloudConfigFileFullPath, "utf-8");
112
145
  const lines = data.split(/\r\n|\n/);