nex_client 0.1.0 → 0.2.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
  SHA1:
3
- metadata.gz: c4ae6ccb86acd03a0fbf4e551551c6ebbe38ebea
4
- data.tar.gz: 6eba8f471e9caefbf1d31907ffe084dcc69ebd4e
3
+ metadata.gz: eaf3b1116d1276f01639f77b71218bb6423c7be0
4
+ data.tar.gz: 3d5abdcc04437acd20d48c797909d3b5d30d7c04
5
5
  SHA512:
6
- metadata.gz: 4cc2d45e22cb810575f8aea00d767839ce67a605f1692692a943e12614cd8287495f5e5d9c25377d70db0455fb3373336df0fecfe5937fade08a76f82940d70e
7
- data.tar.gz: 80dbd8e444186e1ddb630e3e0a2fbf602c491baf6cfe1e43b3c7a858059d4e2bd09b498055c8adc87f7b29a18673dc37ff887f4a2c3ac53fa6170fc59ffe00a7
6
+ metadata.gz: 39cf5913237a6a192c3117737c3970f63d153bea86f7d474fe1f5cbbb429647b8c88ff377d27fa6f10c15114349a7da5c8ab94191921556a26102f5dbcc7dd5a
7
+ data.tar.gz: f16059882c2d143616ad268737a1ba2987a380b8c9e1d5683acbe5ed8f3fa098397509173a42e9e70a5f79fb8b38a75e3247574c0cd1f97e311618f5ff827935
@@ -3,5 +3,8 @@ module NexClient
3
3
  class Addon < BaseResource
4
4
  property :created_at, type: :time
5
5
  property :updated_at, type: :time
6
+
7
+ # GET <api_root>/apps/:id/logs
8
+ custom_endpoint :logs, on: :member, request_method: :get
6
9
  end
7
10
  end
@@ -20,5 +20,8 @@ module NexClient
20
20
 
21
21
  # PATCH <api_root>/apps/:id/unlink_scm
22
22
  custom_endpoint :unlink_scm, on: :member, request_method: :patch
23
+
24
+ # GET <api_root>/apps/:id/logs
25
+ custom_endpoint :logs, on: :member, request_method: :get
23
26
  end
24
27
  end
@@ -3,6 +3,7 @@ module NexClient
3
3
  class BaseResource < JsonApiClient::Resource
4
4
  API_HOST = {
5
5
  'development' => 'http://localhost:5000',
6
+ 'test' => 'http://nex-test.com',
6
7
  'uat' => 'https://api-nex-uat.maestrano.io',
7
8
  'production' => 'https://api-nex.maestrano.com',
8
9
  }
@@ -51,6 +51,18 @@ module NexClient
51
51
  end
52
52
  end
53
53
 
54
+ command :'addons:logs' do |c|
55
+ c.syntax = 'nex-cli addons:logs APP_NAME [options]'
56
+ c.summary = 'Gather addon logs'
57
+ c.description = 'Gather container logs for a given addon'
58
+ c.example 'gather logs for myaddon', 'nex-cli addons:logs myaddon'
59
+ c.example 'gather logs for myapp with a tail of 50', 'nex-cli addons:logs --tail 50 myaddon'
60
+ c.option '--tail NUMBER', String, 'number of lines to retrieve for each container'
61
+ c.action do |args, options|
62
+ NexClient::Commands::Addons.logs(args,options)
63
+ end
64
+ end
65
+
54
66
  command :apps do |c|
55
67
  c.syntax = 'nex-cli apps [options]'
56
68
  c.summary = 'Manage apps'
@@ -116,6 +128,18 @@ module NexClient
116
128
  end
117
129
  end
118
130
 
131
+ command :'apps:logs' do |c|
132
+ c.syntax = 'nex-cli apps:logs APP_NAME [options]'
133
+ c.summary = 'Gather app logs'
134
+ c.description = 'Gather container logs for a given app'
135
+ c.example 'gather logs for myapp', 'nex-cli apps:logs myapp'
136
+ c.example 'gather logs for myapp with a tail of 50', 'nex-cli apps:logs --tail 50 myapp'
137
+ c.option '--tail NUMBER', String, 'number of lines to retrieve for each container'
138
+ c.action do |args, options|
139
+ NexClient::Commands::Apps.logs(args,options)
140
+ end
141
+ end
142
+
119
143
  command :'apps:restart' do |c|
120
144
  c.syntax = 'nex-cli apps:restart APP_NAME'
121
145
  c.summary = 'Restart an app'
@@ -23,6 +23,21 @@ module NexClient
23
23
  self.display_addons(list)
24
24
  end
25
25
 
26
+ def self.logs(args,opts)
27
+ name = args.first
28
+ e = NexClient::Addon.find(name: name).first
29
+
30
+ # Display error
31
+ unless e
32
+ error("Error! Could not find addon: #{name}")
33
+ return false
34
+ end
35
+
36
+ # Retrieve logs and display them
37
+ logs = e.logs(tail: opts.tail).first
38
+ self.display_logs(logs.log_ret)
39
+ end
40
+
26
41
  def self.create(args,opts)
27
42
  svc_name,app_name = args
28
43
  app = NexClient::App.find(name: app_name).first
@@ -4,7 +4,7 @@ module NexClient
4
4
  module Commands
5
5
  module Apps
6
6
  extend Helpers
7
-
7
+
8
8
  SCALING_DIRECTIONS = [:up,:down]
9
9
  APPS_TITLE = "App Details".colorize(:green)
10
10
  APPS_HEADERS = ['id','name','status','image','ssl','storage','preferred region','nodes','owner'].map(&:upcase)
@@ -53,6 +53,21 @@ module NexClient
53
53
  Addons.display_addons(e.addons.select { |a| a.status == 'active'})
54
54
  end
55
55
 
56
+ def self.logs(args,opts)
57
+ name = args.first
58
+ e = NexClient::App.find(name: name).first
59
+
60
+ # Display error
61
+ unless e
62
+ error("Error! Could not find app: #{name}")
63
+ return false
64
+ end
65
+
66
+ # Retrieve logs and display them
67
+ logs = e.logs(tail: opts.tail).first
68
+ self.display_logs(logs.log_ret)
69
+ end
70
+
56
71
  def self.create(args,opts)
57
72
  image_info = args.first.split(':')
58
73
  attrs = { image: image_info[0], image_tag: image_info[1] }
@@ -3,6 +3,7 @@
3
3
  module NexClient
4
4
  module Commands
5
5
  module Helpers
6
+ LOG_COLORS = [:cyan,:green,:red,:yellow,:magenta]
6
7
 
7
8
  def display_record_errors(record)
8
9
  record.errors.messages.each do |k,v|
@@ -17,6 +18,18 @@ module NexClient
17
18
  def error(msg)
18
19
  puts msg.colorize(:red)
19
20
  end
21
+
22
+ def display_logs(logs)
23
+ color_index = 0
24
+ logs.each do |container_id,log_lines|
25
+ color_index = (color_index + 1) % LOG_COLORS.size
26
+ puts "\n"
27
+ puts "Node: #{container_id}".colorize(LOG_COLORS[color_index])
28
+ puts "-"*50
29
+ puts log_lines.join("\n")
30
+ end
31
+ puts "\n"
32
+ end
20
33
  end
21
34
  end
22
35
  end
@@ -1,3 +1,3 @@
1
1
  module NexClient
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ describe NexClient::App do
4
+ subject { described_class.new(id: 1) }
5
+ let(:api_key) { ENV['NEX_API_KEY'] }
6
+
7
+ describe 'restart' do
8
+ let!(:stub) { stub_request(:patch, "#{api_key}:@nex-test.com/api/v1/apps/#{subject.id}/restart") }
9
+ before { subject.restart }
10
+ it { expect(stub).to have_been_requested }
11
+ end
12
+
13
+ describe 'scale_up' do
14
+ describe 'without arguments' do
15
+ let!(:stub) { stub_request(:patch, "#{api_key}:@nex-test.com/api/v1/apps/#{subject.id}/scale_up") }
16
+ before { subject.scale_up }
17
+ it { expect(stub).to have_been_requested }
18
+ end
19
+ end
20
+
21
+ describe 'scale_down' do
22
+ let!(:stub) { stub_request(:patch, "#{api_key}:@nex-test.com/api/v1/apps/#{subject.id}/scale_down") }
23
+ before { subject.scale_down }
24
+ it { expect(stub).to have_been_requested }
25
+ end
26
+
27
+ describe 'link_scm' do
28
+ let!(:stub) { stub_request(:patch, "#{api_key}:@nex-test.com/api/v1/apps/#{subject.id}/link_scm") }
29
+ before { subject.link_scm }
30
+ it { expect(stub).to have_been_requested }
31
+ end
32
+
33
+ describe 'unlink_scm' do
34
+ let!(:stub) { stub_request(:patch, "#{api_key}:@nex-test.com/api/v1/apps/#{subject.id}/unlink_scm") }
35
+ before { subject.unlink_scm }
36
+ it { expect(stub).to have_been_requested }
37
+ end
38
+
39
+ describe 'logs' do
40
+ let!(:stub) { stub_request(:get, "#{api_key}:@nex-test.com/api/v1/apps/#{subject.id}/logs") }
41
+ before { subject.logs }
42
+ it { expect(stub).to have_been_requested }
43
+ end
44
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe NexClient::CubeInstance do
4
+ subject { described_class.new(id: 1) }
5
+ let(:api_key) { ENV['NEX_API_KEY'] }
6
+
7
+ describe 'restart' do
8
+ let!(:stub) { stub_request(:patch, "#{api_key}:@nex-test.com/api/v1/cube_instances/#{subject.id}/restart") }
9
+ before { subject.restart }
10
+ it { expect(stub).to have_been_requested }
11
+ end
12
+
13
+ describe 'start' do
14
+ let!(:stub) { stub_request(:patch, "#{api_key}:@nex-test.com/api/v1/cube_instances/#{subject.id}/start") }
15
+ before { subject.start }
16
+ it { expect(stub).to have_been_requested }
17
+ end
18
+
19
+ describe 'stop' do
20
+ let!(:stub) { stub_request(:patch, "#{api_key}:@nex-test.com/api/v1/cube_instances/#{subject.id}/stop") }
21
+ before { subject.stop }
22
+ it { expect(stub).to have_been_requested }
23
+ end
24
+
25
+ end
@@ -0,0 +1,93 @@
1
+ ENV['NEX_API_KEY'] = 'somekey'
2
+ ENV['NEX_ENV'] = 'test'
3
+
4
+ $:.unshift File.expand_path("../../lib", __FILE__)
5
+
6
+ require 'nex_client'
7
+ require 'webmock/rspec'
8
+
9
+ RSpec.configure do |config|
10
+ # rspec-expectations config goes here. You can use an alternate
11
+ # assertion/expectation library such as wrong or the stdlib/minitest
12
+ # assertions if you prefer.
13
+ config.expect_with :rspec do |expectations|
14
+ # This option will default to `true` in RSpec 4. It makes the `description`
15
+ # and `failure_message` of custom matchers include text for helper methods
16
+ # defined using `chain`, e.g.:
17
+ # be_bigger_than(2).and_smaller_than(4).description
18
+ # # => "be bigger than 2 and smaller than 4"
19
+ # ...rather than:
20
+ # # => "be bigger than 2"
21
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
22
+ end
23
+
24
+ # rspec-mocks config goes here. You can use an alternate test double
25
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
26
+ config.mock_with :rspec do |mocks|
27
+ # Prevents you from mocking or stubbing a method that does not exist on
28
+ # a real object. This is generally recommended, and will default to
29
+ # `true` in RSpec 4.
30
+ mocks.verify_partial_doubles = true
31
+ end
32
+
33
+ # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
34
+ # have no way to turn it off -- the option exists only for backwards
35
+ # compatibility in RSpec 3). It causes shared context metadata to be
36
+ # inherited by the metadata hash of host groups and examples, rather than
37
+ # triggering implicit auto-inclusion in groups with matching metadata.
38
+ config.shared_context_metadata_behavior = :apply_to_host_groups
39
+
40
+ # The settings below are suggested to provide a good initial experience
41
+ # with RSpec, but feel free to customize to your heart's content.
42
+ =begin
43
+ # This allows you to limit a spec run to individual examples or groups
44
+ # you care about by tagging them with `:focus` metadata. When nothing
45
+ # is tagged with `:focus`, all examples get run. RSpec also provides
46
+ # aliases for `it`, `describe`, and `context` that include `:focus`
47
+ # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
48
+ config.filter_run_when_matching :focus
49
+
50
+ # Allows RSpec to persist some state between runs in order to support
51
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
52
+ # you configure your source control system to ignore this file.
53
+ config.example_status_persistence_file_path = "spec/examples.txt"
54
+
55
+ # Limits the available syntax to the non-monkey patched syntax that is
56
+ # recommended. For more details, see:
57
+ # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
58
+ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
59
+ # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
60
+ config.disable_monkey_patching!
61
+
62
+ # This setting enables warnings. It's recommended, but in some cases may
63
+ # be too noisy due to issues in dependencies.
64
+ config.warnings = true
65
+
66
+ # Many RSpec users commonly either run the entire suite or an individual
67
+ # file, and it's useful to allow more verbose output when running an
68
+ # individual spec file.
69
+ if config.files_to_run.one?
70
+ # Use the documentation formatter for detailed output,
71
+ # unless a formatter has already been configured
72
+ # (e.g. via a command-line flag).
73
+ config.default_formatter = 'doc'
74
+ end
75
+
76
+ # Print the 10 slowest examples and example groups at the
77
+ # end of the spec run, to help surface which specs are running
78
+ # particularly slow.
79
+ config.profile_examples = 10
80
+
81
+ # Run specs in random order to surface order dependencies. If you find an
82
+ # order dependency and want to debug it, you can fix the order by providing
83
+ # the seed, which is printed after each run.
84
+ # --seed 1234
85
+ config.order = :random
86
+
87
+ # Seed global randomization in this process using the `--seed` CLI option.
88
+ # Setting this allows you to use `--seed` to deterministically reproduce
89
+ # test failures related to randomization by passing the same `--seed` value
90
+ # as the one that triggered the failure.
91
+ Kernel.srand config.seed
92
+ =end
93
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nex_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arnaud Lachaume
@@ -80,6 +80,34 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.5'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.5'
97
+ - !ruby/object:Gem::Dependency
98
+ name: webmock
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
83
111
  description: Client library for Maestrano Nex!™ PaaS
84
112
  email:
85
113
  - developers@maestrano.com
@@ -119,6 +147,9 @@ files:
119
147
  - lib/nex_client/storage_rack.rb
120
148
  - lib/nex_client/user.rb
121
149
  - lib/nex_client/version.rb
150
+ - spec/nex_client/app_spec.rb
151
+ - spec/nex_client/cube_instance_spec.rb
152
+ - spec/spec_helper.rb
122
153
  homepage: https://maestrano.com
123
154
  licenses:
124
155
  - Apache-2.0
@@ -143,4 +174,7 @@ rubygems_version: 2.5.1
143
174
  signing_key:
144
175
  specification_version: 4
145
176
  summary: Maestrano Nex!™ Client
146
- test_files: []
177
+ test_files:
178
+ - spec/nex_client/app_spec.rb
179
+ - spec/nex_client/cube_instance_spec.rb
180
+ - spec/spec_helper.rb