floe 0.6.1 → 0.7.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -1
- data/README.md +32 -0
- data/examples/set-credential.asl +26 -0
- data/floe.gemspec +0 -1
- data/lib/floe/version.rb +1 -1
- data/lib/floe/workflow/path.rb +2 -4
- data/lib/floe/workflow/reference_path.rb +28 -11
- data/lib/floe/workflow/states/input_output_mixin.rb +31 -0
- data/lib/floe/workflow/states/pass.rb +4 -4
- data/lib/floe/workflow/states/task.rb +2 -17
- data/lib/floe.rb +1 -0
- metadata +4 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8e3870ee415e08857191014d61d92dac1b84be70aeff69bed7dbb6dd6f5f7af3
|
4
|
+
data.tar.gz: f6695006e7043837a078a8092ba1c544e23750a9179018ed29e84520e78424eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ada0c662fa9f4c300ca977029b3c522a5ba36adf37485260dfccba5961064adfc513853beb1b992ca9199856b457bb6f66c8f4d60918157cb4579cf0655d7a7b
|
7
|
+
data.tar.gz: f6918df717d7e5c29d7298c1f9076d77515a3033247fefde072cdfd59797227defcec0087189d58945bbbbd528da3b5d876af612479bd1d2754fc7dc78db8c81
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,14 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
4
4
|
|
5
5
|
## [Unreleased]
|
6
6
|
|
7
|
+
## [0.7.0] - 2023-12-18
|
8
|
+
### Changed
|
9
|
+
- Remove the dependency on more_core_extensions in ReferencePath ([#144](https://github.com/ManageIQ/floe/pull/144))
|
10
|
+
|
11
|
+
### Added
|
12
|
+
- Implement `ReferencePath#get` ([#144](https://github.com/ManageIQ/floe/pull/144))
|
13
|
+
- Allow a State to set a value in Credentials for subsequent states ([#145](https://github.com/ManageIQ/floe/pull/145))
|
14
|
+
|
7
15
|
## [0.6.1] - 2023-11-21
|
8
16
|
### Fixed
|
9
17
|
- Return an error payload if run_async! fails ([#143](https://github.com/ManageIQ/floe/pull/143))
|
@@ -106,7 +114,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
106
114
|
### Added
|
107
115
|
- Initial release
|
108
116
|
|
109
|
-
[Unreleased]: https://github.com/ManageIQ/floe/compare/v0.
|
117
|
+
[Unreleased]: https://github.com/ManageIQ/floe/compare/v0.7.0...HEAD
|
118
|
+
[0.7.0]: https://github.com/ManageIQ/floe/compare/v0.6.1...v0.7.0
|
110
119
|
[0.6.1]: https://github.com/ManageIQ/floe/compare/v0.6.0...v0.6.1
|
111
120
|
[0.6.0]: https://github.com/ManageIQ/floe/compare/v0.5.0...v0.6.0
|
112
121
|
[0.5.0]: https://github.com/ManageIQ/floe/compare/v0.4.1...v0.5.0
|
data/README.md
CHANGED
@@ -51,6 +51,38 @@ You can provide that at runtime via the `--credentials` parameter:
|
|
51
51
|
bundle exec ruby exe/floe --workflow my-workflow.asl --credentials='{"roleArn": "arn:aws:iam::111122223333:role/LambdaRole"}'
|
52
52
|
```
|
53
53
|
|
54
|
+
If you need to set a credential at runtime you can do that by using the `"ResultPath": "$.Credentials"` directive, for example to user a username/password to login and get a Bearer token:
|
55
|
+
|
56
|
+
```
|
57
|
+
bundle exec ruby exe/floe --workflow my-workflow.asl --credentials='{"username": "user", "password": "pass"}'
|
58
|
+
```
|
59
|
+
|
60
|
+
```json
|
61
|
+
{
|
62
|
+
"StartAt": "Login",
|
63
|
+
"States": {
|
64
|
+
"Login": {
|
65
|
+
"Type": "Task",
|
66
|
+
"Resource": "docker://login:latest",
|
67
|
+
"Credentials": {
|
68
|
+
"username.$": "$.username",
|
69
|
+
"password.$": "$.password"
|
70
|
+
},
|
71
|
+
"ResultPath": "$.Credentials",
|
72
|
+
"Next": "DoSomething"
|
73
|
+
},
|
74
|
+
"DoSomething": {
|
75
|
+
"Type": "Task",
|
76
|
+
"Resource": "docker://do-something:latest",
|
77
|
+
"Credentials": {
|
78
|
+
"token.$": "$.bearer_token"
|
79
|
+
},
|
80
|
+
"End": true
|
81
|
+
}
|
82
|
+
}
|
83
|
+
}
|
84
|
+
```
|
85
|
+
|
54
86
|
### Ruby Library
|
55
87
|
|
56
88
|
```ruby
|
@@ -0,0 +1,26 @@
|
|
1
|
+
{
|
2
|
+
"Comment": "An example showing how to set a credential.",
|
3
|
+
"StartAt": "Login",
|
4
|
+
"States": {
|
5
|
+
"Login": {
|
6
|
+
"Type": "Task",
|
7
|
+
"Resource": "docker://docker.io/agrare/echo:latest",
|
8
|
+
"Parameters": {
|
9
|
+
"ECHO": "TOKEN"
|
10
|
+
},
|
11
|
+
"ResultPath": "$.Credentials",
|
12
|
+
"ResultSelector": {
|
13
|
+
"bearer_token.$": "$.echo"
|
14
|
+
},
|
15
|
+
"Next": "DoSomething"
|
16
|
+
},
|
17
|
+
"DoSomething": {
|
18
|
+
"Type": "Task",
|
19
|
+
"Resource": "docker://docker.io/agrare/hello-world:latest",
|
20
|
+
"Credentials": {
|
21
|
+
"bearer_token.$": "$.bearer_token"
|
22
|
+
},
|
23
|
+
"End": true
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
data/floe.gemspec
CHANGED
data/lib/floe/version.rb
CHANGED
data/lib/floe/workflow/path.rb
CHANGED
@@ -9,6 +9,8 @@ module Floe
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
+
attr_reader :payload
|
13
|
+
|
12
14
|
def initialize(payload)
|
13
15
|
@payload = payload
|
14
16
|
|
@@ -28,10 +30,6 @@ module Floe
|
|
28
30
|
|
29
31
|
results.count < 2 ? results.first : results
|
30
32
|
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
attr_reader :payload
|
35
33
|
end
|
36
34
|
end
|
37
35
|
end
|
@@ -4,37 +4,54 @@ module Floe
|
|
4
4
|
class Workflow
|
5
5
|
class ReferencePath < Path
|
6
6
|
class << self
|
7
|
+
def get(payload, context)
|
8
|
+
new(payload).get(context)
|
9
|
+
end
|
10
|
+
|
7
11
|
def set(payload, context, value)
|
8
12
|
new(payload).set(context, value)
|
9
13
|
end
|
10
14
|
end
|
11
15
|
|
12
|
-
|
13
|
-
require "more_core_extensions/core_ext/hash/nested"
|
14
|
-
require "more_core_extensions/core_ext/array/nested"
|
16
|
+
attr_reader :path
|
15
17
|
|
18
|
+
def initialize(*)
|
16
19
|
super
|
17
20
|
|
18
21
|
raise Floe::InvalidWorkflowError, "Invalid Reference Path" if payload.match?(/@|,|:|\?/)
|
22
|
+
@path = JsonPath.new(payload)
|
23
|
+
.path[1..]
|
24
|
+
.map { |v| v.match(/\[(?<name>.+)\]/)["name"] }
|
25
|
+
.map { |v| v[0] == "'" ? v.delete("'") : v.to_i }
|
26
|
+
.compact
|
27
|
+
end
|
28
|
+
|
29
|
+
def get(context)
|
30
|
+
return context if path.empty?
|
31
|
+
|
32
|
+
context.dig(*path)
|
19
33
|
end
|
20
34
|
|
21
35
|
def set(context, value)
|
22
36
|
result = context.dup
|
23
37
|
|
24
|
-
path = JsonPath.new(payload)
|
25
|
-
.path[1..]
|
26
|
-
.map { |v| v.match(/\[(?<name>.+)\]/)["name"] }
|
27
|
-
.map { |v| v[0] == "'" ? v.delete("'") : v.to_i }
|
28
|
-
.compact
|
29
|
-
|
30
38
|
# If the payload is '$' then merge the value into the context
|
31
|
-
# otherwise
|
39
|
+
# otherwise store the value under the path
|
32
40
|
#
|
33
41
|
# TODO: how to handle non-hash values, raise error if path=$ and value not a hash?
|
34
42
|
if path.empty?
|
35
43
|
result.merge!(value)
|
36
44
|
else
|
37
|
-
result
|
45
|
+
child = result
|
46
|
+
keys = path.dup
|
47
|
+
last_key = keys.pop
|
48
|
+
|
49
|
+
keys.each do |key|
|
50
|
+
child[key] = {} if child[key].nil?
|
51
|
+
child = child[key]
|
52
|
+
end
|
53
|
+
|
54
|
+
child[last_key] = value
|
38
55
|
end
|
39
56
|
|
40
57
|
result
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Floe
|
4
|
+
class Workflow
|
5
|
+
module States
|
6
|
+
module InputOutputMixin
|
7
|
+
def process_input(input)
|
8
|
+
input = input_path.value(context, input)
|
9
|
+
input = parameters.value(context, input) if parameters
|
10
|
+
input
|
11
|
+
end
|
12
|
+
|
13
|
+
def process_output(input, results)
|
14
|
+
return input if results.nil?
|
15
|
+
return if output_path.nil?
|
16
|
+
|
17
|
+
results = result_selector.value(context, results) if @result_selector
|
18
|
+
if result_path.payload.start_with?("$.Credentials")
|
19
|
+
credentials = result_path.set(workflow.credentials, results)["Credentials"]
|
20
|
+
workflow.credentials.merge!(credentials)
|
21
|
+
output = input
|
22
|
+
else
|
23
|
+
output = result_path.set(input, results)
|
24
|
+
end
|
25
|
+
|
26
|
+
output_path.value(context, output)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -4,6 +4,7 @@ module Floe
|
|
4
4
|
class Workflow
|
5
5
|
module States
|
6
6
|
class Pass < Floe::Workflow::State
|
7
|
+
include InputOutputMixin
|
7
8
|
include NonTerminalMixin
|
8
9
|
|
9
10
|
attr_reader :end, :next, :result, :parameters, :input_path, :output_path, :result_path
|
@@ -25,12 +26,11 @@ module Floe
|
|
25
26
|
|
26
27
|
def start(input)
|
27
28
|
super
|
28
|
-
output = input_path.value(context, input)
|
29
|
-
output = result_path.set(output, result) if result && result_path
|
30
|
-
output = output_path.value(context, output)
|
31
29
|
|
30
|
+
input = process_input(input)
|
31
|
+
|
32
|
+
context.output = process_output(input, result)
|
32
33
|
context.next_state = end? ? nil : @next
|
33
|
-
context.output = output
|
34
34
|
end
|
35
35
|
|
36
36
|
def running?
|
@@ -4,6 +4,7 @@ module Floe
|
|
4
4
|
class Workflow
|
5
5
|
module States
|
6
6
|
class Task < Floe::Workflow::State
|
7
|
+
include InputOutputMixin
|
7
8
|
include NonTerminalMixin
|
8
9
|
|
9
10
|
attr_reader :credentials, :end, :heartbeat_seconds, :next, :parameters,
|
@@ -49,7 +50,7 @@ module Floe
|
|
49
50
|
|
50
51
|
if success?
|
51
52
|
output = parse_output(output)
|
52
|
-
context.state["Output"] = process_output
|
53
|
+
context.state["Output"] = process_output(context.input.dup, output)
|
53
54
|
context.next_state = next_state
|
54
55
|
else
|
55
56
|
error = parse_error(output)
|
@@ -126,12 +127,6 @@ module Floe
|
|
126
127
|
context.state["Error"] = context.output["Error"]
|
127
128
|
end
|
128
129
|
|
129
|
-
def process_input(input)
|
130
|
-
input = input_path.value(context, input)
|
131
|
-
input = parameters.value(context, input) if parameters
|
132
|
-
input
|
133
|
-
end
|
134
|
-
|
135
130
|
def parse_error(output)
|
136
131
|
return if output.nil?
|
137
132
|
return output if output.kind_of?(Hash)
|
@@ -150,16 +145,6 @@ module Floe
|
|
150
145
|
nil
|
151
146
|
end
|
152
147
|
|
153
|
-
def process_output!(results)
|
154
|
-
output = context.input.dup
|
155
|
-
return output if results.nil?
|
156
|
-
return if output_path.nil?
|
157
|
-
|
158
|
-
results = result_selector.value(context, results) if result_selector
|
159
|
-
output = result_path.set(output, results)
|
160
|
-
output_path.value(context, output)
|
161
|
-
end
|
162
|
-
|
163
148
|
def next_state
|
164
149
|
end? ? nil : @next
|
165
150
|
end
|
data/lib/floe.rb
CHANGED
@@ -25,6 +25,7 @@ require_relative "floe/workflow/runner/podman"
|
|
25
25
|
require_relative "floe/workflow/state"
|
26
26
|
require_relative "floe/workflow/states/choice"
|
27
27
|
require_relative "floe/workflow/states/fail"
|
28
|
+
require_relative "floe/workflow/states/input_output_mixin"
|
28
29
|
require_relative "floe/workflow/states/map"
|
29
30
|
require_relative "floe/workflow/states/non_terminal_mixin"
|
30
31
|
require_relative "floe/workflow/states/parallel"
|
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.7.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-
|
11
|
+
date: 2023-12-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: awesome_spawn
|
@@ -52,20 +52,6 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '4.7'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: more_core_extensions
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :runtime
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
56
|
name: optimist
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -96,6 +82,7 @@ files:
|
|
96
82
|
- Gemfile
|
97
83
|
- README.md
|
98
84
|
- Rakefile
|
85
|
+
- examples/set-credential.asl
|
99
86
|
- examples/workflow.asl
|
100
87
|
- exe/floe
|
101
88
|
- floe.gemspec
|
@@ -123,6 +110,7 @@ files:
|
|
123
110
|
- lib/floe/workflow/state.rb
|
124
111
|
- lib/floe/workflow/states/choice.rb
|
125
112
|
- lib/floe/workflow/states/fail.rb
|
113
|
+
- lib/floe/workflow/states/input_output_mixin.rb
|
126
114
|
- lib/floe/workflow/states/map.rb
|
127
115
|
- lib/floe/workflow/states/non_terminal_mixin.rb
|
128
116
|
- lib/floe/workflow/states/parallel.rb
|