factor 0.6.3 → 0.6.4

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
  SHA1:
3
- metadata.gz: e28a2f08cdba9af411b81e73a76fb45e636a29a6
4
- data.tar.gz: 1713d9bf5e5ec9fc52bfd9d676b9889e4397528c
3
+ metadata.gz: 26eb148636a08597d3d15057a3536d5b1780f9c8
4
+ data.tar.gz: 87b420da894fa98fd2f9e151982a63008ea452cd
5
5
  SHA512:
6
- metadata.gz: fd78594288d0f1f86e07fd92d3207c429f09a0df1867601d9d8efa709360a7309411bd550bce7f2691ff8e79cbbefb0e5ec6640b0445868eae2727ac26bbec44
7
- data.tar.gz: 674bb6adeb7232d7988a7538547bdb9f0fe481361d7048184ba0f4788794a72d8cd50b766305111729ecf1e9849ffab51579bb7ad5eff7441ae129296fa40a9a
6
+ metadata.gz: 90c063260db5e9fc933991d4bedfb17b52c52e1908f5fbb0a1ab53fd5acfbf03eca4027947b99c854aea968fbfd732f7db69d3d1096c2fe6783be2a37e665d37
7
+ data.tar.gz: fb996d555b5542c5dda46e198e2fb84cf8a642308843a4d4edaa2946f4985e3ff68b5058b4fa495c952fc18a832acddc47f04406b469415bce1536002278bb58
data/bin/factor CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
  # -*- mode: ruby -*-
3
3
 
4
- require File.expand_path('../../lib/factor', __FILE__)
4
+ require File.expand_path('../../lib/commands', __FILE__)
@@ -3,8 +3,8 @@
3
3
  require 'commander/import'
4
4
 
5
5
  require 'factor/version'
6
- require 'commands/workflows'
7
- require 'commands/registry'
6
+ require 'commands/workflow_command'
7
+ require 'commands/registry_command'
8
8
 
9
9
  program :name, 'Factor.io Server'
10
10
  program :version, Factor::VERSION
@@ -17,20 +17,20 @@ command 'server' do |c|
17
17
  c.option '--credentials FILE', String, 'credentials.yml file path.'
18
18
  c.option '--connectors FILE', String, 'connectors.yml file path'
19
19
  c.option '--path FILE', String, 'Path to workflows'
20
- c.when_called Factor::Commands::Workflow, :server
20
+ c.when_called Factor::Commands::WorkflowCommand, :server
21
21
  end
22
22
 
23
23
  command 'cloud' do |c|
24
24
  c.syntax = 'factor host <account id> <workflow id> <api key>'
25
25
  c.description = 'Start the Factor.io Server using your workflows and credentials from Factor.io Cloud'
26
26
  c.option '--host URL', String, 'Use non-default Cloud service provider (e.g. pro server)'
27
- c.when_called Factor::Commands::Workflow, :cloud
27
+ c.when_called Factor::Commands::WorkflowCommand, :cloud
28
28
  end
29
29
 
30
30
  command 'registry workflows' do |c|
31
31
  c.syntax = 'factor registry workflows'
32
32
  c.description = 'Get list of available workflow jumpstarts'
33
- c.when_called Factor::Commands::Registry, :workflows
33
+ c.when_called Factor::Commands::RegistryCommand, :workflows
34
34
  end
35
35
 
36
36
  command 'registry workflows add' do |c|
@@ -39,13 +39,13 @@ command 'registry workflows add' do |c|
39
39
  c.option '--credentials FILE', String, 'credentials.yml file path.'
40
40
  c.option '--connectors FILE', String, 'connectors.yml file path'
41
41
  c.option '--values \'{"api_key":"foo"}\'', String, "{}"
42
- c.when_called Factor::Commands::Registry, :add_workflow
42
+ c.when_called Factor::Commands::RegistryCommand, :add_workflow
43
43
  end
44
44
 
45
45
  command 'registry connectors' do |c|
46
46
  c.syntax = 'factor registry connectors'
47
47
  c.description = 'Get list of available connectors'
48
- c.when_called Factor::Commands::Registry, :connectors
48
+ c.when_called Factor::Commands::RegistryCommand, :connectors
49
49
  end
50
50
 
51
51
  command 'registry connector add' do |c|
@@ -54,7 +54,7 @@ command 'registry connector add' do |c|
54
54
  c.option '--credentials FILE', String, 'credentials.yml file path.'
55
55
  c.option '--connectors FILE', String, 'connectors.yml file path'
56
56
  c.option '--values \'{"api_key":"foo"}\'', String, "{}"
57
- c.when_called Factor::Commands::Registry, :add_connector
57
+ c.when_called Factor::Commands::RegistryCommand, :add_connector
58
58
  end
59
59
 
60
60
  alias_command 's', 'server'
data/lib/commands/base.rb CHANGED
@@ -4,40 +4,21 @@ require 'colored'
4
4
  require 'configatron'
5
5
  require 'yaml'
6
6
  require 'fileutils'
7
+ require 'logger/basic'
7
8
 
8
9
  module Factor
9
10
  module Commands
10
11
  # Base command with common methods used by all commands
11
12
  class Command
13
+ attr_accessor :logger
14
+
12
15
  DEFAULT_FILENAME = {
13
16
  connectors: File.expand_path('./connectors.yml'),
14
17
  credentials: File.expand_path('./credentials.yml')
15
18
  }
16
19
 
17
- attr_accessor :destination_stream
18
-
19
- def info(options = {})
20
- log_line :info, options
21
- end
22
-
23
- def error(options = {})
24
- log_line :error, options
25
- end
26
-
27
- def warn(options = {})
28
- log_line :warn, options
29
- end
30
-
31
- def success(options = {})
32
- log_line :success, options
33
- end
34
-
35
- def exception(message, exception)
36
- error 'message' => message
37
- error 'message' => " #{exception.message}"
38
- exception.backtrace.each do |line|
39
- error 'message' => " #{line}"
40
- end
20
+ def initialize
21
+ @logger = Factor::Log::BasicLogger.new
41
22
  end
42
23
 
43
24
  def load_config(options = {})
@@ -77,46 +58,7 @@ module Factor
77
58
  end
78
59
  configatron[config_type].configure_from_hash(data)
79
60
  rescue => ex
80
- exception "Couldn't load #{config_type} from #{absolute_path}", ex
81
- end
82
-
83
- def log_line(section, options = {})
84
- options = { message: options } if options.is_a?(String)
85
- tag = tag(options)
86
- message = options['message'] || options[:message]
87
- section_text = format_section(section)
88
- write "[ #{section_text} ] [#{time}]#{tag} #{message}" if message
89
- end
90
-
91
- def format_section(section)
92
- formated_section = section.to_s.upcase.center(10)
93
- case section
94
- when :error then formated_section.red
95
- when :info then formated_section.bold
96
- when :warn then formated_section.yellow
97
- when :success then formated_section.green
98
- else formated_section
99
- end
100
- end
101
-
102
- def tag(options)
103
- primary = options['service_id'] || options['instance_id']
104
- secondary = if options['service_id'] && options['instance_id']
105
- ":#{options['instane_id']}"
106
- else
107
- ''
108
- end
109
- primary ? "[#{primary}#{secondary}]" : ''
110
- end
111
-
112
- def time
113
- Time.now.localtime.strftime('%m/%d/%y %T.%L')
114
- end
115
-
116
- def write(message)
117
- stream = @destination_stream || $stdout
118
- stream.puts(message)
119
- stream.flush
61
+ logger.error "Couldn't load #{config_type} from #{absolute_path}", exception:ex
120
62
  end
121
63
  end
122
64
  end
@@ -10,7 +10,7 @@ require 'commands/base'
10
10
  module Factor
11
11
  module Commands
12
12
  # Workflow is a Command to start the factor runtime from the CLI
13
- class Registry < Factor::Commands::Command
13
+ class RegistryCommand < Factor::Commands::Command
14
14
 
15
15
  def workflows(args, options)
16
16
  list = get_yaml_data 'https://raw.githubusercontent.com/factor-io/index/master/workflows.yml'
@@ -3,14 +3,15 @@
3
3
  require 'configatron'
4
4
 
5
5
  require 'commands/base'
6
- require 'runtime'
6
+ require 'runtime/workflow'
7
7
 
8
8
  module Factor
9
9
  module Commands
10
10
  # Workflow is a Command to start the factor runtime from the CLI
11
- class Workflow < Factor::Commands::Command
11
+ class WorkflowCommand < Factor::Commands::Command
12
12
  def initialize
13
13
  @workflows = {}
14
+ super
14
15
  end
15
16
 
16
17
  def server(_args, options)
@@ -23,7 +24,7 @@ module Factor
23
24
  load_config(config_settings)
24
25
  load_all_workflows(workflow_filename)
25
26
  block_until_interupt
26
- info 'Good bye!'
27
+ logger.info 'Good bye!'
27
28
  end
28
29
 
29
30
  def cloud(args, options)
@@ -31,35 +32,35 @@ module Factor
31
32
  host = (options.host || "https://factor.io").sub(/(\/)+$/,'')
32
33
 
33
34
  if !api_key || !workflow_id || !account_id
34
- error "API Key, Worklfow ID and Acount ID are all required"
35
+ logger.error "API Key, Worklfow ID and Acount ID are all required"
35
36
  exit
36
37
  end
37
38
 
38
- info "Getting workflow (#{workflow_id}) from Factor.io Cloud"
39
+ logger.info "Getting workflow (#{workflow_id}) from Factor.io Cloud"
39
40
  begin
40
41
  workflow_url = "#{host}/#{account_id}/workflows/#{workflow_id}.json?auth_token=#{api_key}"
41
42
  raw_content = RestClient.get(workflow_url)
42
43
  workflow_info = JSON.parse(raw_content)
43
44
  rescue => ex
44
- error "Couldn't retreive workflow: #{ex.message}"
45
+ logger.error "Couldn't retreive workflow: #{ex.message}"
45
46
  exit
46
47
  end
47
48
 
48
49
  workflow_definition = workflow_info["definition"]
49
50
 
50
- info "Getting credentials from Factor.io Cloud"
51
+ logger.info "Getting credentials from Factor.io Cloud"
51
52
  begin
52
53
  credential_url = "#{host}/#{account_id}/credentials.json?auth_token=#{api_key}"
53
54
  raw_content = RestClient.get(credential_url)
54
55
  credentials = JSON.parse(raw_content)
55
56
  rescue => ex
56
- error "Couldn't retreive workflow: #{ex.message}"
57
+ logger.error "Couldn't retreive workflow: #{ex.message}"
57
58
  exit
58
59
  end
59
60
 
60
61
  configatron[:credentials].configure_from_hash(credentials)
61
62
 
62
- info "Getting connectors from Factor.io Cloud"
63
+ logger.info "Getting connectors from Factor.io Cloud"
63
64
  connectors = {}
64
65
  begin
65
66
  connectors_url = "#{host}/#{account_id}/connectors.json?auth_token=#{api_key}"
@@ -70,7 +71,7 @@ module Factor
70
71
  connectors[connector_id] = connector_info['connectors'].values.first
71
72
  end
72
73
  rescue => ex
73
- error "Couldn't retreive workflow: #{ex.message}"
74
+ logger.error "Couldn't retreive workflow: #{ex.message}"
74
75
  exit
75
76
  end
76
77
 
@@ -80,7 +81,7 @@ module Factor
80
81
 
81
82
  block_until_interupt
82
83
 
83
- info 'Good bye!'
84
+ logger.info 'Good bye!'
84
85
  end
85
86
 
86
87
  private
@@ -90,22 +91,22 @@ module Factor
90
91
  glob = "#{workflow_filename}#{glob_ending}*.rb"
91
92
  file_list = Dir.glob(glob)
92
93
  if !file_list.all? { |file| File.file?(file) }
93
- error "#{workflow_filename} is neither a file or directory"
94
+ logger.error "#{workflow_filename} is neither a file or directory"
94
95
  elsif file_list.count == 0
95
- error 'No workflows in this directory to run'
96
+ logger.error 'No workflows in this directory to run'
96
97
  else
97
98
  file_list.each { |filename| load_workflow(File.expand_path(filename)) }
98
99
  end
99
100
  end
100
101
 
101
102
  def block_until_interupt
102
- info 'Ctrl-c to exit'
103
+ logger.info 'Ctrl-c to exit'
103
104
  begin
104
105
  loop do
105
106
  sleep 1
106
107
  end
107
108
  rescue Interrupt
108
- info 'Exiting app...'
109
+ logger.info 'Exiting app...'
109
110
  ensure
110
111
  @workflows.keys.each { |workflow_id| unload_workflow(workflow_id) }
111
112
  end
@@ -113,11 +114,11 @@ module Factor
113
114
 
114
115
  def load_workflow(workflow_filename)
115
116
  # workflow_filename = File.expand_path(filename)
116
- info "Loading workflow from #{workflow_filename}"
117
+ logger.info "Loading workflow from #{workflow_filename}"
117
118
  begin
118
119
  workflow_definition = File.read(workflow_filename)
119
120
  rescue => ex
120
- exception "Couldn't read file #{workflow_filename}", ex
121
+ logger.error "Couldn't read file #{workflow_filename}", exception:ex
121
122
  return
122
123
  end
123
124
 
@@ -125,23 +126,22 @@ module Factor
125
126
  end
126
127
 
127
128
  def load_workflow_from_definition(workflow_definition)
128
- info "Setting up workflow processor"
129
+ logger.info "Setting up workflow processor"
129
130
  begin
130
131
  connector_settings = configatron.connectors.to_hash
131
132
  credential_settings = configatron.credentials.to_hash
132
- runtime = Runtime.new(connector_settings, credential_settings)
133
- runtime.logger = method(:log_message)
133
+ runtime = Factor::Runtime::Workflow.new(connector_settings, credential_settings, logger: logger)
134
134
  rescue => ex
135
- message = "Couldn't setup workflow process for #{workflow_filename}"
136
- exception message, ex
135
+ message = "Couldn't setup workflow process"
136
+ logger.error message:message, exception:ex
137
137
  end
138
138
 
139
139
  workflow_thread = fork do
140
140
  begin
141
- info "Starting workflow"
141
+ logger.info "Starting workflow"
142
142
  runtime.load(workflow_definition)
143
143
  rescue => ex
144
- exception "Couldn't workflow", ex
144
+ logger.error message: "Couldn't workflow", exception: ex
145
145
  end
146
146
  end
147
147
 
@@ -149,18 +149,9 @@ module Factor
149
149
  end
150
150
 
151
151
  def unload_workflow(workflow_id)
152
- info "Stopping #{workflow_id}"
152
+ logger.info "Stopping #{workflow_id}"
153
153
  Process.kill('SIGINT', @workflows[workflow_id])
154
154
  end
155
-
156
- def log_message(message_info)
157
- case message_info['status']
158
- when 'info' then info message_info
159
- when 'success' then success message_info
160
- when 'warn' then warn message_info
161
- else error message_info
162
- end
163
- end
164
155
  end
165
156
  end
166
157
  end
@@ -0,0 +1,48 @@
1
+ require 'ostruct'
2
+
3
+ module Factor
4
+ module Common
5
+ class DeepStruct < OpenStruct
6
+ def initialize(hash=nil)
7
+ @table = {}
8
+ @hash_table = {}
9
+
10
+ if hash
11
+ hash.each do |k,v|
12
+ @table[k.to_sym] = (v.is_a?(Hash) ? self.class.new(v) : v)
13
+ @hash_table[k.to_sym] = v
14
+
15
+ new_ostruct_member(k)
16
+ end
17
+ end
18
+ end
19
+
20
+ def to_h
21
+ @hash_table
22
+ end
23
+
24
+ def [](idx)
25
+ hash = marshal_dump
26
+ hash[idx.to_sym]
27
+ end
28
+ end
29
+
30
+ def self.flat_hash(h,f=[],g={})
31
+ return g.update({ f=>h }) unless h.is_a? Hash
32
+ h.each { |k,r| flat_hash(r,f+[k],g) }
33
+ g
34
+ end
35
+
36
+ def self.simple_object_convert(item)
37
+ if item.is_a?(Hash)
38
+ Factor::Common::DeepStruct.new(item)
39
+ elsif item.is_a?(Array)
40
+ item.map do |i|
41
+ simple_object_convert(i)
42
+ end
43
+ else
44
+ item
45
+ end
46
+ end
47
+ end
48
+ end
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Primary Factor.io module
4
4
  module Factor
5
- VERSION = '0.6.3'
5
+ VERSION = '0.6.4'
6
6
  end
@@ -0,0 +1,68 @@
1
+ require_relative './logger.rb'
2
+
3
+ module Factor
4
+ module Log
5
+ class BasicLogger < Factor::Log::Logger
6
+
7
+ attr_accessor :destination_stream
8
+
9
+ def log(section, options={})
10
+ options = { message: options } if options.is_a?(String)
11
+ tag = tag(options)
12
+ message = options['message'] || options[:message]
13
+ section_text = format_section(section)
14
+ write "[ #{section_text} ] [#{time}]#{tag} #{message}" if message
15
+ exception options[:exception] if options[:exception]
16
+ end
17
+
18
+ def info(options = {})
19
+ log :info, options
20
+ end
21
+
22
+ def warn(options = {})
23
+ log :warn, options
24
+ end
25
+
26
+ def error(options = {})
27
+ log :error, options
28
+ end
29
+
30
+ def success(options = {})
31
+ log :success, options
32
+ end
33
+
34
+ private
35
+
36
+ def exception(exception)
37
+ error message: " #{exception.message}"
38
+ exception.backtrace.each do |line|
39
+ error message: " #{line}"
40
+ end
41
+ end
42
+
43
+ def format_section(section)
44
+ formated_section = section.to_s.upcase.center(10)
45
+ case section.to_sym
46
+ when :error then formated_section.red
47
+ when :info then formated_section.bold
48
+ when :warn then formated_section.yellow
49
+ when :success then formated_section.green
50
+ else formated_section
51
+ end
52
+ end
53
+
54
+ def tag(options)
55
+ primary = options['service_id'] || options['instance_id']
56
+ secondary = ":#{options['instane_id']}" if options['service_id'] && options['instance_id']
57
+ primary ? "[#{primary}#{secondary || ''}]" : ''
58
+ end
59
+
60
+ def write(message)
61
+ stream = @destination_stream || $stdout
62
+ stream.puts(message)
63
+ stream.flush
64
+ end
65
+
66
+ end
67
+ end
68
+ end