Skip to content

Commit e6fe9ee

Browse files
authored
feat: read variables from environment as command (#22)
1 parent 5d5097c commit e6fe9ee

File tree

3 files changed

+78
-32
lines changed

3 files changed

+78
-32
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import ArgumentParser
2+
import Foundation
3+
import Models
4+
5+
extension Array: ExpressibleByArgument where Element: Decodable {
6+
public init?(argument: String) {
7+
guard let data = argument.data(using: .utf8) else {
8+
return nil
9+
}
10+
11+
guard let decoded = try? JSONDecoder().decode(Self.self, from: data) else {
12+
return nil
13+
}
14+
15+
self = decoded
16+
}
17+
}
18+
19+
extension Optional: ExpressibleByArgument where Wrapped: ExpressibleByArgument {
20+
public init?(argument: String) {
21+
self = Wrapped(argument: argument)
22+
}
23+
}

Sources/Command/Environment.swift

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,49 @@
1+
import ArgumentParser
12
import Foundation
23

34
enum Environment {
4-
static var decoder: JSONDecoder = JSONDecoder()
5+
static var decoder = JSONDecoder()
56

6-
static func get<Key: CodingKey>(_ key: Key) -> String? {
7-
ProcessInfo.processInfo.environment[key.stringValue]
7+
@inlinable
8+
static func get(_ key: String) throws -> String {
9+
guard let value = ProcessInfo.processInfo.environment[key] else {
10+
throw Error.keyNotFound
11+
}
12+
13+
return value
814
}
915

10-
static func get<Key: CodingKey, D: Decodable>(
11-
_ key: Key,
16+
static func get<Key: CodingKey>(_ key: Key) throws -> String {
17+
try get(key.stringValue)
18+
}
19+
20+
@inlinable
21+
static func get<D: Decodable>(
22+
_ key: String,
1223
_ type: D.Type = D.self,
13-
decoder: JSONDecoder = Self.decoder
14-
) throws -> D? {
15-
guard let data = get(key)?.data(using: .utf8) else {
16-
return nil
24+
decoder: JSONDecoder? = nil
25+
) throws -> D {
26+
guard let data = try get(key).data(using: .utf8) else {
27+
throw Error.cannotConvertToData
1728
}
1829

30+
let decoder = decoder ?? Self.decoder
31+
1932
return try decoder.decode(D.self, from: data)
2033
}
34+
35+
static func get<Key: CodingKey, D: Decodable>(
36+
_ key: Key,
37+
_ type: D.Type = D.self,
38+
decoder: JSONDecoder? = nil
39+
) throws -> D {
40+
try get(key.stringValue)
41+
}
42+
}
43+
44+
extension Environment {
45+
enum Error: Swift.Error {
46+
case keyNotFound
47+
case cannotConvertToData
48+
}
2149
}

Sources/Command/run.swift

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import App
22
import ArgumentParser
3+
import Foundation
34
import Models
45
import NIO
56
import SotoCore
@@ -10,6 +11,16 @@ import SotoEKS
1011
struct Command: AsyncParsableCommand {
1112
static var configuration: CommandConfiguration { CommandConfiguration(commandName: "aws-asg-tags") }
1213

14+
// swiftlint:disable force_try
15+
16+
@Option(name: .shortAndLong)
17+
var clusterName: String = try! Environment.get(ClusterNodesTags.CodingKeys.clusterName)
18+
19+
@Option(name: .long)
20+
var nodePools: [NodePool] = try! Environment.get(ClusterNodesTags.CodingKeys.nodePools)
21+
22+
@Option(name: .long)
23+
var commonTags: [Tag]? = try? Environment.get(ClusterNodesTags.CodingKeys.commonTags)
1324

1425
func run() async throws {
1526
let logger = Logger(label: "ai.ydata.aws-asg-tags")
@@ -32,31 +43,15 @@ struct Command: AsyncParsableCommand {
3243

3344
let hulk = Hulk(asgClient: asgClient, eksClient: eksClient, logger: logger)
3445

35-
let clusterNodeTags = try createClusterNodeTags(logger)
36-
37-
try await hulk.smash(clusterNodeTags)
38-
}
39-
40-
private func createClusterNodeTags(_ logger: Logger) throws -> ClusterNodesTags {
41-
guard let clusterName = Environment.get(ClusterNodesTags.CodingKeys.clusterName) else {
42-
logger.error("missing value for property \(ClusterNodesTags.CodingKeys.clusterName.description))")
43-
throw Error.missingProperty
44-
}
45-
46-
logger.info("extracted clusterName from env: \(clusterName)")
47-
48-
guard let nodePools: [NodePool] = try Environment.get(ClusterNodesTags.CodingKeys.nodePools) else {
49-
logger.error("missing value for property \(ClusterNodesTags.CodingKeys.nodePools.description))")
50-
throw Error.missingProperty
51-
}
52-
53-
logger.info("extracted nodePools from env: \(nodePools)")
54-
55-
let commonTags: [Tag]? = try Environment.get(ClusterNodesTags.CodingKeys.commonTags)
46+
let clusterNodeTags = ClusterNodesTags(
47+
clusterName: clusterName,
48+
commonTags: commonTags,
49+
nodePools: nodePools
50+
)
5651

57-
logger.info("commonTags extracted from env: \(commonTags ?? [])")
52+
logger.info("processing cluster node tags:\n\(clusterNodeTags)")
5853

59-
return ClusterNodesTags(clusterName: clusterName, commonTags: commonTags, nodePools: nodePools)
54+
try await hulk.smash(clusterNodeTags)
6055
}
6156
}
6257

0 commit comments

Comments
 (0)