Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

domains records #161

Merged
merged 2 commits into from
Jul 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 13 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@
"license": "Apache-2.0",
"dependencies": {
"@apidevtools/json-schema-ref-parser": "9.1.0",
"@architect/inventory": "3.5.6",
"@architect/inventory": "3.5.7",
"@architect/parser": "6.0.2",
"@architect/sandbox": "5.7.1",
"@architect/sandbox": "5.7.4",
"@architect/utils": "3.1.9",
"@begin/api": "1.8.0",
"@begin/api": "1.9.1",
"@enhance/starter-project": "5.1.4",
"adm-zip": "0.5.10",
"cli-table3": "0.6.3",
"enquirer": "2.3.6",
"escodegen": "2.0.0",
"esprima": "4.0.1",
Expand All @@ -48,23 +49,23 @@
"devDependencies": {
"@architect/eslint-config": "^2.1.1",
"@architect/plugin-node-prune": "2.1.0-RC.0",
"@aws-sdk/client-apigatewaymanagementapi": "3.338.0",
"@aws-sdk/client-dynamodb": "3.338.0",
"@aws-sdk/client-s3": "3.338.0",
"@aws-sdk/client-sns": "3.338.0",
"@aws-sdk/client-sqs": "3.338.0",
"@aws-sdk/client-ssm": "3.338.0",
"@aws-sdk/lib-dynamodb": "3.338.0",
"@aws-sdk/client-apigatewaymanagementapi": "3.378.0",
"@aws-sdk/client-dynamodb": "3.378.0",
"@aws-sdk/client-s3": "3.378.0",
"@aws-sdk/client-sns": "3.378.0",
"@aws-sdk/client-sqs": "3.378.0",
"@aws-sdk/client-ssm": "3.378.0",
"@aws-sdk/lib-dynamodb": "3.378.0",
"aws-sdk": "2.1384.0",
"cross-env": "^7.0.3",
"eslint": "8.43.0",
"eslint": "8.45.0",
"fs-extra": "11.1.1",
"nyc": "^15.1.0",
"pkg": "5.8.1",
"proxyquire": "~2.1.3",
"string-argv": "~0.3.2",
"tap-arc": "~0.3.5",
"tape": "~5.6.3"
"tape": "~5.6.6"
},
"eslintConfig": {
"extends": "@architect/eslint-config",
Expand Down
32 changes: 32 additions & 0 deletions src/commands/domains/help.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,36 @@ const HELP = {
],
},
},
records: {
en: {
usage: [ 'domains records <parameters>', '[options]' ],
description: 'Manage DNS records for a domain',
contents: {
header: 'Records parameters',
items: [
{ name: '--domain', description: 'Domain name to list records for' },
{ name: '-a, --add', description: 'Add a record' },
{ name: '-r, --remove', description: 'Remove a record' },
{ name: '-t, --type', description: 'Record type; currently only TXT is supported' },
{ name: '-n --name', description: 'Record name, ie. example.com' },
{ name: '--ttl', description: 'Record TTL; defaults to 300' },
{ name: '--value', description: 'Record value' },
],
},
examples: [
{
name: 'List all records for a domain',
example: 'begin domains records --domain example.com',
},
{
name: 'Add a TXT record',
example: 'begin domains records --domain example.com --add --type TXT --name example.com --value foobarbaz',
},
{
name: 'Remove a TXT record',
example: 'begin domains records --domain example.com -r -t TXT -n example.com --value foobarbaz"',
},
],
},
}
}
18 changes: 8 additions & 10 deletions src/commands/domains/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
let names = { en: [ 'domains' ] }
let subcommands = [ 'list', 'add', 'remove', 'link', 'unlink' ]
let subcommands = [ 'list', 'add', 'remove', 'link', 'unlink', 'records' ]
let aliases = {
ls: 'list',
buy: 'add',
Expand All @@ -17,10 +17,11 @@ let help = require('./help').bind({})

async function action (params) {
let { args } = params
let { verbose } = args
let subcommand = args._[1] || defaultCommand
let { domain, env, verbose, _ } = args
let subcommand = _[1] || defaultCommand
let alias = Object.keys(aliases).includes(subcommand) && aliases[subcommand]
subcommand = alias || subcommand
env = env || args.e

if (subcommands.includes(subcommand)) {
let _inventory = require('@architect/inventory')
Expand All @@ -31,19 +32,16 @@ async function action (params) {
if (!config.access_token)
return Error('You must be logged in, please run: begin login')

params.inventory = await _inventory()

let inventory = await _inventory()
let appID
try {
appID = getAppID(params.inventory, args)
appID = getAppID(inventory, args)
}
catch (error) {
catch (e) {
appID = null
}
let env = args.env || args.e
let domain = args.domain

return action({ config, appID, env, domain, verbose, ...params })
return action({ config, appID, env, domain, verbose, inventory, ...params })
}
else {
let err = new Error('Please specify an domains subcommand')
Expand Down
85 changes: 85 additions & 0 deletions src/commands/domains/records.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
const visibleTypes = [ 'TXT', 'MX', 'ALIAS', 'NS', 'SPF' ]

async function action (params) {
let c = require('picocolors')
let client = require('@begin/api')
let { config, args, domain, verbose } = params
let { access_token: token, stagingAPI: _staging } = config
let { add, remove, type, name, value, ttl } = args
add = add || args.a
remove = remove || args.r
type = type || args.t
name = name || args.n
// value = value || args.v // -v is "verbose"

if (!domain)
return Error('Please specify a domain with --domain')

if (add || remove) {
if (!type || (typeof type === 'string' && type.length === 0))
type = 'TXT' // defaults to TXT
if (!name || (typeof name === 'string' && name.length === 0))
return Error('Please specify a record name with --name')
if (!value || (typeof value === 'string' && value.length === 0))
return Error('Please specify record value with --value')

ttl = Number(ttl) || 300
value = `"${value}"`
}

// @ts-ignore
let domains = await client.domains.list({ token, _staging })
let theDomain = domains.find(d => d.domain === domain)

if (!theDomain)
return Error([
`You do not subscribe to the domain "${domain}".`,
`To subscribe, run: begin domains check ${domain}`,
].join('\n'))

if (add) {
let result = await client.domains.records.upsert({
token,
// @ts-ignore
_staging,
domainID: theDomain.domainID,
changes: [ { type, name, value, ttl } ],
})

return `Added record ${c.bold(type)} ${c.cyan(name)} (${result.status})`
}
else if (remove) {
let result = await client.domains.records.delete({
token,
// @ts-ignore
_staging,
domainID: theDomain.domainID,
record: { type, name, value, ttl },
})

return `Removed record ${c.bold(type)} ${c.cyan(name)} (${result.status})`
}
else { // list records
let records = await client.domains.records.list({ token, _staging, domainID: theDomain.domainID })
let outputRecords = verbose ? records : records.filter(r => visibleTypes.includes(r.type))
outputRecords = outputRecords.sort((a, b) => a.type.localeCompare(b.type))

if (outputRecords.length === 0) {
return c.red(`No records found for ${c.underline(c.cyan(domain))}`)
}
else {
let Table = require('cli-table3')
let table = new Table({ head: [ 'Type', 'Name', 'TTL', 'Value' ] })
for (const r of outputRecords)
table.push([ c.bold(r.type), c.cyan(r.name), r.ttl, r.values?.join('\n') ])

return table.toString()
}
}
}

module.exports = {
name: 'records',
description: 'Manage DNS records for a domain',
action,
}