floe 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +27 -13
- data/README.md +27 -0
- data/lib/floe/version.rb +1 -1
- data/lib/floe/workflow/payload_template.rb +5 -4
- data/lib/floe/workflow/runner/docker.rb +9 -2
- data/lib/floe/workflow/runner/podman.rb +9 -2
- data/lib/floe/workflow/state.rb +0 -9
- data/lib/floe/workflow/states/choice.rb +8 -0
- data/lib/floe/workflow/states/fail.rb +4 -1
- data/lib/floe/workflow/states/pass.rb +10 -1
- data/lib/floe/workflow/states/succeed.rb +8 -2
- data/lib/floe/workflow/states/task.rb +10 -1
- data/lib/floe/workflow/states/wait.rb +10 -1
- data/lib/floe/workflow.rb +12 -12
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f2791bb2351fad37f210264d51e059b780937e42a5cb1ab2c9c157ac01e18eea
|
4
|
+
data.tar.gz: 37436eb4095fc92c4ec4d07e84a09fd27a5b3e794faea09d5ebd37383f886830
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ef1fd3317c12e6af2cdfaaf07dc7cf9c281579d21b623b8ff1a7bcfe906794e19d4b964e3e33560a8d1a3e66abc1c7b1fe85e236c05497aaafea5dc027e8acfd
|
7
|
+
data.tar.gz: da683adbe9e0513613524f1e6c94380159e0cb07a34b6464c90b76b1ea9227534c1a7af6c1c884873ee9a811cbf90bc40275c4c728c20d2a8732172eab6554d6
|
data/CHANGELOG.md
CHANGED
@@ -4,45 +4,59 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
4
4
|
|
5
5
|
## [Unreleased]
|
6
6
|
|
7
|
+
## [0.3.0] - 2023-08-07
|
8
|
+
### Added
|
9
|
+
- Add --network=host option to Docker/Podman runners ([#81])(https://github.com/ManageIQ/floe/pull/81)
|
10
|
+
|
11
|
+
### Fixed
|
12
|
+
- Fix PayloadTemplate value transformation rules ([#78])(https://github.com/ManageIQ/floe/pull/78)
|
13
|
+
- Move end out of the root state node ([#80])(https://github.com/ManageIQ/floe/pull/80)
|
14
|
+
|
15
|
+
## [0.2.3] - 2023-07-28
|
16
|
+
### Fixed
|
17
|
+
- Fix storing next_state in Context ([#76])(https://github.com/ManageIQ/floe/pull/76)
|
18
|
+
|
7
19
|
## [0.2.2] - 2023-07-24
|
8
20
|
### Fixed
|
9
|
-
- Don't pick up real KUBECONFIG for tests (#73)
|
10
|
-
- Fix double json.parse and context default value (#69)
|
21
|
+
- Don't pick up real KUBECONFIG for tests ([#73](https://github.com/ManageIQ/floe/pull/73))
|
22
|
+
- Fix double json.parse and context default value ([#69](https://github.com/ManageIQ/floe/pull/69))
|
11
23
|
|
12
24
|
### Added
|
13
|
-
- Configure Renovate (#46)
|
25
|
+
- Configure Renovate ([#46](https://github.com/ManageIQ/floe/pull/46))
|
14
26
|
|
15
27
|
### Changed
|
16
|
-
- Simplify next state handling (#66)
|
17
|
-
- Refactor Input/Output path handling (#68)
|
28
|
+
- Simplify next state handling ([#66](https://github.com/ManageIQ/floe/pull/66))
|
29
|
+
- Refactor Input/Output path handling ([#68](https://github.com/ManageIQ/floe/pull/68))
|
18
30
|
|
19
31
|
## [0.2.1] - 2023-07-12
|
20
32
|
### Fixed
|
21
|
-
- Fix State EnteredTime and FinishedTime (#59)
|
33
|
+
- Fix State EnteredTime and FinishedTime ([#59](https://github.com/ManageIQ/floe/pull/59))
|
22
34
|
|
23
35
|
### Added
|
24
|
-
- Add workflow output (#57)
|
36
|
+
- Add workflow output ([#57](https://github.com/ManageIQ/floe/pull/57))
|
25
37
|
|
26
38
|
## [0.2.0] - 2023-07-05
|
27
39
|
### Added
|
28
|
-
- Add ability to pass options to `Floe::Workflow::Runner` (#48)
|
29
|
-
- Add kubeconfig file support to `Floe::Workflow::Runner::Kubernetes` (#53)
|
40
|
+
- Add ability to pass options to `Floe::Workflow::Runner` ([#48](https://github.com/ManageIQ/floe/pull/48))
|
41
|
+
- Add kubeconfig file support to `Floe::Workflow::Runner::Kubernetes` ([#53](https://github.com/ManageIQ/floe/pull/53))
|
30
42
|
|
31
43
|
### Removed
|
32
|
-
- Remove to_dot/to_svg code (#54)
|
44
|
+
- Remove to_dot/to_svg code ([#54](https://github.com/ManageIQ/floe/pull/54))
|
33
45
|
|
34
46
|
### Fixed
|
35
|
-
- Fixed default rake task to spec (#55)
|
47
|
+
- Fixed default rake task to spec ([#55](https://github.com/ManageIQ/floe/pull/55))
|
36
48
|
|
37
49
|
## [0.1.1] - 2023-06-05
|
38
50
|
### Fixed
|
39
|
-
- Fix States::Wait Path initializer arguments (#47)
|
51
|
+
- Fix States::Wait Path initializer arguments ([#47](https://github.com/ManageIQ/floe/pull/47))
|
40
52
|
|
41
53
|
## [0.1.0] - 2023-03-13
|
42
54
|
### Added
|
43
55
|
- Initial release
|
44
56
|
|
45
|
-
[Unreleased]: https://github.com/ManageIQ/floe/compare/v0.
|
57
|
+
[Unreleased]: https://github.com/ManageIQ/floe/compare/v0.3.0...HEAD
|
58
|
+
[0.3.0]: https://github.com/ManageIQ/floe/compare/v0.2.3...v0.3.0
|
59
|
+
[0.2.3]: https://github.com/ManageIQ/floe/compare/v0.2.2...v0.2.3
|
46
60
|
[0.2.2]: https://github.com/ManageIQ/floe/compare/v0.2.1...v0.2.2
|
47
61
|
[0.2.1]: https://github.com/ManageIQ/floe/compare/v0.2.0...v0.2.1
|
48
62
|
[0.2.0]: https://github.com/ManageIQ/floe/compare/v0.1.1...v0.2.0
|
data/README.md
CHANGED
@@ -36,6 +36,21 @@ bundle exec ruby exe/floe --workflow examples/workflow.asl --inputs='{"foo": 1}'
|
|
36
36
|
bundle exec ruby exe/floe --workflow examples/workflow.asl --inputs='{"foo": 1}' --docker-runner kubernetes --docker-runner-options namespace=default server=https://k8s.example.com:6443 token=my-token
|
37
37
|
```
|
38
38
|
|
39
|
+
If your workflow has `Credentials` you can provide a payload that will help resolve those credentials references at runtime.
|
40
|
+
|
41
|
+
For example if your workflow had the following Credentials field with a JSON Path property:
|
42
|
+
```json
|
43
|
+
"Credentials": {
|
44
|
+
"RoleArn.$": "$.roleArn"
|
45
|
+
}
|
46
|
+
```
|
47
|
+
|
48
|
+
You can provide that at runtime via the `--credentials` parameter:
|
49
|
+
|
50
|
+
```
|
51
|
+
bundle exec ruby exe/floe --workflow my-workflow.asl --credentials='{"roleArn": "arn:aws:iam::111122223333:role/LambdaRole"}'
|
52
|
+
```
|
53
|
+
|
39
54
|
### Ruby Library
|
40
55
|
|
41
56
|
```ruby
|
@@ -59,6 +74,18 @@ workflow.run!
|
|
59
74
|
|
60
75
|
### Docker Runner Options
|
61
76
|
|
77
|
+
#### Docker
|
78
|
+
|
79
|
+
Options supported by the Docker docker runner are:
|
80
|
+
|
81
|
+
* `network` - What docker to connect the container to, defaults to `"bridge"`. If you need access to host resources for development you can pass `network=host`.
|
82
|
+
|
83
|
+
#### Podman
|
84
|
+
|
85
|
+
Options supported by the podman docker runner are:
|
86
|
+
|
87
|
+
* `network` - What docker to connect the container to, defaults to `"bridge"`. If you need access to host resources for development you can pass `network=host`.
|
88
|
+
|
62
89
|
#### Kubernetes
|
63
90
|
|
64
91
|
Options supported by the kubernetes docker runner are:
|
data/lib/floe/version.rb
CHANGED
@@ -21,10 +21,11 @@ module Floe
|
|
21
21
|
value.map { |val| interpolate_value_nested(val, context, inputs) }
|
22
22
|
when Hash
|
23
23
|
value.to_h do |key, val|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
if key.end_with?(".$")
|
25
|
+
[key.chomp(".$"), interpolate_value_nested(val, context, inputs)]
|
26
|
+
else
|
27
|
+
[key, val]
|
28
|
+
end
|
28
29
|
end
|
29
30
|
when String
|
30
31
|
value.start_with?("$") ? Path.value(value, context, inputs) : value
|
@@ -4,11 +4,13 @@ module Floe
|
|
4
4
|
class Workflow
|
5
5
|
class Runner
|
6
6
|
class Docker < Floe::Workflow::Runner
|
7
|
-
def initialize(
|
7
|
+
def initialize(options = {})
|
8
8
|
require "awesome_spawn"
|
9
9
|
require "tempfile"
|
10
10
|
|
11
11
|
super
|
12
|
+
|
13
|
+
@network = options.fetch("network", "bridge")
|
12
14
|
end
|
13
15
|
|
14
16
|
def run!(resource, env = {}, secrets = {})
|
@@ -16,7 +18,8 @@ module Floe
|
|
16
18
|
|
17
19
|
image = resource.sub("docker://", "")
|
18
20
|
|
19
|
-
params
|
21
|
+
params = ["run", :rm]
|
22
|
+
params += [[:net, "host"]] if network == "host"
|
20
23
|
params += env.map { |k, v| [:e, "#{k}=#{v}"] } if env
|
21
24
|
|
22
25
|
secrets_file = nil
|
@@ -39,6 +42,10 @@ module Floe
|
|
39
42
|
ensure
|
40
43
|
secrets_file&.close!
|
41
44
|
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
attr_reader :network
|
42
49
|
end
|
43
50
|
end
|
44
51
|
end
|
@@ -4,11 +4,13 @@ module Floe
|
|
4
4
|
class Workflow
|
5
5
|
class Runner
|
6
6
|
class Podman < Floe::Workflow::Runner
|
7
|
-
def initialize(
|
7
|
+
def initialize(options = {})
|
8
8
|
require "awesome_spawn"
|
9
9
|
require "securerandom"
|
10
10
|
|
11
11
|
super
|
12
|
+
|
13
|
+
@network = options.fetch("network", "bridge")
|
12
14
|
end
|
13
15
|
|
14
16
|
def run!(resource, env = {}, secrets = {})
|
@@ -16,7 +18,8 @@ module Floe
|
|
16
18
|
|
17
19
|
image = resource.sub("docker://", "")
|
18
20
|
|
19
|
-
params
|
21
|
+
params = ["run", :rm]
|
22
|
+
params += [[:net, "host"]] if network == "host"
|
20
23
|
params += env.map { |k, v| [:e, "#{k}=#{v}"] } if env
|
21
24
|
|
22
25
|
if secrets && !secrets.empty?
|
@@ -36,6 +39,10 @@ module Floe
|
|
36
39
|
ensure
|
37
40
|
AwesomeSpawn.run("podman", :params => ["secret", "rm", secret_guid]) if secret_guid
|
38
41
|
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
attr_reader :network
|
39
46
|
end
|
40
47
|
end
|
41
48
|
end
|
data/lib/floe/workflow/state.rb
CHANGED
@@ -25,22 +25,13 @@ module Floe
|
|
25
25
|
@workflow = workflow
|
26
26
|
@name = name
|
27
27
|
@payload = payload
|
28
|
-
@end = !!payload["End"]
|
29
28
|
@type = payload["Type"]
|
30
29
|
@comment = payload["Comment"]
|
31
30
|
end
|
32
31
|
|
33
|
-
def end?
|
34
|
-
@end
|
35
|
-
end
|
36
|
-
|
37
32
|
def context
|
38
33
|
workflow.context
|
39
34
|
end
|
40
|
-
|
41
|
-
def status
|
42
|
-
end? ? "success" : "running"
|
43
|
-
end
|
44
35
|
end
|
45
36
|
end
|
46
37
|
end
|
@@ -10,6 +10,7 @@ module Floe
|
|
10
10
|
super
|
11
11
|
|
12
12
|
@next = payload["Next"]
|
13
|
+
@end = !!payload["End"]
|
13
14
|
@result = payload["Result"]
|
14
15
|
|
15
16
|
@parameters = PayloadTemplate.new(payload["Parameters"]) if payload["Parameters"]
|
@@ -23,7 +24,15 @@ module Floe
|
|
23
24
|
output = result_path.set(output, result) if result && result_path
|
24
25
|
output = output_path.value(context, output)
|
25
26
|
|
26
|
-
[@next, output]
|
27
|
+
[@end ? nil : @next, output]
|
28
|
+
end
|
29
|
+
|
30
|
+
def status
|
31
|
+
@end ? "success" : "running"
|
32
|
+
end
|
33
|
+
|
34
|
+
def end?
|
35
|
+
@end
|
27
36
|
end
|
28
37
|
end
|
29
38
|
end
|
@@ -13,6 +13,7 @@ module Floe
|
|
13
13
|
|
14
14
|
@heartbeat_seconds = payload["HeartbeatSeconds"]
|
15
15
|
@next = payload["Next"]
|
16
|
+
@end = !!payload["End"]
|
16
17
|
@resource = payload["Resource"]
|
17
18
|
@timeout_seconds = payload["TimeoutSeconds"]
|
18
19
|
@retry = payload["Retry"].to_a.map { |retrier| Retrier.new(retrier) }
|
@@ -33,7 +34,7 @@ module Floe
|
|
33
34
|
_exit_status, results = runner.run!(resource, input, credentials&.value({}, workflow.credentials))
|
34
35
|
|
35
36
|
output = process_output!(input, results)
|
36
|
-
[@next, output]
|
37
|
+
[@end ? nil : @next, output]
|
37
38
|
rescue => err
|
38
39
|
retrier = self.retry.detect { |r| (r.error_equals & [err.to_s, "States.ALL"]).any? }
|
39
40
|
retry if retry!(retrier)
|
@@ -44,6 +45,14 @@ module Floe
|
|
44
45
|
[catcher.next, output]
|
45
46
|
end
|
46
47
|
|
48
|
+
def status
|
49
|
+
@end ? "success" : "running"
|
50
|
+
end
|
51
|
+
|
52
|
+
def end?
|
53
|
+
@end
|
54
|
+
end
|
55
|
+
|
47
56
|
private
|
48
57
|
|
49
58
|
def retry!(retrier)
|
@@ -10,6 +10,7 @@ module Floe
|
|
10
10
|
super
|
11
11
|
|
12
12
|
@next = payload["Next"]
|
13
|
+
@end = !!payload["End"]
|
13
14
|
@seconds = payload["Seconds"].to_i
|
14
15
|
|
15
16
|
@input_path = Path.new(payload.fetch("InputPath", "$"))
|
@@ -20,7 +21,15 @@ module Floe
|
|
20
21
|
input = input_path.value(context, input)
|
21
22
|
sleep(seconds)
|
22
23
|
output = output_path.value(context, input)
|
23
|
-
[@next, output]
|
24
|
+
[@end ? nil : @next, output]
|
25
|
+
end
|
26
|
+
|
27
|
+
def status
|
28
|
+
@end ? "success" : "running"
|
29
|
+
end
|
30
|
+
|
31
|
+
def end?
|
32
|
+
@end
|
24
33
|
end
|
25
34
|
end
|
26
35
|
end
|
data/lib/floe/workflow.rb
CHANGED
@@ -29,8 +29,10 @@ module Floe
|
|
29
29
|
@states_by_name = @states.each_with_object({}) { |state, result| result[state.name] = state }
|
30
30
|
start_at = @payload["StartAt"]
|
31
31
|
|
32
|
-
|
33
|
-
|
32
|
+
context.state["Name"] ||= start_at
|
33
|
+
|
34
|
+
current_state_name = context.state["Name"]
|
35
|
+
@current_state = @states_by_name[current_state_name]
|
34
36
|
|
35
37
|
@status = current_state_name == start_at ? "pending" : current_state.status
|
36
38
|
rescue JSON::ParserError => err
|
@@ -41,26 +43,22 @@ module Floe
|
|
41
43
|
@status = "running" if @status == "pending"
|
42
44
|
context.execution["StartTime"] ||= Time.now.utc
|
43
45
|
|
44
|
-
|
46
|
+
context.state["Guid"] = SecureRandom.uuid
|
47
|
+
context.state["Input"] ||= context.execution["Input"].dup
|
45
48
|
|
46
|
-
logger.info("Running state: [#{current_state.name}] with input [#{
|
49
|
+
logger.info("Running state: [#{current_state.name}] with input [#{context.state["Input"]}]...")
|
47
50
|
|
48
|
-
context.state =
|
49
|
-
"Guid" => SecureRandom.uuid,
|
50
|
-
"EnteredTime" => Time.now.utc,
|
51
|
-
"Input" => input,
|
52
|
-
"Name" => current_state.name
|
53
|
-
}
|
51
|
+
context.state["EnteredTime"] = Time.now.utc
|
54
52
|
|
55
53
|
tick = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
56
|
-
next_state, output = current_state.run!(
|
54
|
+
next_state, output = current_state.run!(context.state["Input"])
|
57
55
|
tock = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
58
56
|
|
59
57
|
context.state["FinishedTime"] = Time.now.utc
|
60
58
|
context.state["Duration"] = (tock - tick) / 1_000_000.0
|
61
59
|
context.state["Output"] = output
|
62
60
|
|
63
|
-
logger.info("Running state: [#{current_state.name}] with input [#{
|
61
|
+
logger.info("Running state: [#{current_state.name}] with input [#{context["Input"]}]...Complete - next state: [#{next_state}] output: [#{output}]")
|
64
62
|
|
65
63
|
context.states << context.state
|
66
64
|
|
@@ -68,6 +66,8 @@ module Floe
|
|
68
66
|
@current_state = next_state && @states_by_name[next_state]
|
69
67
|
@output = output if end?
|
70
68
|
|
69
|
+
context.state = {"Name" => next_state, "Input" => output} unless end?
|
70
|
+
|
71
71
|
self
|
72
72
|
end
|
73
73
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: floe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ManageIQ Developers
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-07
|
11
|
+
date: 2023-08-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: awesome_spawn
|