• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

silvermine / dynamodb-table-sync / 9822079146

06 Jul 2024 09:03PM UTC coverage: 0.0%. Remained the same
9822079146

Pull #26

github

web-flow
Merge 95d4595de into 80edaf9a1
Pull Request #26: feat: Add support for synchronizing to a local slave instance

0 of 132 branches covered (0.0%)

Branch coverage included in aggregate %.

0 of 7 new or added lines in 2 files covered. (0.0%)

1 existing line in 1 file now uncovered.

0 of 278 relevant lines covered (0.0%)

0.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/cli.js
1
#!/usr/bin/env node
2
'use strict';
3

4
var _ = require('underscore'),
×
5
    Q = require('q'),
×
6
    AWS = require('aws-sdk'),
×
7
    minimist = require('minimist'),
×
8
    Synchronizer = require('./Synchronizer'),
×
9
    startupPromise = Q.when(),
×
10
    argvOpts, argv, argsFailed, options;
11

12
argvOpts = {
×
13
   string: [
14
      'master',
15
      'slaves',
16
      'ignore-atts',
17
      'starting-key',
18
      'profile',
19
      'role-arn',
20
      'mfa-serial',
21
      'mfa-token',
22
      'slave-endpoint',
23
      'slave-profile',
24
      'slave-role-arn',
25
      'slave-mfa-serial',
26
      'slave-mfa-token',
27
   ],
28
   'boolean': [ 'write-missing', 'write-differing', 'scan-for-extra', 'delete-extra', 'verbose' ],
29
   'default': {
30
      'verbose': false,
31
      'write-missing': false,
32
      'write-differing': false,
33
      'scan-for-extra': false,
34
      'delete-extra': false,
35
   },
36
   alias: {
37
      master: 'm',
38
      slaves: [ 's', 'slave' ],
39
      verbose: 'v',
40
      'ignore-atts': [ 'ignore', 'ignore-att' ],
41
   },
42
};
43

44
argv = minimist(process.argv.slice(2), argvOpts);
×
45

46
function mapTableName(type, name) {
47
   var parts = name.split(':');
×
48

49
   if (parts.length !== 2) {
×
50
      console.log('Your table name must be supplied in two parts: "<region>:<table-name>"');
×
51
      console.log('This %s table does not meet that requirement:', type, name);
×
52
      argsFailed = true;
×
53
   }
54

55
   return { region: parts[0], name: parts[1] };
×
56
}
57

58
if (_.isEmpty(argv.master)) {
×
59
   console.log('Must supply a master table: --master <region>:<table>');
×
60
   argsFailed = true;
×
61
} else if (_.isArray(argv.master)) {
×
62
   console.log('Can only supply one master table. You supplied:', argv.master);
×
63
   argsFailed = true;
×
64
} else {
65
   argv.master = mapTableName('master', argv.master);
×
66
}
67

68
if (_.isEmpty(argv.slaves)) {
×
69
   console.log('Must supply one or more slave tables: --slave <region>:<table>');
×
70
   console.log('Or: --slave <region>:<table> --slave <region>:<table>');
×
71
   argsFailed = true;
×
72
} else if (!_.isArray(argv.slaves)) {
×
73
   argv.slaves = [ argv.slaves ];
×
74
}
75

76
if (_.isEmpty(argv['ignore-atts'])) {
×
77
   argv['ignore-atts'] = [];
×
78
} else if (!_.isArray(argv['ignore-atts'])) {
×
79
   argv['ignore-atts'] = [ argv['ignore-atts'] ];
×
80
}
81

82
argv.slaves = _.map(argv.slaves, mapTableName.bind(null, 'slave'));
×
83

84
if (_.isEmpty(argv['starting-key'])) {
×
85
   argv['starting-key'] = undefined;
×
86
} else {
87
   if (argv.parallel) {
×
88
      console.log('ERROR: --starting-key can not be used when using --parallel');
×
89
      console.log('because each segment would need its own starting key.');
×
90
      argsFailed = true;
×
91
   }
92

93
   argv['starting-key'] = JSON.parse(argv['starting-key']);
×
94
}
95

96
if (argsFailed) {
×
97
   process.exit(1); // eslint-disable-line no-process-exit
×
98
}
99

100
options = {
×
101
   verbose: argv.verbose,
102
   writeMissing: argv['write-missing'],
103
   writeDiffering: argv['write-differing'],
104
   deleteExtra: argv['delete-extra'],
105
   scanForExtra: argv['scan-for-extra'],
106
   ignoreAtts: argv['ignore-atts'],
107
   startingKey: argv['starting-key'],
108
};
109

110
if (_.isNumber(argv['scan-limit'])) {
×
111
   options.scanLimit = parseInt(argv['scan-limit'], 10);
×
112
}
113

114
options.batchReadLimit = _.isNumber(argv['batch-read-limit']) ? parseInt(argv['batch-read-limit'], 10) : 50;
×
115

116
options.maxRetries = _.isNumber(argv['max-retries']) ? parseInt(argv['max-retries'], 10) : 10;
×
117

118
options.retryDelayBase = _.isNumber(argv['retry-delay-base']) ? parseInt(argv['retry-delay-base'], 10) : 50;
×
119

120
if (_.isNumber(argv.parallel)) {
×
121
   options.parallel = parseInt(argv.parallel, 10);
×
122
}
123

124
function setupRoleRelatedCredentials(argPrefix, msg, masterCreds) {
125
   var params = { RoleArn: argv[argPrefix + 'role-arn'] },
×
126
       creds = masterCreds;
×
127

128
   if (_.isEmpty(params.RoleArn)) {
×
129
      return creds;
×
130
   }
131

132
   if (_.isEmpty(argv[argPrefix + 'mfa-serial'])) {
×
133
      console.log('Assuming role %s %s', params.RoleArn, msg);
×
134
   } else {
135
      params.SerialNumber = argv[argPrefix + 'mfa-serial'];
×
136
      params.TokenCode = argv[argPrefix + 'mfa-token'];
×
137
      console.log('Assuming role %s with MFA %s (%s) %s', params.RoleArn, params.SerialNumber, params.TokenCode, msg);
×
138
   }
139

140
   creds = new AWS.TemporaryCredentials(params, masterCreds);
×
141

142
   // See jthomerson comments on https://github.com/aws/aws-sdk-js/issues/1064
143
   // And subsequently: https://github.com/aws/aws-sdk-js/issues/1664
144
   startupPromise = startupPromise.then(function() {
×
145
      return Q.ninvoke(creds, 'refresh');
×
146
   });
147

148
   return creds;
×
149
}
150

151
// Set up master table (SDK default) credentials
152
if (!_.isEmpty(argv.profile)) {
×
153
   console.log('Setting AWS credentials provider to use profile %s', argv.profile);
×
154
   AWS.config.credentials = new AWS.SharedIniFileCredentials({ profile: argv.profile });
×
155
}
156

157
AWS.config.credentials = setupRoleRelatedCredentials('', 'for master', AWS.config.credentials);
×
158

159
if (!_.isEmpty(argv['slave-profile'])) {
×
160
   console.log('Setting AWS credentials provider to use profile %s for slaves', argv['slave-profile']);
×
161
   options.slaveCredentials = new AWS.SharedIniFileCredentials({ profile: argv['slave-profile'] });
×
162
}
163

NEW
164
if (!_.isEmpty(argv['slave-endpoint'])) {
×
NEW
165
   options.slaveEndpoint = argv['slave-endpoint'];
×
166
}
167

UNCOV
168
options.slaveCredentials = setupRoleRelatedCredentials('slave-', 'for slaves', options.slaveCredentials || AWS.config.credentials);
×
169

170
startupPromise
×
171
   .then(function() {
172
      return new Synchronizer(argv.master, argv.slaves, options).run();
×
173
   })
174
   .done();
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc