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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ad8fec2f632914594254c32b7871eb8a4f23f3dfd2263ef5fe0875d0cccce8fa
4
- data.tar.gz: 7e12b5a1a197dc44a7c7bd1b1581891a56908e7ae26836d5e26b73eb41c2a3ae
3
+ metadata.gz: f2791bb2351fad37f210264d51e059b780937e42a5cb1ab2c9c157ac01e18eea
4
+ data.tar.gz: 37436eb4095fc92c4ec4d07e84a09fd27a5b3e794faea09d5ebd37383f886830
5
5
  SHA512:
6
- metadata.gz: 0b02c0ff479ff69433994732d6f3371c2a3e27fa36a094d5dea8340798f249015319821de30ad61334bc2bd9a6b25fb1791dfb0b023e7d0097472f35b93279a7
7
- data.tar.gz: 49b6adb80c1910c9d006d41418e1741e8c62510633507583d2b34dc526a0ce4b73bb1faaa83b7950f0e1d31cbb9b37bd3e4b566bd2c374c824390a840e2e2519
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.2.2...HEAD
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Floe
4
- VERSION = "0.2.2"
4
+ VERSION = "0.3.0"
5
5
  end
@@ -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
- val = interpolate_value_nested(val, context, inputs)
25
- key = key.gsub(/\.\$$/, "") if key.end_with?(".$")
26
-
27
- [key, val]
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 = ["run", :rm, [:net, "host"]]
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 = ["run", :rm]
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
@@ -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
@@ -23,6 +23,14 @@ module Floe
23
23
 
24
24
  [next_state, output]
25
25
  end
26
+
27
+ def status
28
+ "running"
29
+ end
30
+
31
+ def end?
32
+ false
33
+ end
26
34
  end
27
35
  end
28
36
  end
@@ -11,7 +11,6 @@ module Floe
11
11
 
12
12
  @cause = payload["Cause"]
13
13
  @error = payload["Error"]
14
- @end = true
15
14
  end
16
15
 
17
16
  def run!(input)
@@ -21,6 +20,10 @@ module Floe
21
20
  def status
22
21
  "errored"
23
22
  end
23
+
24
+ def end?
25
+ true
26
+ end
24
27
  end
25
28
  end
26
29
  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
@@ -8,13 +8,19 @@ module Floe
8
8
 
9
9
  def initialize(workflow, name, payload)
10
10
  super
11
-
12
- @end = true
13
11
  end
14
12
 
15
13
  def run!(input)
16
14
  [nil, input]
17
15
  end
16
+
17
+ def status
18
+ "success"
19
+ end
20
+
21
+ def end?
22
+ true
23
+ end
18
24
  end
19
25
  end
20
26
  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
- current_state_name = context.state["Name"] || start_at
33
- @current_state = @states_by_name[current_state_name]
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
- input = context.state["Output"] || context.execution["Input"].dup
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 [#{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!(input)
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 [#{input}]...Complete - next state: [#{next_state}] output: [#{output}]")
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.2.2
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-24 00:00:00.000000000 Z
11
+ date: 2023-08-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: awesome_spawn