floe 0.6.1 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b92b3c488e49ea77447b370e9152c49e11036e8295c6a781feda666662927f9e
4
- data.tar.gz: c553deab6491c9876e28a816cb2422a1318ac6f91a9f9f75cbfc5a144a84d248
3
+ metadata.gz: 88cfa362fcb949aeaa6e9b0b799bff4bbb0e6b7158c95920545300ba063d6a0d
4
+ data.tar.gz: 14df3cddf7a1811e945f533b88fcacd6611566e212cacb88bebf2da0bae9fe67
5
5
  SHA512:
6
- metadata.gz: 3f5c210d2a745aaed8e3419e228465203dcebb02ee678c1d2b47285083e1f154118c25864e51360d3d062ca0cfade9baa84f5a932804b586f26607a195acc710
7
- data.tar.gz: 238fd469915e8682c449abd26e1950f68fd4b032a32fcace11130109d46dc6962b29e4ce381734d167f5328ef16ee2fdd4bb250f844644abebc571fc001ab2dd
6
+ metadata.gz: 90a3cdfdb241242d5b52ad403e7bbbf409476efec6d01d16f8f6f223b6f5fa3e227647da98ab2fb9466993982793be32684521ca5a268e73ab191ff7b6a025fb
7
+ data.tar.gz: c1194b741493a3db2f3abdf083ef2858b25af61442584c6a2001d222579c78e5057f0a7efd3c6c904e02d898c296f543c5af1889c2e4bb91c95f9197d327fa35
data/CHANGELOG.md CHANGED
@@ -4,6 +4,18 @@ This project adheres to [Semantic Versioning](http://semver.org/).
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.7.1] - 2024-01-17
8
+ ### Fixed
9
+ - Ensure that workflow credentials is not-nil ([#156](https://github.com/ManageIQ/floe/pull/156))
10
+
11
+ ## [0.7.0] - 2023-12-18
12
+ ### Changed
13
+ - Remove the dependency on more_core_extensions in ReferencePath ([#144](https://github.com/ManageIQ/floe/pull/144))
14
+
15
+ ### Added
16
+ - Implement `ReferencePath#get` ([#144](https://github.com/ManageIQ/floe/pull/144))
17
+ - Allow a State to set a value in Credentials for subsequent states ([#145](https://github.com/ManageIQ/floe/pull/145))
18
+
7
19
  ## [0.6.1] - 2023-11-21
8
20
  ### Fixed
9
21
  - Return an error payload if run_async! fails ([#143](https://github.com/ManageIQ/floe/pull/143))
@@ -106,7 +118,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
106
118
  ### Added
107
119
  - Initial release
108
120
 
109
- [Unreleased]: https://github.com/ManageIQ/floe/compare/v0.6.1...HEAD
121
+ [Unreleased]: https://github.com/ManageIQ/floe/compare/v0.7.1...HEAD
122
+ [0.7.1]: https://github.com/ManageIQ/floe/compare/v0.7.0...v0.7.1
123
+ [0.7.0]: https://github.com/ManageIQ/floe/compare/v0.6.1...v0.7.0
110
124
  [0.6.1]: https://github.com/ManageIQ/floe/compare/v0.6.0...v0.6.1
111
125
  [0.6.0]: https://github.com/ManageIQ/floe/compare/v0.5.0...v0.6.0
112
126
  [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
@@ -32,6 +32,5 @@ Gem::Specification.new do |spec|
32
32
  spec.add_dependency "awesome_spawn", "~>1.0"
33
33
  spec.add_dependency "jsonpath", "~>1.1"
34
34
  spec.add_dependency "kubeclient", "~>4.7"
35
- spec.add_dependency "more_core_extensions"
36
35
  spec.add_dependency "optimist", "~>3.0"
37
36
  end
data/lib/floe/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Floe
4
- VERSION = "0.6.1".freeze
4
+ VERSION = "0.7.1".freeze
5
5
  end
@@ -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
- def initialize(*)
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 use store path to set the value to a sub-key
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.store_path(path, value)
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!(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/workflow.rb CHANGED
@@ -44,7 +44,7 @@ module Floe
44
44
 
45
45
  @payload = payload
46
46
  @context = context
47
- @credentials = credentials
47
+ @credentials = credentials || {}
48
48
  @start_at = payload["StartAt"]
49
49
 
50
50
  @states = payload["States"].to_a.map { |name, state| State.build!(self, name, state) }
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.6.1
4
+ version: 0.7.1
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-21 00:00:00.000000000 Z
11
+ date: 2024-01-17 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