foreman_teamdynamix 0.4.0 → 2.0.0

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
- SHA1:
3
- metadata.gz: 77e70ad3672357e8772f829cdf43cb8005b82ec3
4
- data.tar.gz: 4f2b4a5249fbe6c31a6af63a6ffd9aeec60bbed0
2
+ SHA256:
3
+ metadata.gz: 794c51b66dd0d644686457e879f7afdac549631887c3992ff7fb3e0f605c75b6
4
+ data.tar.gz: 643df4d3a0afa76409a95bea74a9d1827ba52ccb34de79d1beef8100c9ecc21d
5
5
  SHA512:
6
- metadata.gz: 341100129b0941eaac64e24226fc100364209ab9821b7af26cdff2159e10064f188c7bb2add1d7829b3dc20835fe379c11f128f08ff447695a6d662a15b8c3e6
7
- data.tar.gz: f6502be9bc5df3826407317d315500fbc5d929082fb50ea0160508f1864baa329d5936fe777a982523aaae075cf2b132a162090be26b4739fb9030b1cf5d5a95
6
+ metadata.gz: 43388c4a90d67990cafa869640227c28dcc11d16ec9a404aca967c4e06ef44ee1637c9d95fb381cc398eca99f40a1e713799c11b0432510061da40286b6f14a6
7
+ data.tar.gz: a197a8ec8140d1d076b5173529d1bde01c8c3145708f701bf7ba3088fcb0f2d142b4c95eee03269ccbe4925a4ae0e10716f849b08bd1b442879f376e8f4c1ae1
data/LICENSE CHANGED
File without changes
data/README.md CHANGED
@@ -28,23 +28,23 @@ Example Configuration
28
28
  :username: 'xxxxxx'
29
29
  :password: 'xxxxxx'
30
30
  :create:
31
- :StatusID: 641
32
- :AcquisitionDate: host.created_at
33
- :OwningCustomerName: "'foreman_teamdynamix_plugin_test'"
34
- :Attributes:
35
- - name: mu.ci.Lifecycle Status
36
- id: 11634
37
- value: 26190
38
- - name: mu.ci.Description
39
- id: 11632
40
- value: >-
31
+ StatusID: 641
32
+ AcquisitionDate: host.created_at
33
+ OwningCustomerName: "'foreman_teamdynamix_plugin_test'"
34
+ Attributes:
35
+ - Name: mu.ci.Lifecycle Status
36
+ ID: 11634
37
+ Value: 26190
38
+ - Name: mu.ci.Description
39
+ ID: 11632
40
+ Value: >-
41
41
  "created by ForemanTeamdynamix plugin, owner is #{host.owner_id}"
42
- - name: Ticket Routing Details
43
- id: 11636
44
- value: >-
42
+ - Name: Ticket Routing Details
43
+ ID: 11636
44
+ Value: >-
45
45
  "Asset for host running on OS #{host.operatingsystem_id}"
46
46
  :delete:
47
- :StatusId: 642
47
+ StatusId: 642
48
48
  :fields:
49
49
  :url: https://miamioh.teamdynamix.com/SBTDNext/Apps
50
50
  Asset ID: ID
@@ -58,9 +58,10 @@ Example Configuration
58
58
  * All attributes are passed to the TeamDynamix API as is, while creating or deleting a TeamDynamix Asset.
59
59
  * An asset gets created or deleted with the Foreman Host create or delete life cycle event.
60
60
 
61
- [:api][:create][:Attributes]
61
+ [:api][:create][Attributes]
62
62
  * To configure any [Custom Attributes](https://api.teamdynamix.com/TDWebApi/Home/type/TeamDynamix.Api.CustomAttributes.CustomAttribute) for the asset.
63
- * It must contain expected value for 'id' and 'value' fields.
63
+ * It must contain expected value for 'Name', 'ID' and 'Value' fields.
64
+ * Notice the case of 'Name', 'ID' and 'Value', this must match for correct merging.
64
65
  * rest of the fields are optional, check the Custom Attribute's definition for what other fields are updatable.
65
66
  * Code evaluation is supported for custom attribute's value.
66
67
 
data/Rakefile CHANGED
@@ -38,7 +38,7 @@ task default: :test
38
38
  begin
39
39
  require 'rubocop/rake_task'
40
40
  RuboCop::RakeTask.new
41
- rescue StandardError => _
41
+ rescue StandardError => _e
42
42
  puts 'Rubocop not loaded.'
43
43
  end
44
44
 
@@ -6,8 +6,8 @@ module ForemanTeamdynamix
6
6
  def teamdynamix
7
7
  find_resource
8
8
  render partial: 'foreman_teamdynamix/hosts/teamdynamix', :locals => { :host => @host }
9
- rescue ActionView::Template::Error => exception
10
- process_ajax_error exception, 'fetch teamdynamix tab information'
9
+ rescue ActionView::Template::Error => e
10
+ process_ajax_error e, 'fetch teamdynamix tab information'
11
11
  end
12
12
 
13
13
  private
@@ -11,9 +11,9 @@ module ForemanTeamdynamix
11
11
 
12
12
  def teamdynamix_fields
13
13
  td_pane_fields = SETTINGS[:teamdynamix][:fields] || DEFAULT_TD_PANE_FIELDS
14
- return [[_('Asset'), 'None Associated']] unless @host.teamdynamix_asset_uid
14
+ return [[_('Asset'), 'None Associated or error from Team Dynamix']] unless @host.teamdynamix_asset
15
15
 
16
- get_teamdynamix_asset(@host.teamdynamix_asset_uid)
16
+ @asset = @host.teamdynamix_asset
17
17
 
18
18
  # display a link to the asset if url set
19
19
  fields = asset_uri(td_pane_fields)
@@ -32,29 +32,26 @@ module ForemanTeamdynamix
32
32
  def asset_uri(td_pane_fields)
33
33
  if td_pane_fields[:url]
34
34
  uri = "#{td_pane_fields[:url]}/#{@asset['AppID']}/Assets/AssetDet?AssetID=#{@asset['ID']}"
35
- [[_('URI'), link_to(@asset['SerialNumber'], uri, target: '_blank')]]
35
+ [[_('URI'), link_to(@asset['SerialNumber'], uri, target: '_blank', rel: 'noopener')]]
36
36
  else
37
37
  []
38
38
  end
39
39
  end
40
40
 
41
- def get_teamdynamix_asset(asset_id)
42
- @asset = @host.td_api.get_asset(asset_id)
43
- rescue StandardError => e
44
- raise "Error getting asset Data from Team Dynamix: #{e.message}"
45
- end
46
-
47
41
  def get_nested_attrib_val(nested_attrib)
48
42
  nested_attrib_tokens = nested_attrib.split('.')
49
43
  parent_attrib = nested_attrib_tokens.first
50
44
  child_attrib = nested_attrib_tokens[1..nested_attrib_tokens.length].join('.')
51
45
  return '' if parent_attrib.blank? || child_attrib.blank?
46
+
52
47
  child_attrib.delete!("'")
53
48
  parent_attrib_val = @asset[parent_attrib]
54
49
  return '' if parent_attrib_val.blank?
55
- nested_attrib_val = parent_attrib_val.select { |attrib| attrib['Name'] == child_attrib }
50
+
51
+ nested_attrib_val = parent_attrib_val.find { |attrib| attrib['Name'] == child_attrib }
56
52
  return '' if nested_attrib_val.blank?
57
- nested_attrib_val[0]['Value']
53
+
54
+ nested_attrib_val['Value']
58
55
  end
59
56
  end
60
57
  end
@@ -2,38 +2,59 @@ module ForemanTeamdynamix
2
2
  module HostExtensions
3
3
  extend ActiveSupport::Concern
4
4
 
5
+ included do
6
+ before_create :create_or_update_teamdynamix_asset
7
+ before_destroy :retire_teamdynamix_asset
8
+ validates :teamdynamix_asset_uid, uniqueness: { :allow_blank => true }
9
+ end
10
+
5
11
  def td_api
6
12
  @td_api ||= TeamdynamixApi.instance
7
13
  end
8
14
 
9
- included do
10
- before_create :create_teamdynamix_asset
11
- before_destroy :retire_teamdynamix_asset
12
- validates :teamdynamix_asset_uid, uniqueness: { :allow_blank => true }
15
+ def teamdynamix_asset_status
16
+ @teamdynamix_asset_status
13
17
  end
14
18
 
15
- private
19
+ def teamdynamix_asset(search = false)
20
+ @teamdynamix_asset ||= td_api.get_asset(teamdynamix_asset_uid)
16
21
 
17
- def create_teamdynamix_asset
18
- # when the asset is already in teamdynamix
19
- assets = td_api.search_asset(SerialLike: name)
22
+ if search && !@teamdynamix_asset
23
+ assets = td_api.search_asset(SerialLike: name)
24
+ if assets.length == 1
25
+ @teamdynamix_asset = td_api.get_asset(assets.first['ID'])
26
+ self.teamdynamix_asset_uid = teamdynamix_asset['ID']
27
+ @teamdynamix_asset_status = :updated_search
28
+ elsif assets.length > 1
29
+ errors.add(:base, _("Search for asset in TeamDynamix failed: Found #{assets.length} matching assets"))
30
+ end
31
+ end
20
32
 
21
- if assets.empty?
22
- asset = td_api.create_asset(self)
23
- self.teamdynamix_asset_uid = asset['ID']
24
- elsif assets.length > 1
25
- raise 'Found more than 1 existing asset'
26
- else
27
- self.teamdynamix_asset_uid = assets.first['ID']
33
+ @teamdynamix_asset
34
+ end
35
+
36
+ def create_or_update_teamdynamix_asset(save = false)
37
+ if teamdynamix_asset(true)
28
38
  td_api.update_asset(self)
39
+ @teamdynamix_asset_status ||= :updated_id
40
+ self.save if save
41
+ elsif errors.empty?
42
+ @teamdynamix_asset = td_api.create_asset(self)
43
+ self.teamdynamix_asset_uid = teamdynamix_asset['ID']
44
+ @teamdynamix_asset_status = :created
45
+ self.save if save
46
+ else
47
+ false
29
48
  end
30
49
  rescue StandardError => e
31
- errors.add(:base, _("Could not create the asset for the host in TeamDynamix: #{e.message}"))
50
+ errors.add(:base, _("Could not create or update the asset for the host in TeamDynamix: #{e.message}"))
32
51
  false
33
52
  end
34
53
 
54
+ private
55
+
35
56
  def retire_teamdynamix_asset
36
- td_api.retire_asset(teamdynamix_asset_uid) if teamdynamix_asset_uid
57
+ td_api.retire_asset(self) if teamdynamix_asset
37
58
  rescue StandardError => e
38
59
  errors.add(:base, _("Could not retire the asset for the host in TeamDynamix: #{e.message}"))
39
60
  false
File without changes
File without changes
@@ -5,12 +5,15 @@ class TeamdynamixApi
5
5
  if SETTINGS[:teamdynamix].blank?
6
6
  raise('Missing configurations for the plugin see https://github.com/MiamiOH/foreman_teamdynamix')
7
7
  end
8
+
8
9
  API_CONFIG = SETTINGS[:teamdynamix][:api]
9
10
 
10
11
  raise('Missing Team Dynamix Api ID in plugin settings') if API_CONFIG[:appId].blank?
12
+
11
13
  APP_ID = API_CONFIG[:appId]
12
14
 
13
15
  raise('Missing Team Dynamix API URL in plugin settings') if API_CONFIG[:url].blank?
16
+
14
17
  API_URL = API_CONFIG[:url]
15
18
 
16
19
  def initialize
@@ -20,14 +23,12 @@ class TeamdynamixApi
20
23
 
21
24
  # returns TeamDynamix.Api.Assets.Asset
22
25
  def get_asset(asset_id)
26
+ return nil unless asset_id
27
+
23
28
  uri = URI.parse("#{API_URL}/#{APP_ID}/assets/#{asset_id}")
24
29
  rest(:get, uri)
25
- end
26
-
27
- def asset_exist?(asset_id)
28
- get_asset(asset_id).present?
29
30
  rescue RuntimeError
30
- false
31
+ nil
31
32
  end
32
33
 
33
34
  def create_asset(host)
@@ -40,9 +41,9 @@ class TeamdynamixApi
40
41
  rest(:post, uri, update_asset_payload(host))
41
42
  end
42
43
 
43
- def retire_asset(asset_id)
44
- uri = URI.parse("#{API_URL}/#{APP_ID}/assets/#{asset_id}")
45
- rest(:post, uri, retire_asset_payload(asset_id))
44
+ def retire_asset(host)
45
+ uri = URI.parse("#{API_URL}/#{APP_ID}/assets/#{host.teamdynamix_asset_uid}")
46
+ rest(:post, uri, retire_asset_payload(host))
46
47
  end
47
48
 
48
49
  # Gets a list of assets matching the specified criteria. (IEnumerable(Of TeamDynamix.Api.Assets.Asset))
@@ -106,26 +107,38 @@ class TeamdynamixApi
106
107
  end
107
108
  end
108
109
 
109
- def retire_asset_payload(asset_id)
110
- asset = get_asset(asset_id)
111
- asset.merge(API_CONFIG[:delete].stringify_keys)
112
- end
113
-
114
110
  def create_asset_payload(host)
115
111
  ensure_configured_create_params
116
- default_attrs = { AppID: APP_ID,
117
- SerialNumber: host.name,
118
- Name: host.fqdn }
119
- create_attrs = evaluate_attributes(API_CONFIG[:create], host)
120
- default_attrs.merge(create_attrs)
121
- end
122
-
123
- def evaluate_attributes(create_attrs, host)
124
- create_attrs.symbolize_keys.each_with_object({}) do |(k, v), h|
125
- if k.eql?(:Attributes)
126
- h[:Attributes] = v.each_with_object([]) do |attribute, a|
127
- a << attribute.transform_keys(&:downcase)
128
- a.last['value'] = eval_attribute(a.last['value'], host)
112
+ default_attrs = { 'AppID' => APP_ID,
113
+ 'SerialNumber' => host.name,
114
+ 'Name' => host.fqdn }
115
+ evaluate_attributes(API_CONFIG[:create], host, default_attrs)
116
+ end
117
+
118
+ def update_asset_payload(host)
119
+ default_attrs = { 'AppID' => APP_ID,
120
+ 'SerialNumber' => host.name,
121
+ 'Name' => host.fqdn }
122
+ evaluate_attributes(API_CONFIG[:create], host, host.teamdynamix_asset.merge(default_attrs))
123
+ end
124
+
125
+ def retire_asset_payload(host)
126
+ evaluate_attributes(API_CONFIG[:delete], host, host.teamdynamix_asset)
127
+ end
128
+
129
+ def evaluate_attributes(attrs, host, asset = {})
130
+ attrs.stringify_keys.each_with_object(asset) do |(k, v), h|
131
+ if k.eql?('Attributes')
132
+ h['Attributes'] ||= []
133
+ v.each do |attrib|
134
+ attrib_c = attrib.stringify_keys
135
+ match = h['Attributes'].find { |attrib_a| attrib_a['Name'] == attrib_c['Name'] }
136
+ if match
137
+ match['Value'] = eval_attribute(attrib_c['Value'], host)
138
+ else
139
+ attrib_c['Value'] = eval_attribute(attrib_c['Value'], host)
140
+ h['Attributes'] << attrib_c
141
+ end
129
142
  end
130
143
  else
131
144
  h[k] = eval_attribute(v, host)
@@ -140,21 +153,16 @@ class TeamdynamixApi
140
153
  end
141
154
 
142
155
  def must_configure_create_params
143
- [:StatusID]
156
+ ['StatusID']
144
157
  end
145
158
 
146
159
  def valid_auth_token?(token)
147
- token.match(/^[a-zA-Z0-9\.\-\_]*$/)
148
- end
149
-
150
- def update_asset_payload(host)
151
- payload = { ID: host.teamdynamix_asset_uid }
152
- payload.merge(create_asset_payload(host))
160
+ token.match(/^[a-zA-Z0-9.\-_]*$/)
153
161
  end
154
162
 
155
163
  def ensure_configured_create_params
156
164
  must_configure_create_params.each do |must_configure_param|
157
- unless API_CONFIG[:create].include?(must_configure_param)
165
+ unless API_CONFIG[:create].include?(must_configure_param) || API_CONFIG[:create].include?(must_configure_param.to_sym)
158
166
  raise("#{must_configure_param} is required. Set it as a configuration item.")
159
167
  end
160
168
  end
@@ -1,5 +1,5 @@
1
1
  Rails.application.routes.draw do
2
- constraints(:id => %r{[^\/]+}) do
2
+ constraints(:id => %r{[^/]+}) do
3
3
  resources :hosts do
4
4
  member do
5
5
  get 'teamdynamix'
File without changes
@@ -16,29 +16,24 @@ module ForemanTeamdynamix
16
16
 
17
17
  initializer 'foreman_teamdynamix.register_plugin', :before => :finisher_hook do |_app|
18
18
  Foreman::Plugin.register :foreman_teamdynamix do
19
- requires_foreman '>= 1.7'
19
+ requires_foreman '>= 2.3'
20
20
 
21
21
  # Add permissions
22
22
  security_block :foreman_teamdynamix do
23
- ps = permission :view_hosts,
24
- { :hosts => [:teamdynamix] },
25
- :resource_type => 'Host'
26
- pn = ps.pop
27
- po = ps.detect { |p| p.name == :view_hosts }
28
- po.actions << pn.actions.first
23
+ permission :view_teamdynamix,
24
+ { :hosts => [:teamdynamix] },
25
+ :resource_type => 'Host'
29
26
  end
30
27
  end
31
28
  end
32
29
 
33
30
  # Include concerns in this config.to_prepare block
34
31
  config.to_prepare do
35
- begin
36
- HostsHelper.send(:include, ForemanTeamdynamix::HostsHelperExtensions)
37
- ::HostsController.send(:include, ForemanTeamdynamix::HostsControllerExtensions)
38
- ::Host::Managed.send(:include, ForemanTeamdynamix::HostExtensions)
39
- rescue StandardError => e
40
- Rails.logger.warn "ForemanTeamdynamix: skipping engine hook (#{e})"
41
- end
32
+ HostsHelper.include ForemanTeamdynamix::HostsHelperExtensions
33
+ ::HostsController.include ForemanTeamdynamix::HostsControllerExtensions
34
+ ::Host::Managed.include ForemanTeamdynamix::HostExtensions
35
+ rescue StandardError => e
36
+ Rails.logger.warn "ForemanTeamdynamix: skipping engine hook (#{e})"
42
37
  end
43
38
 
44
39
  initializer 'foreman_teamdynamix.register_gettext', after: :load_config_initializers do |_app|
@@ -1,3 +1,3 @@
1
1
  module ForemanTeamdynamix
2
- VERSION = '0.4.0'.freeze
2
+ VERSION = '2.0.0'.freeze
3
3
  end
@@ -11,7 +11,7 @@ namespace :test do
11
11
  end
12
12
 
13
13
  namespace :foreman_teamdynamix do
14
- task :rubocop do
14
+ task rubocop: :environment do
15
15
  begin
16
16
  require 'rubocop/rake_task'
17
17
  RuboCop::RakeTask.new(:rubocop_foreman_teamdynamix) do |task|
@@ -1,4 +1,4 @@
1
- desc <<-DESC.strip_heredoc.squish
1
+ desc <<~DESC.squish
2
2
  Scans existing hosts and creates or updates the asset in TeamDynamix.
3
3
  * If found, update the fields in the TeamDynamix asset.
4
4
  * If not found, create a TeamDynamix asset with desired fields.
@@ -6,46 +6,41 @@ desc <<-DESC.strip_heredoc.squish
6
6
  It could be run for all the hosts as:
7
7
  * rake teamydynamix:sync:hosts
8
8
 
9
+ Available options:
10
+ * where => where string for limiting host query
11
+ * limit => limit for limiting host query
12
+
9
13
  DESC
10
14
  namespace :teamdynamix do
11
15
  namespace :sync do
12
16
  task :hosts => :environment do
13
- td_api = TeamdynamixApi.instance
14
17
  errors = []
15
- creates = 0
16
- updates_from_serial_matching = 0
17
- update_from_asset_id = 0
18
+ created = 0
19
+ updated_search = 0
20
+ updated_id = 0
18
21
 
19
22
  console_user = User.find_by(login: 'foreman_console_admin')
20
23
  User.current = console_user
21
24
 
22
- Host.all.each do |h|
23
- # if asset exists, update it
24
- if td_api.asset_exist?(h.teamdynamix_asset_uid)
25
- td_api.update_asset(h)
26
- update_from_asset_id += 1
27
- else
28
- assets = td_api.search_asset(SerialLike: h.name)
29
- if assets.empty?
30
- asset = td_api.create_asset(h)
31
- h.teamdynamix_asset_uid = asset['ID']
32
- errors.push("Could not save host: #{h.name} (#{h.id})") unless h.save
33
- creates += 1
34
- elsif assets.length > 1
35
- errors.push("Could not sync: Found more than 1 asset for #{h.name} (#{h.id})")
36
- else
37
- h.teamdynamix_asset_uid = assets.first['ID']
38
- td_api.update_asset(h)
39
- errors.push("Could not save host: #{h.name} (#{h.id})") unless h.save
40
- updates_from_serial_matching += 1
25
+ hosts = Host
26
+ hosts = hosts.where(ENV['where']) if ENV['where']
27
+ hosts = hosts.limit(ENV['limit']) if ENV['limit']
28
+
29
+ hosts.all.each do |h|
30
+ if h.create_or_update_teamdynamix_asset(true)
31
+ case h.teamdynamix_asset_status
32
+ when :created then created += 1
33
+ when :updated_search then updated_search += 1
34
+ when :updated_id then updated_id += 1
41
35
  end
36
+ else
37
+ errors.push("Could not save host: #{h.name} (#{h.id}):\n #{h.errors.full_messages.join("\n ")}")
42
38
  end
39
+ sleep(1.5) # TD only allows 60 api calls per minute
43
40
  end
44
- puts "Assets created: #{creates}" unless creates.eql?(0)
45
- unless updates_from_serial_matching.eql?(0)
46
- puts "Assets updated from serial search: #{updates_from_serial_matching}"
47
- end
48
- puts "Assets updated from ID: #{update_from_asset_id}" unless update_from_asset_id.eql?(0)
41
+ puts "Assets created: #{created}" unless created.eql?(0)
42
+ puts "Assets updated from serial search: #{updated_search}" unless updated_search.eql?(0)
43
+ puts "Assets updated from ID: #{updated_id}" unless updated_id.eql?(0)
49
44
  puts "Errors:\n#{errors.join("\n")}" unless errors.empty?
50
45
  end
51
46
  end
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -7,7 +7,7 @@ class HostsControllerTest < ActionController::TestCase
7
7
  before do
8
8
  Host::Managed.any_instance.stubs(:td_api).returns(td_api)
9
9
  end
10
- # rubocop:disable Style/StringLiterals, HttpPositionalArguments
10
+ # rubocop:disable Style/StringLiterals, Rails/HttpPositionalArguments
11
11
  describe 'Given host exist as an asset in TeamDynamix' do
12
12
  describe 'when TeamDynamix asset attributes are configured' do
13
13
  describe 'GET hosts/show' do
@@ -15,9 +15,10 @@ class HostsControllerTest < ActionController::TestCase
15
15
  get :show, { :id => host.name }, set_session_user
16
16
  assert_includes response.headers['Content-Type'], 'text/html'
17
17
  assert_includes response.body, "<ul id=\"myTab\""
18
- assert_equal response.status, 200
18
+ assert_equal(200, response.status)
19
19
  assert_includes response.body, "<li><a href=\"#teamdynamix\" data-toggle=\"tab\">#{td_tab_title}</a></li>"
20
- assert_includes response.body, "<div id=\"teamdynamix\" class=\"tab-pane\" data-ajax-url=\"/hosts/#{host.name}/teamdynamix\" data-on-complete=\"onContentLoad\">"
20
+ assert_includes response.body,
21
+ "<div id=\"teamdynamix\" class=\"tab-pane\" data-ajax-url=\"/hosts/#{host.name}/teamdynamix\" data-on-complete=\"onContentLoad\">"
21
22
  end
22
23
  test 'TeamDynamix tab contains configured asset attributes' do
23
24
  skip
@@ -27,5 +28,5 @@ class HostsControllerTest < ActionController::TestCase
27
28
  end
28
29
  end
29
30
  end
30
- # rubocop:enable Style/StringLiterals, HttpPositionalArguments
31
+ # rubocop:enable Style/StringLiterals, Rails/HttpPositionalArguments
31
32
  end
@@ -13,7 +13,9 @@ class HostsHelperExtensionsTest < ActiveSupport::TestCase
13
13
  describe '#teamdynamix_fields' do
14
14
  let(:sample_asset) { td_api.get_asset }
15
15
  let(:default_fields) { [sample_asset_uri] }
16
- let(:direct_attribs_config) { { 'Asset ID' => 'ID', 'Owner' => 'OwningCustomerName', 'Parent Asset' => 'ParentID' } }
16
+ let(:direct_attribs_config) do
17
+ { 'Asset ID' => 'ID', 'Owner' => 'OwningCustomerName', 'Parent Asset' => 'ParentID' }
18
+ end
17
19
  let(:direct_attribs_fields) { get_direct_asset_attribs_val(direct_attribs_config) }
18
20
  let(:expected_fields) { default_fields + direct_attribs_fields }
19
21
  before do
@@ -56,7 +58,7 @@ class HostsHelperExtensionsTest < ActiveSupport::TestCase
56
58
 
57
59
  test 'settings title is not present: return default title' do
58
60
  SETTINGS[:teamdynamix][:title] = nil
59
- assert_equal teamdynamix_title, 'Team Dynamix'
61
+ assert_equal('Team Dynamix', teamdynamix_title)
60
62
  SETTINGS[:teamdynamix][:title] = title_orig
61
63
  end
62
64
  end
File without changes
File without changes
@@ -8,17 +8,19 @@ class TeamdynamixApiTest < ActiveSupport::TestCase
8
8
  let(:api_url) { api_config[:url] }
9
9
  let(:host) { FactoryBot.build(:host, :managed) }
10
10
  let(:auth_payload) { { username: api_config[:username], password: api_config[:password] }.to_json }
11
- let(:dummy_token) { 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1bmlxdWVfbmFtZSI6InR5YWdpbkBtaWFtaW9oLmVkdSIsImlzcyI6IlREIiwiYXVkIjoiaHR0cHM6Ly93d3cudGVhbWR5bmFtaXguY29tLyIsImV4cCI6MTUxNzA2OTU1OSwibmJmIjoxNTE2OTgzMTU5fQ.PkvKbYQCV-hY7_ni4-Zg3qJARBagSzz99fclBYyxxas' }
11
+ let(:dummy_token) do
12
+ 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1bmlxdWVfbmFtZSI6InR5YWdpbkBtaWFtaW9oLmVkdSIsImlzcyI6IlREIiwiYXVkIjoiaHR0cHM6Ly93d3cudGVhbWR5bmFtaXguY29tLyIsImV4cCI6MTUxNzA2OTU1OSwibmJmIjoxNTE2OTgzMTU5fQ.PkvKbYQCV-hY7_ni4-Zg3qJARBagSzz99fclBYyxxas'
13
+ end
12
14
  let(:sample_asset) { FakeTeamdynamixApi.new.get_asset }
13
15
  let(:sample_asset_id) { sample_asset['ID'].to_s }
14
16
  let(:host_name) { 'delete.foreman_teamdynamix.com' }
15
- let(:get_asset_path) { api_url + '/' + app_id + '/assets/' + sample_asset_id }
17
+ let(:get_asset_path) { "#{api_url}/#{app_id}/assets/#{sample_asset_id}" }
16
18
  let(:create_status_id) { 641 }
17
19
  let(:custom_attributes) do
18
20
  [{ 'name' => 'mu.ci.Lifecycle Status', 'id' => 11_634, 'value' => '26193' },
19
21
  { 'name' => 'mu.ci.Description', 'id' => 11_632, 'value' => 'Foreman host created by ForemanTeamdynamix plugin' }]
20
22
  end
21
- let(:create_path) { api_url + '/' + app_id + '/assets' }
23
+ let(:create_path) { "#{api_url}/#{app_id}/assets" }
22
24
  let(:create_payload) do
23
25
  { AppID: app_id,
24
26
  SerialNumber: host_name,
@@ -27,7 +29,7 @@ class TeamdynamixApiTest < ActiveSupport::TestCase
27
29
  Attributes: custom_attributes }
28
30
  end
29
31
  before do
30
- stub_request(:post, api_url + '/auth')
32
+ stub_request(:post, "#{api_url}/auth")
31
33
  .with(body: auth_payload,
32
34
  headers: { 'Content-Type' => 'application/json' })
33
35
  .to_return(status: 200, body: dummy_token)
@@ -45,7 +47,7 @@ class TeamdynamixApiTest < ActiveSupport::TestCase
45
47
  context 'Valid Request' do
46
48
  before do
47
49
  stub_request(:post, update_path)
48
- .with(headers: { 'Authorization' => 'Bearer ' + dummy_token,
50
+ .with(headers: { 'Authorization' => "Bearer #{dummy_token}",
49
51
  'Content-Type' => 'application/json' },
50
52
  body: update_payload)
51
53
  .to_return(status: 200, body: sample_asset.to_json)
@@ -67,10 +69,10 @@ class TeamdynamixApiTest < ActiveSupport::TestCase
67
69
  end
68
70
  describe 'valid request' do
69
71
  let(:retired_asset) { sample_asset.merge('StatusID' => retire_status_id) }
70
- let(:retire_path) { api_url + '/' + app_id + '/assets/' + sample_asset_id }
72
+ let(:retire_path) { "#{api_url}/#{app_id}/assets/#{sample_asset_id}" }
71
73
  before do
72
74
  stub_request(:post, retire_path)
73
- .with(headers: { 'Authorization' => 'Bearer ' + dummy_token,
75
+ .with(headers: { 'Authorization' => "Bearer #{dummy_token}",
74
76
  'Content-Type' => 'application/json' })
75
77
  .to_return(status: 200, body: retired_asset.to_json)
76
78
  end
@@ -91,7 +93,7 @@ class TeamdynamixApiTest < ActiveSupport::TestCase
91
93
  context 'Valid Request' do
92
94
  before do
93
95
  stub_request(:post, create_path)
94
- .with(headers: { 'Authorization' => 'Bearer ' + dummy_token,
96
+ .with(headers: { 'Authorization' => "Bearer #{dummy_token}",
95
97
  'Content-Type' => 'application/json' },
96
98
  body: create_payload)
97
99
  .to_return(status: 200, body: sample_asset.to_json)
@@ -112,7 +114,7 @@ class TeamdynamixApiTest < ActiveSupport::TestCase
112
114
  # rubocop:enable Style/StringLiterals
113
115
  before do
114
116
  stub_request(:post, create_path)
115
- .with(headers: { 'Authorization' => 'Bearer ' + dummy_token,
117
+ .with(headers: { 'Authorization' => "Bearer #{dummy_token}",
116
118
  'Content-Type' => 'application/json' },
117
119
  body: create_payload)
118
120
  .to_return(status: 400, body: error_body)
@@ -138,7 +140,7 @@ class TeamdynamixApiTest < ActiveSupport::TestCase
138
140
  let(:error) { { status: "403", msg: "", body: error_body }.to_json }
139
141
  # rubocop:enable Style/StringLiterals
140
142
  before do
141
- stub_request(:post, api_url + '/auth')
143
+ stub_request(:post, "#{api_url}/auth")
142
144
  .with(body: auth_payload)
143
145
  .to_return(status: 403, body: error_body)
144
146
  end
@@ -154,7 +156,7 @@ class TeamdynamixApiTest < ActiveSupport::TestCase
154
156
  context 'Valid Request' do
155
157
  before do
156
158
  stub_request(:get, get_asset_path)
157
- .with(headers: { 'Authorization' => 'Bearer ' + dummy_token })
159
+ .with(headers: { 'Authorization' => "Bearer #{dummy_token}" })
158
160
  .to_return(status: 200, body: sample_asset.to_json)
159
161
  end
160
162
  it 'returns asset json' do
@@ -28,7 +28,7 @@ end
28
28
  def sample_asset_uri
29
29
  api_url = SETTINGS[:teamdynamix][:api][:url]
30
30
  asset_uri = api_url.split('api').first + sample_asset['Uri']
31
- [_('URI'), link_to(sample_asset['Uri'], asset_uri, target: '_blank')]
31
+ [_('URI'), link_to(sample_asset['Uri'], asset_uri, target: '_blank', rel: 'noopener')]
32
32
  end
33
33
 
34
34
  require 'webmock/minitest'
File without changes
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_teamdynamix
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nipendar Tyagi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-19 00:00:00.000000000 Z
11
+ date: 2021-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: deface
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubocop-rails
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: webmock
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -101,7 +115,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
101
115
  requirements:
102
116
  - - ">="
103
117
  - !ruby/object:Gem::Version
104
- version: '0'
118
+ version: 2.5.0
105
119
  required_rubygems_version: !ruby/object:Gem::Requirement
106
120
  requirements:
107
121
  - - ">="
@@ -109,16 +123,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
109
123
  version: '0'
110
124
  requirements: []
111
125
  rubyforge_project:
112
- rubygems_version: 2.6.11
126
+ rubygems_version: 2.7.6
113
127
  signing_key:
114
128
  specification_version: 4
115
129
  summary: Creates TeamDynamix Asset when a host is created in Foreman
116
130
  test_files:
117
- - test/models/host_extensions_test.rb
118
131
  - test/fake_teamdynamix_api.rb
119
- - test/test_plugin_helper.rb
120
- - test/sample_asset.json
121
132
  - test/functional/concerns/hosts_controller_extensions_test.rb
133
+ - test/helpers/concerns/foreman_teamdynamix/hosts_helper_extensions_test.rb
134
+ - test/models/host_extensions_test.rb
135
+ - test/sample_asset.json
122
136
  - test/services/teamdynamix_api_test.rb
137
+ - test/test_plugin_helper.rb
123
138
  - test/unit/foreman_teamdynamix_test.rb
124
- - test/helpers/concerns/foreman_teamdynamix/hosts_helper_extensions_test.rb