terraform-enterprise-cli 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/bin/tfe ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- mode: ruby -*-
3
+
4
+ require File.expand_path('../../lib/terraform-enterprise-command-line', __FILE__)
@@ -0,0 +1,79 @@
1
+ require 'thor'
2
+
3
+ require_relative 'terraform_enterprise/command_line/command'
4
+ require_relative 'terraform_enterprise/command_line/commands/configuration_versions'
5
+ require_relative 'terraform_enterprise/command_line/commands/oauth_tokens'
6
+ require_relative 'terraform_enterprise/command_line/commands/organizations'
7
+ require_relative 'terraform_enterprise/command_line/commands/policies'
8
+ require_relative 'terraform_enterprise/command_line/commands/policy_checks'
9
+ require_relative 'terraform_enterprise/command_line/commands/runs'
10
+ require_relative 'terraform_enterprise/command_line/commands/teams'
11
+ require_relative 'terraform_enterprise/command_line/commands/variables'
12
+ require_relative 'terraform_enterprise/command_line/commands/workspaces'
13
+
14
+ module TerraformEnterprise
15
+ # Terraform Enterprise Command Line class
16
+ class MainCommand < TerraformEnterprise::CommandLine::Command
17
+ include TerraformEnterprise::CommandLine
18
+
19
+ desc 'organizations <subcommand>', 'Manage organizations'
20
+ subcommand 'organizations', OrganizationsCommand
21
+
22
+ desc 'workspaces <subcommand>', 'Manage workspaces'
23
+ subcommand 'workspaces', WorkspacesCommand
24
+
25
+ desc 'oauth-tokens <subcommand>', 'Manage OAuth tokens'
26
+ subcommand 'oauth_tokens', OAuthTokensCommand
27
+
28
+ desc 'teams <subcommand>', 'Manage teams'
29
+ subcommand 'teams', TeamsCommand
30
+
31
+ desc 'variables <subcommand>', 'Manage variables'
32
+ subcommand 'variables', VariablesCommand
33
+
34
+ desc 'configuration-versions <subcommand>', 'Manage configuration versions'
35
+ subcommand 'configuration_versions', ConfigurationVersionsCommand
36
+
37
+ desc 'policies <subcommand>', 'Manage policies'
38
+ subcommand 'policies', PoliciesCommand
39
+
40
+ desc 'policy-checks <subcommand>', 'Manage policy checks'
41
+ subcommand 'policy_checks', PolicyChecksCommand
42
+
43
+ desc 'runs <subcommand>', 'Manage runs'
44
+ subcommand 'runs', RunsCommand
45
+
46
+ desc 'push <organization>/<workspace>', STRINGS[:push][:commands][:push]
47
+ option :path, required: true, default: '.', desc: STRINGS[:push][:attributes][:path]
48
+ def push(name)
49
+ name_parts = name.split('/')
50
+ organization_name = name_parts[0]
51
+ workspace_name = name_parts[1]
52
+ workspace_params = {
53
+ organization: organization_name,
54
+ workspace: workspace_name
55
+ }
56
+
57
+ begin
58
+ content = tarball(options[:path])
59
+ rescue
60
+ error! "could not open that file or directory"
61
+ end
62
+
63
+ # Look up the workspace ID
64
+ workspace_response = client.workspaces.get(workspace_params)
65
+ workspace_id = workspace_response&.resource&.id
66
+ error! "workspace '#{organization_name}/#{workspace_name}' was not found!" unless workspace_id
67
+
68
+ # Create a configuration version and get upload-url
69
+ configuration_version_response = client.configuration_versions.create(workspace: workspace_id)
70
+ upload_url = (configuration_version_response&.resource&.attributes || {})['upload-url']
71
+ error! "failed creationg configuration version with workspace id `#{workspace_id}`" unless upload_url
72
+
73
+ upload_params = { content: content, url: upload_url }
74
+ render client.configuration_versions.upload(upload_params)
75
+ end
76
+ end
77
+ end
78
+
79
+ TerraformEnterprise::MainCommand.start(ARGV)
@@ -0,0 +1,61 @@
1
+ require 'json'
2
+ require 'terraform-enterprise-client'
3
+
4
+ require_relative 'formatter'
5
+ require_relative 'strings'
6
+ require_relative 'util'
7
+
8
+ module TerraformEnterprise
9
+ module CommandLine
10
+ # Base class for all commands
11
+ class Command < Thor
12
+ include TerraformEnterprise::CommandLine
13
+ include TerraformEnterprise::CommandLine::Util::Tar
14
+
15
+ CMD_STR = STRINGS[:options]
16
+
17
+ class_option :host, type: :string, desc: CMD_STR[:host]
18
+ class_option :token, type: :string, desc: CMD_STR[:token]
19
+ class_option :color, type: :boolean, default: true, desc: CMD_STR[:color]
20
+ class_option :except, type: :array, desc: CMD_STR[:except]
21
+ class_option :only, type: :array, desc: CMD_STR[:only]
22
+ class_option :all, type: :boolean, default: false, desc: CMD_STR[:all]
23
+ class_option :value, type: :boolean, default: false, desc: CMD_STR[:value]
24
+ class_option :debug, type: :boolean, default: false, desc: CMD_STR[:debug]
25
+
26
+ no_commands do
27
+ def render(obj, default_options = {})
28
+ normalized_options = symbolize_keys(options.to_h)
29
+ calculated_options =
30
+ if options[:all]
31
+ normalized_options
32
+ else
33
+ symbolize_keys(default_options).merge(normalized_options)
34
+ end
35
+ formatter = Formatter.new
36
+ formatter.render obj, calculated_options
37
+ end
38
+
39
+ def error!(message)
40
+ formatter = Formatter.new
41
+ formatter.error(message)
42
+ exit(false)
43
+ end
44
+
45
+ def client
46
+ settings = {}
47
+ settings[:token] = options[:token] || ENV['TFE_TOKEN']
48
+ settings[:host] = options[:host] if options[:host]
49
+ settings[:debug] = options[:debug] if options[:debug]
50
+ TerraformEnterprise::API::Client.new(settings)
51
+ end
52
+
53
+ private
54
+
55
+ def symbolize_keys(hash)
56
+ JSON.parse(JSON[hash], symbolize_names: true)
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,37 @@
1
+ require 'terraform_enterprise/command_line/command'
2
+
3
+ module TerraformEnterprise
4
+ module CommandLine
5
+ # Configuration Version Commoand
6
+ class ConfigurationVersionsCommand < TerraformEnterprise::CommandLine::Command
7
+ ATTR_STR = STRINGS[:configuration_versions][:attributes]
8
+ CMD_STR = STRINGS[:configuration_versions][:commands]
9
+
10
+ desc 'list', CMD_STR[:list]
11
+ option :table, type: :boolean, default: true, desc: STRINGS[:options][:table]
12
+ option :workspace_id, required: true, type: :string, desc: ATTR_STR[:workspace_id]
13
+ def list
14
+ render client.configuration_versions.list(workspace: options[:workspace_id])
15
+ end
16
+
17
+ desc 'create', CMD_STR[:list]
18
+ option :workspace_id, required: true, type: :string, desc: STRINGS[:options][:workspace_id]
19
+ def create
20
+ render client.configuration_versions.create(workspace: options[:workspace_id])
21
+ end
22
+
23
+ desc 'get <id>', CMD_STR[:get]
24
+ def get(id)
25
+ render client.configuration_versions.get(id: id)
26
+ end
27
+
28
+ desc 'upload <path> <upload-url>', CMD_STR[:upload]
29
+ def upload(path, url)
30
+ content = tarball(path)
31
+ params = { content: content, url: url }
32
+
33
+ render client.configuration_versions.upload(params)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,15 @@
1
+ require 'terraform_enterprise/command_line/command'
2
+
3
+ module TerraformEnterprise
4
+ module CommandLine
5
+ class OAuthTokensCommand < TerraformEnterprise::CommandLine::Command
6
+ class_option :organization, required: true, type: :string, desc: STRINGS[:oauth_tokens][:attributes][:organization]
7
+
8
+ desc 'list', STRINGS[:oauth_tokens][:commands][:list]
9
+ option :table, type: :boolean, default: true, desc: STRINGS[:options][:table]
10
+ def list
11
+ render client.oauth_tokens.list(options)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,30 @@
1
+ require 'terraform_enterprise/command_line/command'
2
+
3
+ module TerraformEnterprise
4
+ module CommandLine
5
+ class OrganizationsCommand < TerraformEnterprise::CommandLine::Command
6
+ CMD_STR = STRINGS[:organizations][:commands]
7
+
8
+ desc 'list', CMD_STR[:list]
9
+ option :table, type: :boolean, default: true, desc: STRINGS[:options][:table]
10
+ def list
11
+ render client.organizations.list, only: [:id, :name, 'created-at', :email]
12
+ end
13
+
14
+ desc 'create <name> <email>', CMD_STR[:create]
15
+ def create(name, email)
16
+ render client.organizations.create(name: name, email: email)
17
+ end
18
+
19
+ desc 'get <name>', CMD_STR[:get]
20
+ def get(name)
21
+ render client.organizations.get(name:name)
22
+ end
23
+
24
+ desc 'delete <name>', CMD_STR[:delete]
25
+ def delete(name)
26
+ render client.organizations.delete(name:name)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,72 @@
1
+ require 'terraform_enterprise/command_line/command'
2
+
3
+ module TerraformEnterprise
4
+ module CommandLine
5
+ class PoliciesCommand < TerraformEnterprise::CommandLine::Command
6
+ ATTR_STR = STRINGS[:policies][:attributes]
7
+ CMD_STR = STRINGS[:policies][:commands]
8
+
9
+ desc 'list', CMD_STR[:list]
10
+ option :table, type: :boolean, default: true, desc: STRINGS[:options][:table]
11
+ option :organization, required: true, type: :string, desc: ATTR_STR[:organization]
12
+ def list
13
+ render client.policies.list(organization: options[:organization])
14
+ end
15
+
16
+ desc 'create <name>', CMD_STR[:create]
17
+ option :organization, required: true, type: :string, desc: ATTR_STR[:organization]
18
+ option :mode, type: :string, required: true, enum: ['soft-mandatory', 'hard-mandatory', 'advisory']
19
+ def create(name)
20
+ params = {
21
+ name: name,
22
+ organization: options[:organization],
23
+ enforce: [
24
+ {
25
+ path: "#{name}.sentinel",
26
+ mode: options[:mode]
27
+ }
28
+ ]
29
+ }
30
+ render client.policies.create(params)
31
+ end
32
+
33
+ desc 'update <id>', CMD_STR[:create]
34
+ option :mode, type: :string, required: true, enum: ['soft-mandatory', 'hard-mandatory', 'advisory'], desc: ATTR_STR[:mode]
35
+ def update(id)
36
+ name = ''
37
+ params = {
38
+ id: id,
39
+ name: name,
40
+ enforce: [
41
+ {
42
+ path: 'default.sentinel',
43
+ mode: options[:mode]
44
+ }
45
+ ]
46
+ }
47
+
48
+ render client.policies.update(params)
49
+ end
50
+
51
+ desc 'get <id>', CMD_STR[:get]
52
+ def get(id)
53
+ render client.policies.get(id:id)
54
+ end
55
+
56
+ desc 'delete <id>', CMD_STR[:delete]
57
+ def delete(id)
58
+ render client.policies.delete(id: id)
59
+ end
60
+
61
+ desc 'upload <path> <policy-id>', CMD_STR[:upload]
62
+ def upload(path, policy_id)
63
+ full_path = File.expand_path(path)
64
+ content = File.read(full_path)
65
+
66
+ params = { content: content, id: policy_id }
67
+
68
+ render client.policies.upload(params)
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,29 @@
1
+ require 'terraform_enterprise/command_line/command'
2
+ require 'terraform_enterprise/command_line/util'
3
+
4
+ module TerraformEnterprise
5
+ module CommandLine
6
+ # Configuration Version Commoand
7
+ class PolicyChecksCommand < TerraformEnterprise::CommandLine::Command
8
+ include TerraformEnterprise::CommandLine::Util::Tar
9
+
10
+ ATTR_STR = STRINGS[:policy_checks][:attributes]
11
+ CMD_STR = STRINGS[:policy_checks][:commands]
12
+
13
+ desc 'list', CMD_STR[:list]
14
+ option :table, type: :boolean, default: false, desc: STRINGS[:options][:table]
15
+ option :run_id, required: true, type: :string, desc: ATTR_STR[:run_id]
16
+ def list
17
+ render client.policy_checks.list(run_id: options[:run_id])
18
+ end
19
+
20
+ desc 'override <policy-check-id>', CMD_STR[:override]
21
+ option :comment, type: :string, desc: ATTR_STR[:comment]
22
+ def override(id)
23
+ params = { id: id, action: :override }
24
+ params[:comment] = options[:comment] if options[:comment]
25
+ render client.policy_checks.action(params)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,88 @@
1
+ require 'terraform_enterprise/command_line/command'
2
+
3
+ module TerraformEnterprise
4
+ module CommandLine
5
+ class RunsCommand < TerraformEnterprise::CommandLine::Command
6
+ ATTR_STR = STRINGS[:runs][:attributes]
7
+ CMD_STR = STRINGS[:runs][:commands]
8
+
9
+ desc 'list', CMD_STR[:list]
10
+ option :table, type: :boolean, default: true, desc: STRINGS[:options][:table]
11
+ option :workspace_id, required: true, type: :string, desc: ATTR_STR[:workspace_id]
12
+ def list
13
+ render client.runs.list(id: options[:workspace_id]), except: [:permissions]
14
+ end
15
+
16
+ desc 'create', CMD_STR[:create]
17
+ option :workspace_id, required: true, type: :string, desc: ATTR_STR[:workspace_id]
18
+ option :configuration_version_id, type: :string, desc: ATTR_STR[:configuration_version_id]
19
+ option :destroy, type: :boolean, default: false, desc: ATTR_STR[:destroy]
20
+ def create
21
+ render client.runs.create(options), except: [:permissions]
22
+ end
23
+
24
+ desc 'get <id>', CMD_STR[:get]
25
+ def get(id)
26
+ render client.runs.get(id: id), except: [:permissions]
27
+ end
28
+
29
+ desc 'apply <id>', CMD_STR[:apply]
30
+ option :comment, type: :string, desc: ATTR_STR[:comment]
31
+ def apply(id)
32
+ params = { id: id, action: :apply }
33
+ params[:comment] = options[:comment] if options[:comment]
34
+ render client.runs.action(params)
35
+ end
36
+
37
+ desc 'discard <id>', CMD_STR[:discard]
38
+ option :comment, type: :string, desc: ATTR_STR[:comment]
39
+ def discard(id)
40
+ params = { id: id, action: :discard }
41
+ params[:comment] = options[:comment] if options[:comment]
42
+ render client.runs.action(params)
43
+ end
44
+
45
+ desc 'logs <id>', 'Logs'
46
+ option :event, type: :string, required: true, desc: ATTR_STR[:event], enum:['plan', 'apply']
47
+ option :follow, type: :boolean, default: false, desc: ATTR_STR[:follow]
48
+ def logs(id)
49
+ following = options[:follow]
50
+ finished = false
51
+ exit_requested = false
52
+ finished_states = %w[errored canceled finished]
53
+
54
+ # Listens for "control-c" to exit
55
+ Kernel.trap('INT') { exit_requested = true }
56
+
57
+ loop do
58
+ event = get_event_resource(id, options[:event])
59
+ url = event.attributes['log-read-url']
60
+ finished = finished_states.include?(event.attributes['status'].to_s)
61
+ logs = RestClient.get(url).body
62
+
63
+ # errase screen and go to (0,0)
64
+ print "\033[2J" if following
65
+ print logs
66
+
67
+ break if !following || exit_requested || finished
68
+
69
+ sleep 2
70
+ end
71
+ end
72
+
73
+ private
74
+
75
+ def get_event_resource(id, event)
76
+ event_type = event == 'plan' ? 'plans' : 'applies'
77
+ error_message = "#{options[:event].to_s.capitalize} not started yet"
78
+ run_response = client.runs.get(id: id, include: [event.to_sym])
79
+ render run_response unless run_response.success?
80
+ event_resource = run_response.resource.included.find do |er|
81
+ er.type.to_s == event_type
82
+ end
83
+ error! error_message unless event_resource
84
+ event_resource
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,33 @@
1
+ require 'terraform_enterprise/command_line/command'
2
+
3
+ module TerraformEnterprise
4
+ module CommandLine
5
+ class TeamsCommand < TerraformEnterprise::CommandLine::Command
6
+ ATTR_STR = STRINGS[:teams][:attributes]
7
+ CMD_STR = STRINGS[:teams][:commands]
8
+
9
+ desc 'list', CMD_STR[:list]
10
+ option :table, type: :boolean, default: true, desc: STRINGS[:options][:table]
11
+ option :organization, required: true, type: :string, desc: ATTR_STR[:organization]
12
+ def list
13
+ render client.teams.list(organization: options[:organization]), except: [:permissions]
14
+ end
15
+
16
+ desc 'create <name>', CMD_STR[:create]
17
+ option :organization, required: true, type: :string, desc: ATTR_STR[:organization]
18
+ def create(name)
19
+ render client.teams.create(name: name, organization: options[:organization])
20
+ end
21
+
22
+ desc 'get <id>', CMD_STR[:get]
23
+ def get(id)
24
+ render client.teams.get(id:id), except: [:permissions]
25
+ end
26
+
27
+ desc 'delete <id>', CMD_STR[:delete]
28
+ def delete(id)
29
+ render client.teams.delete(id: id), except: [:permissions]
30
+ end
31
+ end
32
+ end
33
+ end