lita-digitalocean 0.0.1 → 1.0.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.
@@ -0,0 +1,23 @@
1
+ module Lita
2
+ module Handlers
3
+ class Digitalocean < Handler
4
+ class Region < Base
5
+ do_route /^do\s+regions?\s+list$/i, :list, {
6
+ t("help.regions.list_key") => t("help.regions.list_value")
7
+ }
8
+
9
+ def list(response)
10
+ do_response = do_call(response) do |client|
11
+ client.regions.list
12
+ end or return
13
+
14
+ messages = do_response[:regions].map { |region| t("regions.details", region) }
15
+
16
+ response.reply(*messages)
17
+ end
18
+ end
19
+
20
+ Lita.register_handler(Region)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ module Lita
2
+ module Handlers
3
+ class Digitalocean < Handler
4
+ class Size < Base
5
+ do_route /^do\s+sizes\s+list$/, :list, {
6
+ t("help.sizes.list_key") => t("help.sizes.list_value")
7
+ }
8
+
9
+ def list(response)
10
+ do_response = do_call(response) do |client|
11
+ client.sizes.list
12
+ end or return
13
+
14
+ messages = do_response[:sizes].map { |size| t("sizes.details", size) }
15
+
16
+ response.reply(*messages)
17
+ end
18
+ end
19
+
20
+ Lita.register_handler(Size)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,94 @@
1
+ module Lita
2
+ module Handlers
3
+ class Digitalocean < Handler
4
+ class SSHKey < Base
5
+ do_route /^do\s+ssh\s+keys?\s+add\s+.+$/i, :add, {
6
+ t("help.ssh_keys.add_key") => t("help.ssh_keys.add_value")
7
+ }
8
+
9
+ do_route /^do\s+ssh\s+keys?\s+delete\s+(\d+)$/i, :delete, {
10
+ t("help.ssh_keys.delete_key") => t("help.ssh_keys.delete_value")
11
+ }
12
+
13
+ do_route /^do\s+ssh\s+keys?\s+edit\s+(\d+)\s+.+$/i, :edit, {
14
+ t("help.ssh_keys.edit_key") => t("help.ssh_keys.edit_value")
15
+ }, { name: {}, public_key: {} }
16
+
17
+ do_route /^do\s+ssh\s+keys?\s+list$/i, :list, {
18
+ t("help.ssh_keys.list_key") => t("help.ssh_keys.list_value")
19
+ }
20
+
21
+ do_route /^do\s+ssh\s+keys?\s+show\s+(\d+)$/i, :show, {
22
+ t("help.ssh_keys.show_key") => t("help.ssh_keys.show_value"),
23
+ }
24
+
25
+ def add(response)
26
+ name, public_key = response.args[3..4]
27
+
28
+ unless name && public_key
29
+ return response.reply("#{t('format')}: #{t('help.ssh_keys.add_key')}")
30
+ end
31
+
32
+ do_response = do_call(response) do |client|
33
+ client.ssh_keys.add(name: name, ssh_pub_key: public_key)
34
+ end or return
35
+
36
+ response.reply(t("ssh_keys.add.created", do_response[:ssh_key]))
37
+ end
38
+
39
+ def delete(response)
40
+ key_id = response.matches[0][0]
41
+
42
+ do_call(response) do |client|
43
+ client.ssh_keys.delete(key_id)
44
+ end or return
45
+
46
+ response.reply(t("ssh_keys.delete.deleted", key_id: key_id))
47
+ end
48
+
49
+ def edit(response)
50
+ kwargs = {}
51
+
52
+ if (name = response.extensions[:kwargs][:name])
53
+ kwargs[:name] = name
54
+ end
55
+
56
+ if (public_key = response.extensions[:kwargs][:public_key])
57
+ kwargs[:ssh_pub_key] = public_key
58
+ end
59
+
60
+ do_response = do_call(response) do |client|
61
+ client.ssh_keys.edit(response.matches[0][0], kwargs)
62
+ end or return
63
+
64
+ response.reply(t("ssh_keys.edit.updated", do_response[:ssh_key]))
65
+ end
66
+
67
+ def list(response)
68
+ do_response = do_call(response) do |client|
69
+ client.ssh_keys.list
70
+ end or return
71
+
72
+ if do_response[:ssh_keys].empty?
73
+ response.reply(t("ssh_keys.list.empty"))
74
+ else
75
+ do_response[:ssh_keys].each do |key|
76
+ response.reply("#{key[:id]} (#{key[:name]})")
77
+ end
78
+ end
79
+ end
80
+
81
+ def show(response)
82
+ do_response = do_call(response) do |client|
83
+ client.ssh_keys.show(response.matches[0][0])
84
+ end or return
85
+
86
+ key = do_response[:ssh_key]
87
+ response.reply("#{key[:id]} (#{key[:name]}): #{key[:ssh_pub_key]}")
88
+ end
89
+ end
90
+
91
+ Lita.register_handler(SSHKey)
92
+ end
93
+ end
94
+ end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "lita-digitalocean"
3
- spec.version = "0.0.1"
3
+ spec.version = "1.0.0"
4
4
  spec.authors = ["Jimmy Cuadra"]
5
5
  spec.email = ["jimmy@jimmycuadra.com"]
6
6
  spec.description = %q{A Lita handler for managing DigitalOcean services.}
@@ -14,8 +14,9 @@ Gem::Specification.new do |spec|
14
14
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
15
15
  spec.require_paths = ["lib"]
16
16
 
17
- spec.add_runtime_dependency "lita", ">= 3.1"
18
- spec.add_runtime_dependency "digital_ocean", ">= 1.3.0"
17
+ spec.add_runtime_dependency "lita", ">= 3.2"
18
+ spec.add_runtime_dependency "lita-keyword-arguments"
19
+ spec.add_runtime_dependency "digital_ocean", ">= 1.5.0"
19
20
 
20
21
  spec.add_development_dependency "bundler", "~> 1.3"
21
22
  spec.add_development_dependency "rake"
data/locales/en.yml CHANGED
@@ -5,26 +5,163 @@ en:
5
5
  credentials_missing: >-
6
6
  client_id and api_key must be set in Lita's configuration to
7
7
  use the DigitalOcean commands.
8
+ domains:
9
+ create:
10
+ created: "Created new DNS record set for %{name}."
11
+ delete:
12
+ deleted: "Deleted DNS record set."
13
+ list:
14
+ detail: "ID: %{id}, Name: %{name}"
15
+ show:
16
+ details: >-
17
+ ID: %{id}, Name: %{name}, TTL: %{ttl}, Live Zone File: %{live_zone_file},
18
+ Error: %{error}, Zone File With Error: %{zone_file_with_error}
19
+ domain_records:
20
+ create:
21
+ created: "Created new DNS record: %{id}"
22
+ delete:
23
+ deleted: "Deleted DNS record."
24
+ edit:
25
+ updated: "Updated DNS record."
26
+ list:
27
+ detail: "ID: %{id}, Record Type: %{record_type}, Data: %{data}"
28
+ show:
29
+ details: >-
30
+ ID: %{id}, Record Type: %{record_type}, Data: %{data}, Name: %{name},
31
+ Priority: %{priority}, Port: %{port}, Weight: %{weight}
32
+ droplets:
33
+ create:
34
+ created: "Created new droplet: %{id} (%{name})"
35
+ delete:
36
+ deleted: "Deleted droplet: %{id}"
37
+ list:
38
+ detail: "ID: %{id}, Name: %{name}, IP: %{ip_address}"
39
+ password_reset:
40
+ reset: "Password reset for droplet: %{id}"
41
+ power_cycle:
42
+ cycled: "Power cycled for droplet: %{id}"
43
+ power_off:
44
+ powered_off: "Powered off droplet: %{id}"
45
+ power_on:
46
+ powered_on: "Powered on droplet: %{id}"
47
+ reboot:
48
+ rebooted: "Rebooted droplet: %{id}"
49
+ rebuild:
50
+ rebuilt: "Rebuilt droplet: %{id}"
51
+ resize:
52
+ resized: "Resized droplet: %{id}"
53
+ restore:
54
+ restored: "Restored droplet: %{id}"
55
+ show:
56
+ details: >-
57
+ ID: %{id}, Image ID: %{image_id}, Name: %{name}, Region ID: %{region_id}, Size ID:
58
+ %{size_id}, Backups active: %{backups_active}, Backups: %{formatted_backups},
59
+ Snapshots: %{formatted_snapshots}, IP address: %{ip_address}, Private IP address:
60
+ %{private_ip_address}, Locked: %{locked}, Status: %{status}
61
+ shutdown:
62
+ shut_down: "Shut down droplet: %{id}"
63
+ snapshot:
64
+ snapshotted: "Snapshotted droplet: %{id}"
8
65
  error: "DigitalOcean API error: %{message}"
9
66
  format: Format
10
67
  help:
68
+ domains:
69
+ create_key: do domains create NAME IP
70
+ create_value: Creates a new DNS record set for domain NAME and IP.
71
+ delete_key: do domains delete DOMAIN_NAME_OR_ID
72
+ delete_value: Deletes the DNS record set for domain DOMAIN_NAME_OR_ID.
73
+ list_key: do domains list
74
+ list_value: Lists all DNS record sets.
75
+ show_key: do domains show DOMAIN_NAME_OR_ID
76
+ show_value: Shows the DNS record set details for domain DOMAIN_NAME_OR_ID.
77
+ domain_records:
78
+ create_key: >-
79
+ do domain records create DOMAIN_NAME_OR_ID TYPE DATA [--name NAME]
80
+ [--priority PRIORITY] [--port PORT] [--weight WEIGHT]
81
+ create_value: Creates a new DNS record for domain DOMAIN_NAME_OR_ID.
82
+ delete_key: do domain records delete DOMAIN_NAME_OR_ID DOMAIN_RECORD_ID
83
+ delete_value: Deletes the DNS record DOMAIN_RECORD_ID for domain DOMAIN_NAME_OR_ID.
84
+ edit_key: >-
85
+ do domain records edit DOMAIN_NAME_OR_ID DOMAIN_RECORD_ID TYPE DATA [--name NAME]
86
+ [--priority PRIORITY] [--port PORT] [--weight WEIGHT]
87
+ edit_value: Edits DNS record DOMAIN_RECORD_ID for domain DOMAIN_NAME_OR_ID.
88
+ list_key: do domain records list DOMAIN_NAME_OR_ID
89
+ list_value: Lists all DNS records for domain DOMAIN_NAME_OR_ID.
90
+ show_key: do domain records show DOMAIN_NAME_OR_ID DOMAIN_RECORD_ID
91
+ show_value: Shows DNS record DOMAIN_RECORD_ID for domain DOMAIN_NAME_OR_ID.
92
+ droplets:
93
+ create_key: >-
94
+ do droplets create HOSTNAME SIZE_ID_OR_SLUG IMAGE_ID_OR_SLUG REGION_ID_OR_SLUG
95
+ [--ssh-key-ids SSH_KEY_IDS] [--private-networking] [--backups-enabled]
96
+ create_value: >-
97
+ Creates a droplet. The optional ssh_key_ids field is a comma-separated list of
98
+ SSH key IDs.
99
+ delete_key: do droplets delete ID [--scrub]
100
+ delete_value: Deletes a droplet, optionally writing zeroes to the disk first.
101
+ list_key: do droplets list
102
+ list_value: Lists all droplets.
103
+ password_reset_key: do droplets password reset ID
104
+ password_reset_value: Resets the root password for a droplet.
105
+ power_cycle_key: do droplets power cycle ID
106
+ power_cycle_value: Powers off and then powers on a droplet.
107
+ power_off_key: do droplets power off ID
108
+ power_off_value: Powers off a droplet.
109
+ power_on_key: do droplets power on ID
110
+ power_on_value: Powers on a droplet.
111
+ reboot_key: do droplets reboot ID
112
+ reboot_value: Reboots a droplet.
113
+ resize_key: do droplets resize ID SIZE_ID_OR_SLUG
114
+ resize_value: Resizes a droplet.
115
+ restore_key: do droplets restore ID IMAGE_ID
116
+ restore_value: Restores a droplet from an image.
117
+ show_key: do droplets show ID
118
+ show_value: Shows the details of a droplet.
119
+ shutdown_key: do droplets shutdown ID
120
+ shutdown_value: Shuts down a droplet.
121
+ snapshot_key: do droplets snapshot ID [NAME]
122
+ snapshot_value: Takes a snapshot of a droplet, optionally naming the snapshot.
123
+ images:
124
+ delete_key: do images delete ID_OR_SLUG
125
+ delete_value: Deletes an image with the given ID or slug.
126
+ list_key: "do images list [FILTER]"
127
+ list_value: >-
128
+ Lists available images, optionally filtered by FILTER ("global" or "my_images").
129
+ show_key: do images show ID_OR_SLUG
130
+ show_value: Shows the details of an image with the given ID or slug.
131
+ regions:
132
+ list_key: do regions list
133
+ list_value: Lists all available regions.
11
134
  ssh_keys:
12
135
  add_key: do ssh keys add NAME PUBLIC_KEY
13
136
  add_value: Adds a new SSH key.
14
137
  delete_key: do ssh keys delete ID
15
- delete_value: Delete the SSH key with the given ID.
16
- edit_key: "do ssh keys edit ID [name=NAME] [public_key=PUBLIC_KEY]"
17
- edit_value: Change the NAME and/or PUBLIC_KEY of the SSH key with the given ID.
138
+ delete_value: Deletes the SSH key with the given ID.
139
+ edit_key: "do ssh keys edit ID [--name NAME] [--public-key PUBLIC_KEY]"
140
+ edit_value: Changes the NAME and/or PUBLIC_KEY of the SSH key with the given ID.
18
141
  list_key: do ssh keys list
19
142
  list_value: Lists all SSH keys.
20
143
  show_key: do ssh keys show ID
21
144
  show_value: Shows the public key for SSH key with the given ID.
145
+ sizes:
146
+ list_key: do sizes list
147
+ list_value: Lists all the possible image sizes.
148
+ images:
149
+ details: >-
150
+ ID: %{id}, Name: %{name}, Slug: %{slug}, Distribution: %{distribution},
151
+ Public: %{public}, Regions: %{formatted_regions},
152
+ Region Slugs: %{formatted_region_slugs}
153
+ delete:
154
+ deleted: "Deleted image: %{image_id}"
155
+ regions:
156
+ details: "ID: %{id}, Name: %{name}, Slug: %{slug}"
157
+ sizes:
158
+ details: "ID: %{id}, Name: %{name}, Slug: %{slug}"
22
159
  ssh_keys:
23
160
  add:
24
- created: "Created new SSH key: %{message}"
161
+ created: "Created new SSH key: %{id} (%{name}): %{ssh_pub_key}"
25
162
  delete:
26
163
  deleted: "Deleted SSH key: %{key_id}"
27
164
  edit:
28
- updated: "Updated SSH key: %{message}"
165
+ updated: "Updated SSH key: %{id} (%{name}): %{ssh_pub_key}"
29
166
  list:
30
167
  empty: No SSH keys have been added yet.
@@ -0,0 +1,39 @@
1
+ require "spec_helper"
2
+
3
+ handler_class = Class.new(Lita::Handlers::Digitalocean::Base) do
4
+ route /do droplets list/, :list, command: true
5
+
6
+ def self.default_config(config)
7
+ end
8
+
9
+ def list(response)
10
+ do_call(response) do |client|
11
+ { status: "error", message: "Something went wrong" }
12
+ end
13
+ end
14
+ end
15
+
16
+ describe handler_class, lita_handler: true do
17
+ describe "#do_call" do
18
+ it "responds with an error if the DigitalOcean API key is not set" do
19
+ send_command("do droplets list")
20
+ expect(replies.last).to include("client_id and api_key must be set")
21
+ end
22
+
23
+ it "responds with an error if the DigitalOcean client ID is not set" do
24
+ Lita.config.handlers.digitalocean.api_key = "secret"
25
+ send_command("do droplets list")
26
+ expect(replies.last).to include("client_id and api_key must be set")
27
+ end
28
+
29
+ it "responds with an error if the DigitalOcean API responds with an error" do
30
+ Lita.config.handlers.digitalocean.tap do |config|
31
+ config.api_key = "secret"
32
+ config.client_id = "secret"
33
+ end
34
+
35
+ send_command("do droplets list")
36
+ expect(replies.last).to eq("DigitalOcean API error: Something went wrong")
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,118 @@
1
+ require "spec_helper"
2
+
3
+ describe Lita::Handlers::Digitalocean::DomainRecord, lita_handler: true do
4
+ it do
5
+ routes_command(
6
+ "do domain records create example.com txt 'some value' --name example.com"
7
+ ).to(:create)
8
+ end
9
+ it { routes_command("do domain records delete example.com 123").to(:delete) }
10
+ it do
11
+ routes_command(
12
+ "do domain records edit example.com 123 txt 'some value' name=example.com"
13
+ ).to(:edit)
14
+ end
15
+ it { routes_command("do domain records list example.com").to(:list) }
16
+ it { routes_command("do domain records show example.com 123").to(:show) }
17
+
18
+ let(:client) { instance_double("::DigitalOcean::API", domains: client_domains) }
19
+ let(:client_domains) { instance_double("::DigitalOcean::Resource::Domain") }
20
+
21
+ before do
22
+ Lita.config.handlers.digitalocean = Lita::Config.new
23
+ Lita.config.handlers.digitalocean.tap do |config|
24
+ config.client_id = "CLIENT_ID"
25
+ config.api_key = "API_KEY"
26
+ end
27
+
28
+ allow(Lita::Authorization).to receive(:user_in_group?).with(
29
+ user,
30
+ :digitalocean_admins
31
+ ).and_return(true)
32
+
33
+ allow(::DigitalOcean::API).to receive(:new).and_return(client)
34
+ end
35
+
36
+ describe "#create" do
37
+ it "creates a new domain record" do
38
+ allow(client_domains).to receive(:create_record).with(
39
+ "example.com",
40
+ data: "@",
41
+ name: "foo",
42
+ port: "456",
43
+ priority: "123",
44
+ record_type: "srv",
45
+ weight: "789"
46
+ ).and_return(status: "OK", record: { id: 123 })
47
+ send_command("do domain records create example.com srv @ --name foo --priority 123 --port 456 --weight 789")
48
+ expect(replies.last).to eq("Created new DNS record: 123")
49
+ end
50
+ end
51
+
52
+ describe "#delete" do
53
+ it "deletes a domain record" do
54
+ allow(client_domains).to receive(:delete_record).with("123", "456").and_return(status: "OK")
55
+ send_command("do domain records delete 123 456")
56
+ expect(replies.last).to eq("Deleted DNS record.")
57
+ end
58
+ end
59
+
60
+ describe "#edit" do
61
+ it "edits a domain record" do
62
+ allow(client_domains).to receive(:edit_record).with(
63
+ "example.com",
64
+ "123",
65
+ data: "example.com",
66
+ record_type: "cname",
67
+ name: "www.example.com"
68
+ ).and_return(status: "OK")
69
+ send_command(
70
+ "do domain records edit example.com 123 cname example.com --name www.example.com"
71
+ )
72
+ expect(replies.last).to eq("Updated DNS record.")
73
+ end
74
+ end
75
+
76
+ describe "#list" do
77
+ it "responds with a list of all domain records for the given record set" do
78
+ allow(client_domains).to receive(:list_records).with("example.com").and_return(
79
+ status: "OK",
80
+ records: [{
81
+ id: 123,
82
+ record_type: "A",
83
+ data: "10.0.0.0"
84
+ }, {
85
+ id: 456,
86
+ record_type: "CNAME",
87
+ data: "@"
88
+ }]
89
+ )
90
+ send_command("do domain records list example.com")
91
+ expect(replies).to eq([
92
+ "ID: 123, Record Type: A, Data: 10.0.0.0",
93
+ "ID: 456, Record Type: CNAME, Data: @"
94
+ ])
95
+ end
96
+ end
97
+
98
+ describe "#show" do
99
+ it "responds with the details of the domain record" do
100
+ allow(client_domains).to receive(:show_record).with("example.com", "123").and_return(
101
+ status: "OK",
102
+ record: {
103
+ id: 123,
104
+ record_type: "A",
105
+ data: "10.0.0.0",
106
+ name: "example.com",
107
+ priority: 123,
108
+ port: 456,
109
+ weight: 789
110
+ }
111
+ )
112
+ send_command("do domain records show example.com 123")
113
+ expect(replies.last).to eq(
114
+ "ID: 123, Record Type: A, Data: 10.0.0.0, Name: example.com, Priority: 123, Port: 456, Weight: 789"
115
+ )
116
+ end
117
+ end
118
+ end