foreman_hdm 0.1.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 +7 -0
- data/LICENSE +619 -0
- data/README.md +38 -0
- data/Rakefile +60 -0
- data/app/controllers/foreman_hdm/keys_controller.rb +23 -0
- data/app/services/proxy_api/hdm.rb +16 -0
- data/config/routes.rb +11 -0
- data/db/migrate/20230519125201_add_hdm_proxy_id_to_hosts.rb +5 -0
- data/db/seeds.d/75-hdm_seeds.rb +1 -0
- data/lib/foreman_hdm/engine.rb +48 -0
- data/lib/foreman_hdm/version.rb +3 -0
- data/lib/foreman_hdm.rb +4 -0
- data/lib/tasks/foreman_hdm_tasks.rake +39 -0
- data/locale/Makefile +60 -0
- data/locale/en/foreman_hdm.po +19 -0
- data/locale/foreman_hdm.pot +19 -0
- data/locale/gemspec.rb +2 -0
- data/package.json +44 -0
- data/test/factories/foreman_hdm_factories.rb +5 -0
- data/test/test_plugin_helper.rb +6 -0
- data/test/unit/foreman_hdm_test.rb +11 -0
- data/webpack/global_index.js +30 -0
- data/webpack/global_test_setup.js +11 -0
- data/webpack/index.js +7 -0
- data/webpack/src/Extends/Host/HdmTab/Hierarchies.js +82 -0
- data/webpack/src/Extends/Host/HdmTab/Hierarchy.js +70 -0
- data/webpack/src/Extends/Host/HdmTab/index.js +81 -0
- data/webpack/src/Extends/index.js +15 -0
- data/webpack/src/Router/routes.js +12 -0
- data/webpack/src/reducers.js +7 -0
- data/webpack/test_setup.js +17 -0
- metadata +193 -0
    
        data/Rakefile
    ADDED
    
    | @@ -0,0 +1,60 @@ | |
| 1 | 
            +
            #!/usr/bin/env rake
         | 
| 2 | 
            +
            begin
         | 
| 3 | 
            +
              require 'bundler/setup'
         | 
| 4 | 
            +
            rescue LoadError
         | 
| 5 | 
            +
              puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
         | 
| 6 | 
            +
            end
         | 
| 7 | 
            +
            begin
         | 
| 8 | 
            +
              require 'rdoc/task'
         | 
| 9 | 
            +
            rescue LoadError
         | 
| 10 | 
            +
              require 'rdoc/rdoc'
         | 
| 11 | 
            +
              require 'rake/rdoctask'
         | 
| 12 | 
            +
              RDoc::Task = Rake::RDocTask
         | 
| 13 | 
            +
            end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            RDoc::Task.new(:rdoc) do |rdoc|
         | 
| 16 | 
            +
              rdoc.rdoc_dir = 'rdoc'
         | 
| 17 | 
            +
              rdoc.title    = 'ForemanHdm'
         | 
| 18 | 
            +
              rdoc.options << '--line-numbers'
         | 
| 19 | 
            +
              rdoc.rdoc_files.include('README.rdoc')
         | 
| 20 | 
            +
              rdoc.rdoc_files.include('lib/**/*.rb')
         | 
| 21 | 
            +
            end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            APP_RAKEFILE = File.expand_path('test/dummy/Rakefile', __dir__)
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            Bundler::GemHelper.install_tasks
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            require 'rake/testtask'
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            Rake::TestTask.new(:test) do |t|
         | 
| 30 | 
            +
              t.libs << 'lib'
         | 
| 31 | 
            +
              t.libs << 'test'
         | 
| 32 | 
            +
              t.pattern = 'test/**/*_test.rb'
         | 
| 33 | 
            +
              t.verbose = false
         | 
| 34 | 
            +
            end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            begin
         | 
| 37 | 
            +
              require 'rubocop/rake_task'
         | 
| 38 | 
            +
              RuboCop::RakeTask.new
         | 
| 39 | 
            +
            rescue StandardError => _e
         | 
| 40 | 
            +
              puts 'Rubocop not loaded.'
         | 
| 41 | 
            +
            end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            task :default do
         | 
| 44 | 
            +
              Rake::Task['rubocop'].execute
         | 
| 45 | 
            +
            end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
            begin
         | 
| 48 | 
            +
              require 'github_changelog_generator/task'
         | 
| 49 | 
            +
            rescue LoadError
         | 
| 50 | 
            +
              # github_changelog_generator is an optional group
         | 
| 51 | 
            +
            else
         | 
| 52 | 
            +
              GitHubChangelogGenerator::RakeTask.new :changelog do |config|
         | 
| 53 | 
            +
                version = ForemanHdm::VERSION
         | 
| 54 | 
            +
                config.future_release = "v#{version}" if /^\d+\.\d+.\d+$/.match?(version)
         | 
| 55 | 
            +
                config.header = "# Changelog\n\nAll notable changes to this project will be documented in this file."
         | 
| 56 | 
            +
                config.exclude_labels = %w[duplicate question invalid wontfix wont-fix skip-changelog]
         | 
| 57 | 
            +
                config.user = 'betadots'
         | 
| 58 | 
            +
                config.project = 'foreman_hdm'
         | 
| 59 | 
            +
              end
         | 
| 60 | 
            +
            end
         | 
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            module ForemanHdm
         | 
| 2 | 
            +
              class KeysController < ::ApplicationController
         | 
| 3 | 
            +
                before_action :find_host
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                def index
         | 
| 6 | 
            +
                  render json: proxy.keys(@host)
         | 
| 7 | 
            +
                end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def show
         | 
| 10 | 
            +
                  render json: proxy.key(@host, params[:id])
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                private
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def proxy
         | 
| 16 | 
            +
                  ::ProxyAPI::Hdm.new(url: @host.hdm_proxy.url)
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                def find_host
         | 
| 20 | 
            +
                  @host = ::Host.friendly.find(params[:host_id])
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
            end
         | 
| @@ -0,0 +1,16 @@ | |
| 1 | 
            +
            module ProxyAPI
         | 
| 2 | 
            +
              class Hdm < Resource
         | 
| 3 | 
            +
                def initialize(args)
         | 
| 4 | 
            +
                  @url = "#{args[:url]}/hdm/"
         | 
| 5 | 
            +
                  super
         | 
| 6 | 
            +
                end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                def keys(host)
         | 
| 9 | 
            +
                  get("/nodes/#{host.fqdn}/keys")
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def key(host, key)
         | 
| 13 | 
            +
                  get("/nodes/#{host.fqdn}/keys/#{key}")
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
            end
         | 
    
        data/config/routes.rb
    ADDED
    
    | @@ -0,0 +1,11 @@ | |
| 1 | 
            +
            ForemanHdm::Engine.routes.draw do
         | 
| 2 | 
            +
              constraints(id: %r{[^/]+}, host_id: %r{[^/]+}) do
         | 
| 3 | 
            +
                resources :hosts, only: [], controller: '/hosts' do
         | 
| 4 | 
            +
                  resources :keys, only: %i[index show]
         | 
| 5 | 
            +
                end
         | 
| 6 | 
            +
              end
         | 
| 7 | 
            +
            end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            Foreman::Application.routes.draw do
         | 
| 10 | 
            +
              mount ForemanHdm::Engine, at: '/foreman_hdm'
         | 
| 11 | 
            +
            end
         | 
| @@ -0,0 +1 @@ | |
| 1 | 
            +
            Feature.where(name: 'Hdm').first_or_create
         | 
| @@ -0,0 +1,48 @@ | |
| 1 | 
            +
            module ForemanHdm
         | 
| 2 | 
            +
              class Engine < ::Rails::Engine
         | 
| 3 | 
            +
                isolate_namespace ForemanHdm
         | 
| 4 | 
            +
                engine_name 'foreman_hdm'
         | 
| 5 | 
            +
                # register_gettext
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                config.autoload_paths += Dir["#{config.root}/app/controllers/concerns"]
         | 
| 8 | 
            +
                config.autoload_paths += Dir["#{config.root}/app/helpers/concerns"]
         | 
| 9 | 
            +
                config.autoload_paths += Dir["#{config.root}/app/models/concerns"]
         | 
| 10 | 
            +
                config.autoload_paths += Dir["#{config.root}/app/overrides"]
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                # Add any db migrations
         | 
| 13 | 
            +
                initializer 'foreman_hdm.load_app_instance_data' do |app|
         | 
| 14 | 
            +
                  ForemanHdm::Engine.paths['db/migrate'].existent.each do |path|
         | 
| 15 | 
            +
                    app.config.paths['db/migrate'] << path
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                initializer 'foreman_hdm.register_plugin', :before => :finisher_hook do |_app|
         | 
| 20 | 
            +
                  Foreman::Plugin.register :foreman_hdm do
         | 
| 21 | 
            +
                    requires_foreman '>= 3.4.0'
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                    # Add Global files for extending foreman-core components and routes
         | 
| 24 | 
            +
                    register_global_js_file 'global'
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                    # Add permissions
         | 
| 27 | 
            +
                    security_block :foreman_hdm do
         | 
| 28 | 
            +
                      permission :view_foreman_hdm, { :'foreman_hdm/keys' => %i[index show] }
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                    # Add a new role called 'Discovery' if it doesn't exist
         | 
| 32 | 
            +
                    role 'ForemanHdm', [:view_foreman_hdm]
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                    smart_proxy_for Host, :hdm_proxy,
         | 
| 35 | 
            +
                      feature: 'Hdm',
         | 
| 36 | 
            +
                      label: N_('HDM Proxy'),
         | 
| 37 | 
            +
                      description: N_('Smart proxy to access HDM'),
         | 
| 38 | 
            +
                      api_description: N_('ID of HDM Proxy')
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                rake_tasks do
         | 
| 43 | 
            +
                  Rake::Task['db:seed'].enhance do
         | 
| 44 | 
            +
                    ForemanHdm::Engine.load_seed
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
              end
         | 
| 48 | 
            +
            end
         | 
    
        data/lib/foreman_hdm.rb
    ADDED
    
    
| @@ -0,0 +1,39 @@ | |
| 1 | 
            +
            require 'rake/testtask'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # Tests
         | 
| 4 | 
            +
            namespace :test do
         | 
| 5 | 
            +
              desc 'Test ForemanHdm'
         | 
| 6 | 
            +
              Rake::TestTask.new(:foreman_hdm) do |t|
         | 
| 7 | 
            +
                test_dir = File.expand_path('../../test', __dir__)
         | 
| 8 | 
            +
                t.libs << 'test'
         | 
| 9 | 
            +
                t.libs << test_dir
         | 
| 10 | 
            +
                t.pattern = "#{test_dir}/**/*_test.rb"
         | 
| 11 | 
            +
                t.verbose = true
         | 
| 12 | 
            +
                t.warning = false
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
            end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            namespace :foreman_hdm do
         | 
| 17 | 
            +
              desc 'Lint with rubocop'
         | 
| 18 | 
            +
              task rubocop: :environment do
         | 
| 19 | 
            +
                begin
         | 
| 20 | 
            +
                  require 'rubocop/rake_task'
         | 
| 21 | 
            +
                  RuboCop::RakeTask.new(:rubocop_foreman_hdm) do |task|
         | 
| 22 | 
            +
                    task.patterns = ["#{ForemanHdm::Engine.root}/app/**/*.rb",
         | 
| 23 | 
            +
                                     "#{ForemanHdm::Engine.root}/lib/**/*.rb",
         | 
| 24 | 
            +
                                     "#{ForemanHdm::Engine.root}/test/**/*.rb"]
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
                rescue StandardError
         | 
| 27 | 
            +
                  puts 'Rubocop not loaded.'
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                Rake::Task['rubocop_foreman_hdm'].invoke
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
            end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            Rake::Task[:test].enhance ['test:foreman_hdm']
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            load 'tasks/jenkins.rake'
         | 
| 37 | 
            +
            if Rake::Task.task_defined?(:'jenkins:unit')
         | 
| 38 | 
            +
              Rake::Task['jenkins:unit'].enhance ['test:foreman_hdm', 'foreman_hdm:rubocop']
         | 
| 39 | 
            +
            end
         | 
    
        data/locale/Makefile
    ADDED
    
    | @@ -0,0 +1,60 @@ | |
| 1 | 
            +
            #
         | 
| 2 | 
            +
            # Makefile for PO merging and MO generation. More info in the README.
         | 
| 3 | 
            +
            #
         | 
| 4 | 
            +
            # make all-mo (default) - generate MO files
         | 
| 5 | 
            +
            # make check - check translations using translate-tool
         | 
| 6 | 
            +
            # make tx-update - download and merge translations from Transifex
         | 
| 7 | 
            +
            # make clean - clean everything
         | 
| 8 | 
            +
            #
         | 
| 9 | 
            +
            DOMAIN = foreman_hdm
         | 
| 10 | 
            +
            VERSION = $(shell ruby -e 'require "rubygems";spec = Gem::Specification::load(Dir.glob("../*.gemspec")[0]);puts spec.version')
         | 
| 11 | 
            +
            POTFILE = $(DOMAIN).pot
         | 
| 12 | 
            +
            MOFILE = $(DOMAIN).mo
         | 
| 13 | 
            +
            POFILES = $(shell find . -name '$(DOMAIN).po')
         | 
| 14 | 
            +
            MOFILES = $(patsubst %.po,%.mo,$(POFILES))
         | 
| 15 | 
            +
            POXFILES = $(patsubst %.po,%.pox,$(POFILES))
         | 
| 16 | 
            +
            EDITFILES = $(patsubst %.po,%.edit.po,$(POFILES))
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            %.mo: %.po
         | 
| 19 | 
            +
            	mkdir -p $(shell dirname $@)/LC_MESSAGES
         | 
| 20 | 
            +
            	msgfmt -o $(shell dirname $@)/LC_MESSAGES/$(MOFILE) $<
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            # Generate MO files from PO files
         | 
| 23 | 
            +
            all-mo: $(MOFILES)
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            # Check for malformed strings
         | 
| 26 | 
            +
            %.pox: %.po
         | 
| 27 | 
            +
            	msgfmt -c $<
         | 
| 28 | 
            +
            	pofilter --nofuzzy -t variables -t blank -t urls -t emails -t long -t newlines \
         | 
| 29 | 
            +
            		-t endwhitespace -t endpunc -t puncspacing -t options -t printf -t validchars --gnome $< > $@
         | 
| 30 | 
            +
            	cat $@
         | 
| 31 | 
            +
            	! grep -q msgid $@
         | 
| 32 | 
            +
             | 
| 33 | 
            +
            %.edit.po:
         | 
| 34 | 
            +
            	touch $@
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            check: $(POXFILES)
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            # Unify duplicate translations
         | 
| 39 | 
            +
            uniq-po:
         | 
| 40 | 
            +
            	for f in $(shell find ./ -name "*.po") ; do \
         | 
| 41 | 
            +
            		msguniq $$f -o $$f ; \
         | 
| 42 | 
            +
            	done
         | 
| 43 | 
            +
             | 
| 44 | 
            +
            tx-pull: $(EDITFILES)
         | 
| 45 | 
            +
            	tx pull -f
         | 
| 46 | 
            +
            	for f in $(EDITFILES) ; do \
         | 
| 47 | 
            +
            		sed -i 's/^\("Project-Id-Version: \).*$$/\1$(DOMAIN) $(VERSION)\\n"/' $$f; \
         | 
| 48 | 
            +
            	done
         | 
| 49 | 
            +
             | 
| 50 | 
            +
            tx-update: tx-pull
         | 
| 51 | 
            +
            	@echo
         | 
| 52 | 
            +
            	@echo Run rake plugin:gettext[$(DOMAIN)] from the Foreman installation, then make -C locale mo-files to finish
         | 
| 53 | 
            +
            	@echo
         | 
| 54 | 
            +
             | 
| 55 | 
            +
            mo-files: $(MOFILES)
         | 
| 56 | 
            +
            	git add $(POFILES) $(POTFILE) ../locale/*/LC_MESSAGES
         | 
| 57 | 
            +
            	git commit -m "i18n - pulling from tx"
         | 
| 58 | 
            +
            	@echo
         | 
| 59 | 
            +
            	@echo Changes commited!
         | 
| 60 | 
            +
            	@echo
         | 
| @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            # foreman_hdm
         | 
| 2 | 
            +
            #
         | 
| 3 | 
            +
            # This file is distributed under the same license as foreman_hdm.
         | 
| 4 | 
            +
            #
         | 
| 5 | 
            +
            #, fuzzy
         | 
| 6 | 
            +
            msgid ""
         | 
| 7 | 
            +
            msgstr ""
         | 
| 8 | 
            +
            "Project-Id-Version: version 0.0.1\n"
         | 
| 9 | 
            +
            "Report-Msgid-Bugs-To: \n"
         | 
| 10 | 
            +
            "POT-Creation-Date: 2014-08-20 08:46+0100\n"
         | 
| 11 | 
            +
            "PO-Revision-Date: 2014-08-20 08:54+0100\n"
         | 
| 12 | 
            +
            "Last-Translator: Foreman Team <foreman-dev@googlegroups.com>\n"
         | 
| 13 | 
            +
            "Language-Team: Foreman Team <foreman-dev@googlegroups.com>\n"
         | 
| 14 | 
            +
            "Language: \n"
         | 
| 15 | 
            +
            "MIME-Version: 1.0\n"
         | 
| 16 | 
            +
            "Content-Type: text/plain; charset=UTF-8\n"
         | 
| 17 | 
            +
            "Content-Transfer-Encoding: 8bit\n"
         | 
| 18 | 
            +
            "Plural-Forms: nplurals=2; plural=(n != 1);\n"
         | 
| 19 | 
            +
             | 
| @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            # foreman_hdm
         | 
| 2 | 
            +
            #
         | 
| 3 | 
            +
            # This file is distributed under the same license as foreman_hdm.
         | 
| 4 | 
            +
            #
         | 
| 5 | 
            +
            #, fuzzy
         | 
| 6 | 
            +
            msgid ""
         | 
| 7 | 
            +
            msgstr ""
         | 
| 8 | 
            +
            "Project-Id-Version: version 0.0.1\n"
         | 
| 9 | 
            +
            "Report-Msgid-Bugs-To: \n"
         | 
| 10 | 
            +
            "POT-Creation-Date: 2014-08-20 08:46+0100\n"
         | 
| 11 | 
            +
            "PO-Revision-Date: 2014-08-20 08:46+0100\n"
         | 
| 12 | 
            +
            "Last-Translator: Foreman Team <foreman-dev@googlegroups.com>\n"
         | 
| 13 | 
            +
            "Language-Team: Foreman Team <foreman-dev@googlegroups.com>\n"
         | 
| 14 | 
            +
            "Language: \n"
         | 
| 15 | 
            +
            "MIME-Version: 1.0\n"
         | 
| 16 | 
            +
            "Content-Type: text/plain; charset=UTF-8\n"
         | 
| 17 | 
            +
            "Content-Transfer-Encoding: 8bit\n"
         | 
| 18 | 
            +
            "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
         | 
| 19 | 
            +
             | 
    
        data/locale/gemspec.rb
    ADDED
    
    
    
        data/package.json
    ADDED
    
    | @@ -0,0 +1,44 @@ | |
| 1 | 
            +
            {
         | 
| 2 | 
            +
              "name": "foreman_hdm",
         | 
| 3 | 
            +
              "version": "1.0.0",
         | 
| 4 | 
            +
              "description": "DESCRIPTION",
         | 
| 5 | 
            +
              "main": "index.js",
         | 
| 6 | 
            +
              "scripts": {
         | 
| 7 | 
            +
                "lint": "tfm-lint --plugin -d /webpack",
         | 
| 8 | 
            +
                "test": "tfm-test --config jest.config.js",
         | 
| 9 | 
            +
                "test:watch": "tfm-test --plugin --watchAll",
         | 
| 10 | 
            +
                "test:current": "tfm-test --plugin --watch",
         | 
| 11 | 
            +
                "publish-coverage": "tfm-publish-coverage",
         | 
| 12 | 
            +
                "stories": "tfm-stories --plugin",
         | 
| 13 | 
            +
                "stories:build": "tfm-build-stories --plugin",
         | 
| 14 | 
            +
                "create-react-component": "yo react-domain"
         | 
| 15 | 
            +
              },
         | 
| 16 | 
            +
              "repository": {
         | 
| 17 | 
            +
                "type": "git",
         | 
| 18 | 
            +
                "url": "git+https://github.com/theforeman/foreman_hdm.git"
         | 
| 19 | 
            +
              },
         | 
| 20 | 
            +
              "bugs": {
         | 
| 21 | 
            +
                "url": "http://projects.theforeman.org/projects/foreman_hdm/issues"
         | 
| 22 | 
            +
              },
         | 
| 23 | 
            +
              "peerDependencies": {
         | 
| 24 | 
            +
                "@theforeman/vendor": ">= 6.0.0"
         | 
| 25 | 
            +
              },
         | 
| 26 | 
            +
              "dependencies": {
         | 
| 27 | 
            +
                "react-intl": "^2.8.0"
         | 
| 28 | 
            +
              },
         | 
| 29 | 
            +
              "devDependencies": {
         | 
| 30 | 
            +
                "@babel/core": "^7.7.0",
         | 
| 31 | 
            +
                "@sheerun/mutationobserver-shim": "^0.3.3",
         | 
| 32 | 
            +
                "@theforeman/builder": "^6.0.0",
         | 
| 33 | 
            +
                "@theforeman/eslint-plugin-foreman": "6.0.0",
         | 
| 34 | 
            +
                "@theforeman/find-foreman": "^4.8.0",
         | 
| 35 | 
            +
                "@theforeman/stories": "^7.0.0",
         | 
| 36 | 
            +
                "@theforeman/test": "^8.0.0",
         | 
| 37 | 
            +
                "@theforeman/vendor-dev": "^6.0.0",
         | 
| 38 | 
            +
                "babel-eslint": "^10.0.3",
         | 
| 39 | 
            +
                "eslint": "^6.7.2",
         | 
| 40 | 
            +
                "prettier": "^1.19.1",
         | 
| 41 | 
            +
                "stylelint-config-standard": "^18.0.0",
         | 
| 42 | 
            +
                "stylelint": "^9.3.0"
         | 
| 43 | 
            +
              }
         | 
| 44 | 
            +
            }
         | 
| @@ -0,0 +1,30 @@ | |
| 1 | 
            +
            import React from 'react';
         | 
| 2 | 
            +
            import { registerReducer } from 'foremanReact/common/MountingService';
         | 
| 3 | 
            +
            import { addGlobalFill } from 'foremanReact/components/common/Fill/GlobalFill';
         | 
| 4 | 
            +
            import { registerRoutes } from 'foremanReact/routes/RoutingService';
         | 
| 5 | 
            +
            import Routes from './src/Router/routes'
         | 
| 6 | 
            +
            import reducers from './src/reducers';
         | 
| 7 | 
            +
            import HdmTab from './src/Extends/Host/HdmTab';
         | 
| 8 | 
            +
            import "./src/Extends/index";
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            // register reducers
         | 
| 11 | 
            +
            Object.entries(reducers).forEach(([key, reducer]) =>
         | 
| 12 | 
            +
                registerReducer(key, reducer)
         | 
| 13 | 
            +
            );
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            // register client routes
         | 
| 16 | 
            +
            registerRoutes('PluginHdm', Routes);
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            // register fills for extending foreman core
         | 
| 19 | 
            +
            // http://foreman.surge.sh/?path=/docs/introduction-slot-and-fill--page
         | 
| 20 | 
            +
            // addGlobalFill('<slotId>', '<fillId>', <div key='plugin-template-example' />, 300);
         | 
| 21 | 
            +
            addGlobalFill(
         | 
| 22 | 
            +
              "host-details-page-tabs",
         | 
| 23 | 
            +
              "HDM",
         | 
| 24 | 
            +
              <HdmTab key="hdm-fill-root" />,
         | 
| 25 | 
            +
              490,
         | 
| 26 | 
            +
              {
         | 
| 27 | 
            +
                title: __('HDM'),
         | 
| 28 | 
            +
                hideTab: ({hostDetails}) => (hostDetails.hdm_proxy == null)
         | 
| 29 | 
            +
              }, 
         | 
| 30 | 
            +
            );
         | 
| @@ -0,0 +1,11 @@ | |
| 1 | 
            +
            // runs before each test to make sure console.error output will
         | 
| 2 | 
            +
            // fail a test (i.e. default PropType missing). Check the error
         | 
| 3 | 
            +
            // output and traceback for actual error.
         | 
| 4 | 
            +
            global.console.error = (error, stack) => {
         | 
| 5 | 
            +
                /* eslint-disable-next-line no-console */
         | 
| 6 | 
            +
                if (stack) console.log(stack); // Prints out original stack trace
         | 
| 7 | 
            +
                throw new Error(error);
         | 
| 8 | 
            +
            };
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            // Increase jest timeout as some tests using multiple http mocks can time out on CI systems.
         | 
| 11 | 
            +
            jest.setTimeout(10000);
         | 
    
        data/webpack/index.js
    ADDED
    
    
| @@ -0,0 +1,82 @@ | |
| 1 | 
            +
            import React from 'react';
         | 
| 2 | 
            +
            import PropTypes from 'prop-types';
         | 
| 3 | 
            +
            import { STATUS } from 'foremanReact/constants';
         | 
| 4 | 
            +
            import { Divider, EmptyStateIcon, Title } from '@patternfly/react-core';
         | 
| 5 | 
            +
            import { ExclamationCircleIcon } from '@patternfly/react-icons';
         | 
| 6 | 
            +
            import EmptyState from 'foremanReact/components/common/EmptyState/EmptyStatePattern';
         | 
| 7 | 
            +
            import { global_danger_color_200 as dangerColor } from '@patternfly/react-tokens';
         | 
| 8 | 
            +
            import Skeleton from 'react-loading-skeleton';
         | 
| 9 | 
            +
            import { useAPI } from 'foremanReact/common/hooks/API/APIHooks';
         | 
| 10 | 
            +
            import Hierarchy from './Hierarchy';
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            const Hierarchies = ({ hostname, keyName }) => {
         | 
| 13 | 
            +
              let hierarchies = [];
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              if (keyName) {
         | 
| 16 | 
            +
                const url = `${window.location.origin.toString()}/foreman_hdm/hosts/${hostname}/keys/${keyName}`;
         | 
| 17 | 
            +
                const { response, status } = useAPI('get', url);
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                if (status === STATUS.PENDING) {
         | 
| 20 | 
            +
                  return <Skeleton count={5} />;
         | 
| 21 | 
            +
                }
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                if (status === STATUS.ERROR) {
         | 
| 24 | 
            +
                  const description = __('Could not fetch HDM data.');
         | 
| 25 | 
            +
                  const icon = (
         | 
| 26 | 
            +
                    <EmptyStateIcon icon={ExclamationCircleIcon} color={dangerColor.value} />
         | 
| 27 | 
            +
                  );
         | 
| 28 | 
            +
                  return (
         | 
| 29 | 
            +
                    <EmptyState header={__('Error!')} icon={icon} description={description} />
         | 
| 30 | 
            +
                  );
         | 
| 31 | 
            +
                }
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                if (Array.isArray(response)) {
         | 
| 34 | 
            +
                  hierarchies = response.map((item) => {
         | 
| 35 | 
            +
                    return (
         | 
| 36 | 
            +
                      <div keyName={item.hierarchy_name}>
         | 
| 37 | 
            +
                        <Hierarchy hierarchy={item} />
         | 
| 38 | 
            +
                      </div>
         | 
| 39 | 
            +
                    );
         | 
| 40 | 
            +
                  });
         | 
| 41 | 
            +
                }
         | 
| 42 | 
            +
              }
         | 
| 43 | 
            +
             | 
| 44 | 
            +
              const header = () => {
         | 
| 45 | 
            +
                if (keyName) {
         | 
| 46 | 
            +
                  const prefix = __("Key: ");
         | 
| 47 | 
            +
                  return (
         | 
| 48 | 
            +
                    <div>
         | 
| 49 | 
            +
                      <Title headingLevel="h2">
         | 
| 50 | 
            +
                        <b>{prefix}</b>
         | 
| 51 | 
            +
                        {keyName}
         | 
| 52 | 
            +
                      </Title>
         | 
| 53 | 
            +
                      <Divider className="pf-u-mb-md" />
         | 
| 54 | 
            +
                    </div>
         | 
| 55 | 
            +
                  );
         | 
| 56 | 
            +
                } else {
         | 
| 57 | 
            +
                  const message = __("Please select a key from the list on the left.");
         | 
| 58 | 
            +
                  return (
         | 
| 59 | 
            +
                    <EmptyState header={__('No key selected')} description={message} />
         | 
| 60 | 
            +
                  );
         | 
| 61 | 
            +
                }
         | 
| 62 | 
            +
              }
         | 
| 63 | 
            +
             | 
| 64 | 
            +
              return (
         | 
| 65 | 
            +
                <div>
         | 
| 66 | 
            +
                  {header()}
         | 
| 67 | 
            +
                  {hierarchies}
         | 
| 68 | 
            +
                </div>
         | 
| 69 | 
            +
              );
         | 
| 70 | 
            +
            };
         | 
| 71 | 
            +
             | 
| 72 | 
            +
            Hierarchies.propTypes = {
         | 
| 73 | 
            +
              hostname: PropTypes.string,
         | 
| 74 | 
            +
              keyName: PropTypes.string
         | 
| 75 | 
            +
            };
         | 
| 76 | 
            +
             | 
| 77 | 
            +
            Hierarchies.defaultProps = {
         | 
| 78 | 
            +
              hostname: "",
         | 
| 79 | 
            +
              keyName: null
         | 
| 80 | 
            +
            };
         | 
| 81 | 
            +
             | 
| 82 | 
            +
            export default Hierarchies;
         | 
| @@ -0,0 +1,70 @@ | |
| 1 | 
            +
            import React from 'react';
         | 
| 2 | 
            +
            import { Accordion, AccordionItem, AccordionContent, AccordionToggle, AccordionExpandedContentBody, CodeBlock, CodeBlockCode, Title } from '@patternfly/react-core';
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            const Hierarchy = ({ hierarchy }) => {
         | 
| 5 | 
            +
              const [expanded, setExpanded] = React.useState([]);
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              const toggle = id => {
         | 
| 8 | 
            +
                const index = expanded.indexOf(id);
         | 
| 9 | 
            +
                const newExpanded =
         | 
| 10 | 
            +
                  index >= 0 ? [...expanded.slice(0, index), ...expanded.slice(index + 1, expanded.length)] : [...expanded, id];
         | 
| 11 | 
            +
                setExpanded(newExpanded);
         | 
| 12 | 
            +
              };
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              const valueContent = (value) => {
         | 
| 15 | 
            +
                if (value) {
         | 
| 16 | 
            +
                  return (
         | 
| 17 | 
            +
                    <CodeBlock>
         | 
| 18 | 
            +
                      <CodeBlockCode>{value}</CodeBlockCode>
         | 
| 19 | 
            +
                    </CodeBlock>
         | 
| 20 | 
            +
                  );
         | 
| 21 | 
            +
                } else {
         | 
| 22 | 
            +
                  const message = __("No value present");
         | 
| 23 | 
            +
                  return (<div>{message}</div>);
         | 
| 24 | 
            +
                }
         | 
| 25 | 
            +
              };
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              const formattedPath = (file) => {
         | 
| 28 | 
            +
                if (file.value) {
         | 
| 29 | 
            +
                  return (
         | 
| 30 | 
            +
                    <span>{file.path}</span>
         | 
| 31 | 
            +
                  );
         | 
| 32 | 
            +
                } else {
         | 
| 33 | 
            +
                  return (
         | 
| 34 | 
            +
                    <em className="pf-u-disabled-color-100">{file.path}</em>
         | 
| 35 | 
            +
                  );
         | 
| 36 | 
            +
                }
         | 
| 37 | 
            +
              };
         | 
| 38 | 
            +
             | 
| 39 | 
            +
              const accordionItems = hierarchy.files.map((file) => {
         | 
| 40 | 
            +
                const value = valueContent(file.value);
         | 
| 41 | 
            +
                const id = `${file.path}-toggle`;
         | 
| 42 | 
            +
                const path = formattedPath(file);
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                return (
         | 
| 45 | 
            +
                  <AccordionItem>
         | 
| 46 | 
            +
                    <AccordionToggle
         | 
| 47 | 
            +
                      onClick={() => toggle(id)}
         | 
| 48 | 
            +
                      isExpanded={expanded.includes(id)}
         | 
| 49 | 
            +
                      id={id}
         | 
| 50 | 
            +
                    >
         | 
| 51 | 
            +
                      {path}
         | 
| 52 | 
            +
                    </AccordionToggle>
         | 
| 53 | 
            +
                    <AccordionContent id={`${id}-content`} isHidden={!expanded.includes(id)} isFixed>
         | 
| 54 | 
            +
                      {value}
         | 
| 55 | 
            +
                    </AccordionContent>
         | 
| 56 | 
            +
                  </AccordionItem>
         | 
| 57 | 
            +
                );
         | 
| 58 | 
            +
              });
         | 
| 59 | 
            +
              return (
         | 
| 60 | 
            +
                <div className="pf-u-mb-sm">
         | 
| 61 | 
            +
                  <Title headingLevel="h3">{hierarchy.hierarchy_name}</Title>
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                  <Accordion isBordered>
         | 
| 64 | 
            +
                    {accordionItems}
         | 
| 65 | 
            +
                  </Accordion>
         | 
| 66 | 
            +
                </div>
         | 
| 67 | 
            +
              );
         | 
| 68 | 
            +
            };
         | 
| 69 | 
            +
             | 
| 70 | 
            +
            export default Hierarchy;
         |