Skip to content

Commit bd11c14

Browse files
committed
add tag support
1 parent d042765 commit bd11c14

File tree

4 files changed

+166
-4
lines changed

4 files changed

+166
-4
lines changed

src/main/scala/me/jeffshaw/digitalocean/Droplet.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ case class Droplet(
164164
}
165165

166166
def refresh()(implicit client: DigitalOceanClient, ec: ExecutionContext): Future[Droplet] = {
167-
Droplet(id)
167+
Droplet(id)
168168
}
169169

170170
override def equals(obj: scala.Any): Boolean = {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package me.jeffshaw.digitalocean
2+
3+
import org.json4s.JsonDSL.WithBigDecimal._
4+
import scala.concurrent.{ExecutionContext, Future}
5+
6+
case class Tag(
7+
name: String,
8+
resources: Tag.Resources
9+
) {
10+
def delete()(implicit client: DigitalOceanClient,
11+
ec: ExecutionContext
12+
): Future[Unit] = {
13+
Tag.delete(name)
14+
}
15+
16+
def tagDropletIds(
17+
droplets: Seq[BigInt]
18+
)(implicit client: DigitalOceanClient,
19+
ec: ExecutionContext
20+
): Future[Unit] = {
21+
Tag.tagDropletIds(name, droplets)
22+
}
23+
24+
def tagDroplets(
25+
droplets: Seq[Droplet]
26+
)(implicit client: DigitalOceanClient,
27+
ec: ExecutionContext
28+
): Future[Unit] = {
29+
Tag.tagDroplets(name, droplets)
30+
}
31+
32+
def untagDropletIds(
33+
droplets: Seq[BigInt]
34+
)(implicit client: DigitalOceanClient,
35+
ec: ExecutionContext
36+
): Future[Unit] = {
37+
Tag.untagDropletIds(name, droplets)
38+
}
39+
40+
def untagDroplets(
41+
droplets: Seq[Droplet]
42+
)(implicit client: DigitalOceanClient,
43+
ec: ExecutionContext
44+
): Future[Unit] = {
45+
Tag.untagDroplets(name, droplets)
46+
}
47+
}
48+
49+
object Tag extends Path {
50+
51+
override protected val path: Seq[String] = Seq("tags")
52+
53+
def apply(
54+
name: String
55+
)(implicit client: DigitalOceanClient,
56+
ec: ExecutionContext
57+
): Future[Tag] = {
58+
client.get[responses.Tag](path :+ name).map(_.tag)
59+
}
60+
61+
def list()(implicit client: DigitalOceanClient,
62+
ec: ExecutionContext
63+
): Future[Seq[Tag]] = {
64+
client.get[responses.Tags](path).map(_.tags)
65+
}
66+
67+
def create(
68+
name: String
69+
)(implicit client: DigitalOceanClient,
70+
ec: ExecutionContext
71+
): Future[Tag] = {
72+
client.post[responses.Tag](path, "name" -> name).map(_.tag)
73+
}
74+
75+
def delete(
76+
name: String
77+
)(implicit client: DigitalOceanClient,
78+
ec: ExecutionContext
79+
): Future[Unit] = {
80+
client.delete(path :+ name)
81+
}
82+
83+
def tagDroplets(
84+
name: String,
85+
droplets: Seq[Droplet]
86+
)(implicit client: DigitalOceanClient,
87+
ec: ExecutionContext
88+
): Future[Unit] = {
89+
tagDropletIds(name, droplets.map(_.id))
90+
}
91+
92+
def tagDropletIds(
93+
name: String,
94+
dropletIds: Seq[BigInt]
95+
)(implicit client: DigitalOceanClient,
96+
ec: ExecutionContext
97+
): Future[Unit] = {
98+
if (dropletIds.isEmpty) {
99+
Future.successful(())
100+
} else {
101+
val postBody =
102+
"resources" -> (
103+
for {
104+
id <- dropletIds
105+
} yield ("resource_id" -> id) ~ ("resource_type" -> "droplet")
106+
)
107+
client.postWithEmptyResponse(path :+ name, postBody)
108+
}
109+
}
110+
111+
def untagDroplets(
112+
name: String,
113+
droplets: Seq[Droplet]
114+
)(implicit client: DigitalOceanClient,
115+
ec: ExecutionContext
116+
): Future[Unit] = {
117+
untagDropletIds(name, droplets.map(_.id))
118+
}
119+
120+
def untagDropletIds(
121+
name: String,
122+
dropletIds: Seq[BigInt]
123+
)(implicit client: DigitalOceanClient,
124+
ec: ExecutionContext
125+
): Future[Unit] = {
126+
if (dropletIds.isEmpty) {
127+
Future.successful(())
128+
} else {
129+
val postBody =
130+
"resources" -> (
131+
for {
132+
id <- dropletIds
133+
} yield ("resource_id" -> id) ~ ("resource_type" -> "droplet")
134+
)
135+
client.delete(path :+ name, maybeMessage = Some(postBody))
136+
}
137+
}
138+
139+
case class Resources(
140+
droplets: Resources.Droplets
141+
)
142+
143+
object Resources {
144+
case class Droplets(
145+
count: BigInt,
146+
lastTagged: Option[Droplet]
147+
)
148+
}
149+
150+
}

src/main/scala/me/jeffshaw/digitalocean/responses/package.scala

+8
Original file line numberDiff line numberDiff line change
@@ -376,4 +376,12 @@ package object responses {
376376
firewall: Firewall
377377
)
378378

379+
private[digitalocean] case class Tag(
380+
tag: digitalocean.Tag
381+
)
382+
383+
private [digitalocean] case class Tags(
384+
tags: Seq[digitalocean.Tag]
385+
)
386+
379387
}

src/test/scala/me/jeffshaw/digitalocean/FirewallSpec.scala

+7-3
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import scala.concurrent.duration._
77

88
class FirewallSpec extends Suite {
99

10+
val randomSuffix = Random.nextInt().toString
11+
1012
test("create, update") {
11-
val name = firewallNamePrefix + Random.nextInt()
13+
val name = firewallNamePrefix + randomSuffix
1214
val inboundRule = Firewall.InboundRule(
1315
protocol = Firewall.Protocol.Tcp(Firewall.Port.Range(1, 2)),
1416
sources = Firewall.Source(addresses = Seq(Firewall.Source.Address(InetAddress.getByName("1.1.1.1"), cidr = Some(8))))
@@ -22,15 +24,16 @@ class FirewallSpec extends Suite {
2224
assert(firewall.tags.isEmpty)
2325
assert(firewall.dropletIds.isEmpty)
2426

25-
2627
val outboundRule =
2728
Firewall.OutboundRule(
2829
protocol = Firewall.Protocol.Icmp,
2930
destinations = Firewall.Destination(
30-
tags = Seq("hi")
31+
tags = Seq(name)
3132
)
3233
)
3334

35+
val tag = Await.result(Tag.create(name), 10 seconds)
36+
3437
val updated =
3538
Await.result(
3639
firewall.update(
@@ -42,6 +45,7 @@ class FirewallSpec extends Suite {
4245

4346
assert(updated.inboundRules.isEmpty)
4447
assertResult(Seq(outboundRule))(updated.outboundRules)
48+
Await.result(tag.delete(), 10 seconds)
4549
}
4650

4751
override protected def afterAll(): Unit = {

0 commit comments

Comments
 (0)