farmstead 0.0.9 → 0.0.11

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3fc5cf26badb4c4d6936bf064c20e64560f6e5ed
4
- data.tar.gz: 4e8778dafcee5bfe2c27aad8be836fc987dc2e55
3
+ metadata.gz: 032071d2a61bf9d506341f24564fe0a2ae808e3e
4
+ data.tar.gz: 406e17d3e1ed534c9160d5f0bda42e0f98234390
5
5
  SHA512:
6
- metadata.gz: 182397b751e55d19c1a9a2fffb3f6f47c9f0ee84ef70807de1275005a165b277b3cec6360569afe1a95ef7a4c5787415fd7b0eb8e23bfde31d7885084bf0ab2c
7
- data.tar.gz: 49ac4a5933d3ef9d7ca016d70cf1a21af3cbbffc25f7da34d2757bfe100a9460ddf487b1e0e65814d1f4d4b510ddbae85d7eb84227dc99300fc97868f0942233
6
+ metadata.gz: 6cdbf29f46a55486b4db5bd64f602a6d5a65df193e36a30b1ae8f4595e516d50aa3f68d20fdc9692ed404b19bc321b66c53472f17022bfabfbfb70d4e5b5a037
7
+ data.tar.gz: 8d6e13d3641de498b9473586334f927fc8133275e7a3cdff53950068ad52f173908042a97ab45ce490cba606fdf8928dc7bb071230030177afefece080cefa7c
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- farmstead (0.0.9)
4
+ farmstead (0.0.11)
5
5
  thor (~> 0.20.0)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![Gem Version](https://badge.fury.io/rb/farmstead.svg)](https://badge.fury.io/rb/farmstead)
4
4
  [![Build Status](https://api.travis-ci.org/mastermindg/farmstead.svg?branch=master)](http://travis-ci.org/mastermindg/farmstead)
5
5
 
6
- Farmstead is a modular data pipeline platform. Farmstead makes creating and deploying a fully-functional data pipeline a snap. It is built on top of Rails/Ruby and uses Docker. This combination allows for a super-fast deployment and prototyping process.
6
+ Farmstead is a modular data pipeline platform. Farmstead makes creating and deploying a fully-functional data pipeline a snap. Farmstead uses containers to encapsulate the middleware which allows for a super-fast deployment and prototyping process.
7
7
 
8
8
 
9
9
  ## Table of Contents
@@ -38,8 +38,6 @@ To create a new Farmstead project:
38
38
 
39
39
  ```
40
40
  farmstead new myproject
41
- cd myproject
42
- farmstead start
43
41
  ```
44
42
 
45
43
  ### Configuration
@@ -60,17 +58,9 @@ An example configuration file is included.
60
58
 
61
59
  #### Configuration Options
62
60
 
63
- **Rails Authentication**
64
-
65
- There is optional Rails Authentication with AUTH0.
66
-
67
- **Rails Environment**
68
-
69
- The default environment is development but can be set to production (if you're ready).
70
-
71
61
  **Database**
72
62
 
73
- The default database is MySQL but can be set to anything that Rails can handle.
63
+ The default database is MySQL but can be set to either MySQL, Postgres, or SQLLite. Extensions will be available
74
64
 
75
65
  **Kafka**
76
66
 
@@ -103,29 +93,33 @@ farmstead new myproject -x kubernetes
103
93
 
104
94
  ## Architecture
105
95
 
106
- Kafka and Database ETL
96
+ Kafka and Database
97
+
98
+ ETL
107
99
 
108
- Presently only Dorothy is running Rails. The rest of the services are only running a Kafka consumer and producer. Eventually that will change.
100
+ * Extract
101
+ * Transform
102
+ * Load
109
103
 
110
- ### Scheduler - Glenda
104
+ All of the services are only running a Kafka consumer and producer. There is a Manager service that
111
105
 
112
- Glenda
106
+ **Classes:**
113
107
 
114
- ### Fertilize - Tinman
108
+ ### Farmstead::Manager
115
109
 
116
- Tinman
110
+ Task scheduling, batch processing, and general flow control. Exposes a very simple web service where you can pull logs and see the data in real-time.
117
111
 
118
- ### Harvest - Scarecrow
112
+ ### Farmstead::Extract
119
113
 
120
- Scarecrow
114
+ Extracts the data from the source.
121
115
 
122
- ### Mill - CowardlyLion
116
+ ### Farmstead::Transform
123
117
 
124
- Cowardlylion
118
+ Transforms one or more datasets.
125
119
 
126
- ### Serve - Dorothy
120
+ ### Farmstead::Load
127
121
 
128
- Dorothy
122
+ Loads the data into a database.
129
123
 
130
124
  ## License
131
125
 
@@ -134,7 +128,6 @@ MIT
134
128
 
135
129
  ## TODO
136
130
 
137
- 1. Find out how to create roles for Dorothy
131
+ 1. Database extensions
138
132
  2. Get Micro-services working
139
- 3. Figure out how to get Selenium working or if it's necessary (Selenium)
140
133
 
@@ -0,0 +1,7 @@
1
+ module MyProject
2
+ class Extracter < Farmstead::Extract
3
+ def hello
4
+ p "hello"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module MyProject
2
+ class Loader < Farmstead::Load
3
+ def hello
4
+ p "hello"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Primary script to kick off services in project
4
+ # Pass two arguments to this script
5
+ # 1st - the class you want to call
6
+ # 2nd - the method you want to call
7
+
8
+ dynamic_class = ARGV[0]
9
+ dynamic_method = ARGV[1]
10
+
11
+ # Extend Farmstead
12
+ require "farmstead"
13
+
14
+ # Load project classes
15
+ require_relative "extract/extracter"
16
+ require_relative "load/loader"
17
+ require_relative "transform/transformer"
18
+
19
+ module MyProject
20
+ include Farmstead
21
+ end
22
+
23
+ klass = Object.const_get "MyProject::#{dynamic_class}"
24
+ service = klass.new
25
+ service.send(dynamic_method)
@@ -0,0 +1,17 @@
1
+ - name: My Project
2
+ database:
3
+ - type: mysql
4
+ - MYSQL_ROOT_PASSWORD: Rc2$NE99p5%^
5
+ - MYSQL_DATABASE: farmstead
6
+ - MYSQL_USER: farmstead
7
+ - MYSQL_PASSWORD: farmstead
8
+ - MYSQL_HOST: mysql
9
+ kafka:
10
+ - advertise_from_local_ip: false
11
+ - advertised_ip: 192.168.1.2
12
+ - zookeeper_address: "zookeeper:2181"
13
+ - topics
14
+ - "Manage:1:1"
15
+ - "Extract:1:1"
16
+ - "Load:1:1"
17
+ - "Transform:1:1"
@@ -0,0 +1,7 @@
1
+ module MyProject
2
+ class Transformer < Farmstead::Transform
3
+ def hello
4
+ p "hello"
5
+ end
6
+ end
7
+ end
data/farmstead.gemspec CHANGED
@@ -20,7 +20,6 @@ Gem::Specification.new do |spec|
20
20
  f.match(%r{^(test|spec|features)/})
21
21
  end
22
22
 
23
- #spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
23
  spec.executables = ['farmstead']
25
24
  spec.require_paths = ["lib"]
26
25
 
data/lib/farmstead/cli.rb CHANGED
@@ -3,10 +3,16 @@ require "thor"
3
3
 
4
4
  module Farmstead
5
5
  class CLI < Thor
6
- class_option :verbose, aliases: "-v", type: "boolean", desc: "Be verbose"
6
+ class_option :verbose, aliases: "--v", type: "boolean", desc: "Be verbose"
7
7
  class_option :config, aliases: "-c", type: "string", desc: "Config file"
8
8
  class_option :database, aliases: "-d", type: "string", desc: "Database"
9
9
  class_option :deploy, aliases: "-x", type: "string", desc: "Deployment Method"
10
+
11
+ desc "version", "Get the gem version"
12
+ def version
13
+ puts "Farmstead #{Farmstead::VERSION}"
14
+ end
15
+
10
16
  desc "new project_name", "Create a new project"
11
17
  def new(project_name)
12
18
  project = Farmstead::Project.new
@@ -53,5 +59,7 @@ module Farmstead
53
59
 
54
60
  # desc "net COMMANDS", "Net control Module"
55
61
  # subcommand "net", Socialinvestigator::CLI::Net
62
+
63
+ map "-v" => "version"
56
64
  end
57
65
  end
@@ -1,5 +1,4 @@
1
- # Glenda - the Scheduler
2
- #
1
+ # Manager
3
2
  #
4
3
  # It works off of the DB when
5
4
  # 1) A new site is added
@@ -27,7 +26,7 @@
27
26
  # HINT: See .env
28
27
  # Every micro-service inherits the Service class
29
28
  module Farmstead
30
- class Glenda < Service
29
+ class Manager < Service
31
30
  # Runs on an infinite loop processing records
32
31
  # on MySQL DB and writing messages accordingly
33
32
  def producer
@@ -97,3 +96,4 @@ module Farmstead
97
96
  end
98
97
  end
99
98
  end
99
+
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Extract data from the source
4
+ #
5
+ # Runs a Consumer and it will automatically pick up
6
+ # messages from the Field Topic and do it's job
7
+ # and then send a message as a Producer to the Forest Topic
8
+ #
9
+ # Every micro-service inherits the Service class
10
+ module Farmstead
11
+ class Extract < Service
12
+ # Picks up JSON generated by WebDriver and save it to Forest topic
13
+ def producer
14
+ loop do
15
+ puts "Do something"
16
+ sleep 300
17
+ end
18
+ end
19
+
20
+ # Subscribed to the Field topic
21
+ # Works on message
22
+ def consumer
23
+ @consumer.subscribe('Field')
24
+ trap('TERM') { @consumer.stop }
25
+ @consumer.each_message do |message|
26
+ puts "Received: #{message.value}"
27
+ magic_work(message.value)
28
+ @consumer.mark_message_as_processed(message)
29
+ end
30
+ end
31
+
32
+ def magic_work(site)
33
+ hash = JSON.parse(site)
34
+ hash['scarecrow'] = 'true'
35
+ json = hash.to_json
36
+ puts "Writing: #{json}"
37
+ write_message(json, topic: 'Forest')
38
+ end
39
+ end
40
+ end
@@ -1,18 +1,18 @@
1
- # Scarecrow - the Harvester
2
- #
3
- # Scarecrow is responsible for extracting data from a source
1
+ # frozen_string_literal: true
2
+
3
+ # Load data into database
4
4
  #
5
- # Scarecrow is running as a Consumer and it will automatically pick up
5
+ # Runs a Consumer and it will automatically pick up
6
6
  # messages from the Field Topic and do it's job
7
7
  # and then send a message as a Producer to the Forest Topic
8
8
  #
9
9
  # Every micro-service inherits the Service class
10
10
  module Farmstead
11
- class Scarecrow < Service
11
+ class Load < Service
12
12
  # Picks up JSON generated by WebDriver and save it to Forest topic
13
13
  def producer
14
14
  loop do
15
- puts 'Do something'
15
+ puts "Do something"
16
16
  sleep 300
17
17
  end
18
18
  end
@@ -36,20 +36,6 @@ module Farmstead
36
36
  puts "Writing: #{json}"
37
37
  write_message(json, topic: 'Forest')
38
38
  end
39
-
40
- # Call the Site Class
41
- def call_class
42
- puts 'this'
43
- end
44
-
45
- def selenium
46
- browser = Watir::Browser.new :chrome
47
- browser.goto 'http://www.stackoverflow.com'
48
- puts browser.title
49
- # browser.text_field(title: 'Search').set 'Hello World!'
50
- # browser.button(type: 'submit').click
51
- # puts browser.title
52
- browser.quit
53
- end
54
39
  end
55
40
  end
41
+
@@ -1,15 +1,17 @@
1
- # CowardlyLion - the Miller
1
+ # frozen_string_literal: true
2
+
3
+ # Transform data
2
4
  #
3
- # Cowardlylion is responsible for arranging data into usable blocks
5
+ # Arrange data into usable blocks
4
6
  #
5
7
  #
6
- # CowardlyLion is running as a Consumer and it will automatically pick up
8
+ # Running as a Consumer and it will automatically pick up
7
9
  # messages from the Forest topic and do it's job and then send
8
10
  # a message as a Producer to the Road topic
9
11
  #
10
12
  # Every micro-service inherits the Service class
11
13
  module Farmstead
12
- class Cowardlylion #< Service
14
+ class Transform < Service
13
15
  # Does nothing...work is handled by magic_work
14
16
  def producer
15
17
  loop do
@@ -0,0 +1,7 @@
1
+ module MyProject
2
+ class Extracter < Farmstead::Extract
3
+ def hello
4
+ p "hello"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module MyProject
2
+ class Loader < Farmstead::Load
3
+ def hello
4
+ p "hello"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Primary script to kick off services in project
4
+ # Pass two arguments to this script
5
+ # 1st - the class you want to call
6
+ # 2nd - the method you want to call
7
+
8
+ dynamic_class = ARGV[0]
9
+ dynamic_method = ARGV[1]
10
+
11
+ # Extend Farmstead
12
+ require "farmstead"
13
+
14
+ # Load project classes
15
+ require_relative "extract/extracter"
16
+ require_relative "load/loader"
17
+ require_relative "transform/transformer"
18
+
19
+ module MyProject
20
+ include Farmstead
21
+ end
22
+
23
+ klass = Object.const_get "MyProject::#{dynamic_class}"
24
+ service = klass.new
25
+ service.send(dynamic_method)
@@ -0,0 +1,17 @@
1
+ - name: My Project
2
+ database:
3
+ - type: mysql
4
+ - MYSQL_ROOT_PASSWORD: Rc2$NE99p5%^
5
+ - MYSQL_DATABASE: farmstead
6
+ - MYSQL_USER: farmstead
7
+ - MYSQL_PASSWORD: farmstead
8
+ - MYSQL_HOST: mysql
9
+ kafka:
10
+ - advertise_from_local_ip: false
11
+ - advertised_ip: 192.168.1.2
12
+ - zookeeper_address: "zookeeper:2181"
13
+ - topics
14
+ - "Manage:1:1"
15
+ - "Extract:1:1"
16
+ - "Load:1:1"
17
+ - "Transform:1:1"
@@ -0,0 +1,7 @@
1
+ module MyProject
2
+ class Transformer < Farmstead::Transform
3
+ def hello
4
+ p "hello"
5
+ end
6
+ end
7
+ end
@@ -1,3 +1,3 @@
1
1
  module Farmstead
2
- VERSION = "0.0.9"
2
+ VERSION = "0.0.11"
3
3
  end
data/lib/farmstead.rb CHANGED
@@ -35,11 +35,10 @@ require "farmstead/version"
35
35
  require "farmstead/project"
36
36
  require "farmstead/cli"
37
37
  require "farmstead/service"
38
- require "farmstead/tinman"
39
- require "farmstead/cowardlylion"
40
- require "farmstead/glenda"
41
- require "farmstead/scarecrow"
42
- require "farmstead/tinman"
38
+ require "farmstead/manager"
39
+ require "farmstead/pipeline/extract"
40
+ require "farmstead/pipeline/transform"
41
+ require "farmstead/pipeline/load"
43
42
 
44
43
  module Farmstead
45
44
  # Your code goes here...
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: farmstead
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ken Jenney
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-31 00:00:00.000000000 Z
11
+ date: 2018-01-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -87,28 +87,33 @@ files:
87
87
  - LICENSE.txt
88
88
  - README.md
89
89
  - Rakefile
90
- - bin/console
91
90
  - bin/farmstead
92
- - bin/setup
93
- - examples/myproject.yml
91
+ - examples/myproject/extract/extracter.rb
92
+ - examples/myproject/load/loader.rb
93
+ - examples/myproject/myproject.rb
94
+ - examples/myproject/myproject.yml
95
+ - examples/myproject/transform/transformer.rb
94
96
  - farmstead.gemspec
95
97
  - lib/farmstead.rb
96
98
  - lib/farmstead/cli.rb
97
- - lib/farmstead/cowardlylion.rb
98
- - lib/farmstead/glenda.rb
99
+ - lib/farmstead/manager.rb
100
+ - lib/farmstead/pipeline/extract.rb
101
+ - lib/farmstead/pipeline/load.rb
102
+ - lib/farmstead/pipeline/transform.rb
99
103
  - lib/farmstead/project.rb
100
104
  - lib/farmstead/scaffold/.dockerignore.erb
101
105
  - lib/farmstead/scaffold/.env.erb
102
- - lib/farmstead/scaffold/Dockerfile-dorothy.erb
103
106
  - lib/farmstead/scaffold/Dockerfile.erb
104
107
  - lib/farmstead/scaffold/Gemfile.erb
105
- - lib/farmstead/scaffold/app/controllers/application_controller.rb.erb
106
108
  - lib/farmstead/scaffold/docker-compose.yml.erb
107
109
  - lib/farmstead/scaffold/exec.sh.erb
110
+ - lib/farmstead/scaffold/extract/extracter.rb.erb
111
+ - lib/farmstead/scaffold/load/loader.rb
112
+ - lib/farmstead/scaffold/project.rb.erb
113
+ - lib/farmstead/scaffold/project.yml.erb
108
114
  - lib/farmstead/scaffold/supervisord.conf.erb
109
- - lib/farmstead/scarecrow.rb
115
+ - lib/farmstead/scaffold/transform/transformer.rb
110
116
  - lib/farmstead/service.rb
111
- - lib/farmstead/tinman.rb
112
117
  - lib/farmstead/version.rb
113
118
  homepage: https://github.com/mastermindg/farmstead
114
119
  licenses:
data/bin/console DELETED
@@ -1,18 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "farmstead"
5
-
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- # require "irb"
14
- # IRB.start(__FILE__)
15
-
16
- require "farmstead"
17
-
18
- Farmstead::CLI.start(ARGV)
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here
@@ -1,26 +0,0 @@
1
- - name: My Project
2
- rails:
3
- - authentication:
4
- - enable: true
5
- - AUTH0_CLIENT_ID: myclientid
6
- - AUTH0_CLIENT_SECRET: myclientsecret
7
- - AUTH0_DOMAIN: myauth0domain
8
- - AUTH0_DOMAIN: http://localhost:3000/auth/auth0/callback
9
- - AUTH0_AUDIENCE:
10
- - environment: development
11
- database:
12
- - type: mysql
13
- - MYSQL_ROOT_PASSWORD: Rc2$NE99p5%^
14
- - MYSQL_DATABASE: farmstead
15
- - MYSQL_USER: farmstead
16
- - MYSQL_PASSWORD: farmstead
17
- - MYSQL_HOST: mysql
18
- kafka:
19
- - advertise_from_local_ip: false
20
- - advertised_ip: 192.168.1.2
21
- - zookeeper_address: "zookeeper:2181"
22
- - topics
23
- - "Wood:1:1"
24
- - "Field:1:1"
25
- - "Forest:1:1"
26
- - "Road:1:1"
@@ -1,24 +0,0 @@
1
- FROM ruby:2.4.1
2
-
3
- RUN apt-get update -qq && \
4
- apt-get install -y build-essential \
5
- libpq-dev \
6
- nodejs \
7
- telnet \
8
- bash \
9
- supervisor \
10
- vim \
11
- xterm \
12
- ca-certificates \
13
- unzip && \
14
- rm -rf /var/cache/apk/*
15
-
16
- ## Setup Rails
17
-
18
- RUN gem install rails && rails new <%= @name %> <% if @database %>-d <%= @database %><% end %>
19
- WORKDIR /<%= @name %>
20
- ADD app/* /<%= @name %>/app
21
-
22
- EXPOSE 3000
23
-
24
- CMD /<%= @name %>/bin/rails s -b 0.0.0.0
@@ -1,6 +0,0 @@
1
- class ApplicationController < ActionController::Base
2
- # Prevent CSRF attacks by raising an exception.
3
- # For APIs, you may want to use :null_session instead.
4
- protect_from_forgery with: :exception
5
- end
6
-
@@ -1,49 +0,0 @@
1
- # Tinman - the Fertilizer
2
- #
3
- # Tinman is responsible for analyzing a site for changes
4
- # and updating site configs
5
- #
6
- # None of the logic has actually been built and
7
- # this may require some AI but for now it's
8
- # just responding that everything is OK
9
- #
10
- # Tinman is running as a Consumer to the Wood topic and it will automatically
11
- # pick up the message, do it's job and then send a message
12
- # as a Producer to the Field topic
13
- #
14
- # Every micro-service inherits the Service class
15
- module Farmstead
16
- class Tinman < Service
17
- # Doing nothing...for now
18
- # thi is handled by magic_work
19
- def producer
20
- loop do
21
- puts 'Doing nothing'
22
- sleep 300
23
- end
24
- end
25
-
26
- # Subscribed to the Wood topic
27
- # Works on message
28
- def consumer
29
- @consumer.subscribe('Wood')
30
- trap('TERM') { @consumer.stop }
31
- @consumer.each_message do |message|
32
- puts "Received: #{message.value}"
33
- magic_work(message.value)
34
- @consumer.mark_message_as_processed(message)
35
- end
36
- end
37
-
38
- # Do the magic work to determine if the site has changed
39
- # and update the config
40
- # Returns JSON String
41
- def magic_work(site)
42
- hash = JSON.parse(site)
43
- hash['tinman'] = 'true'
44
- json = hash.to_json
45
- puts "Writing: #{json}"
46
- write_message(json, topic: 'Field')
47
- end
48
- end
49
- end