Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Foreman >= 3.9 #62

Merged
merged 1 commit into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 27 additions & 78 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,85 +1,34 @@
name: CI
on: [push, pull_request]
env:
RAILS_ENV: test
DATABASE_URL: postgresql://postgres:@localhost/test
DATABASE_CLEANER_ALLOW_REMOTE_DATABASE_URL: true
name: Ruby test

on:
pull_request:
push:
branches:
- master

concurrency:
group: ${{ github.ref_name }}-${{ github.workflow }}
cancel-in-progress: true

jobs:
rubocop:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 2.7
- name: Setup
run: |
gem install bundler
echo "gem 'rdoc', '< 6.4'" >> Gemfile
bundle install --jobs=3 --retry=3
- name: Run rubocop
run: bundle exec rubocop
uses: theforeman/actions/.github/workflows/rubocop.yml@v0
with:
command: bundle exec rubocop --parallel --format github

test:
runs-on: ubuntu-latest
name: Ruby
needs: rubocop
services:
postgres:
image: postgres:12.1
ports: ['5432:5432']
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
strategy:
fail-fast: false
matrix:
foreman-core-branch: [3.1-stable, 3.2-stable, 3.3-stable, 3.4-stable, 3.5-stable, 3.6-stable, develop]
ruby-version: [2.7]
node-version: [14]
steps:
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install build-essential libcurl4-openssl-dev libvirt-dev ruby-libvirt zlib1g-dev libpq-dev
- uses: actions/checkout@v3
with:
repository: theforeman/foreman
ref: ${{ matrix.foreman-core-branch }}
- uses: actions/checkout@v3
with:
path: foreman_vault
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby-version }}
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: Setup Bundler
run: |
gem install bundler
bundle config path vendor/bundle
bundle config set without journald development console mysql2 sqlite
echo "gem 'foreman_vault', path: './foreman_vault'" > bundler.d/foreman_vault.local.rb
bundle lock --update
- name: Cache gems
uses: actions/cache@v3
with:
path: vendor/bundle
key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-gems-
- name: Setup Plugin
run: |
bundle install --jobs=3 --retry=3
bundle exec rake db:create
bundle exec rake db:migrate
npm install
bundle exec rake webpack:compile
- name: Run plugin tests
run: |
bundle exec rake test:foreman_vault
bundle exec rake test TEST="test/unit/foreman/access_permissions_test.rb"
- name: Precompile plugin assets
run: bundle exec rake 'plugin:assets:precompile[foreman_vault]'
env:
RAILS_ENV: production
foreman:
- "develop"
- "3.10-stable"
- "3.9-stable"
uses: theforeman/actions/.github/workflows/foreman_plugin.yml@v0
with:
plugin: foreman_vault
foreman_version: ${{ matrix.foreman }}
environment_variables: |
FOREMAN_VERSION=${{ matrix.foreman }}
14 changes: 8 additions & 6 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
AllCops:
TargetRubyVersion: 2.3
TargetRailsVersion: 5.1
Exclude:
- 'Rakefile'
inherit_gem:
theforeman-rubocop:
- default.yml

Rails:
Enabled: true
Expand All @@ -11,7 +9,7 @@ Rails:
Style/Documentation:
Enabled: false

Metrics/LineLength:
Layout/LineLength:
Max: 190

Metrics/ParameterLists:
Expand All @@ -34,6 +32,10 @@ Metrics/BlockLength:
- lib/foreman_vault/engine.rb
- 'test/**/*'

Style/FrozenStringLiteralComment:
Exclude:
- Rakefile

Metrics/ClassLength:
Exclude:
- 'test/**/*'
Expand Down
4 changes: 2 additions & 2 deletions Rakefile
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ RDoc::Task.new(:rdoc) do |rdoc|
rdoc.rdoc_files.include('lib/**/*.rb')
end

APP_RAKEFILE = File.expand_path('../test/dummy/Rakefile', __FILE__)
APP_RAKEFILE = File.expand_path('test/dummy/Rakefile', __dir__)

Bundler::GemHelper.install_tasks

Expand All @@ -38,7 +38,7 @@ task default: :test
begin
require 'rubocop/rake_task'
RuboCop::RakeTask.new
rescue => _
rescue StandardError => _e
puts 'Rubocop not loaded.'
end

Expand Down
3 changes: 2 additions & 1 deletion app/controllers/api/v2/vault_connections_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ def index

api :GET, '/vault_connections/:id', N_('Show VaultConnection details')
param :id, :identifier, required: true
def show; end
def show
end

def_param_group :vault_connection do
param :vault_connection, Hash, action_aware: true, required: true do
Expand Down
3 changes: 2 additions & 1 deletion app/controllers/vault_connections_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ def create
end
end

def edit; end
def edit
end

def update
if @vault_connection.update(vault_connection_params)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def queue_vault_push
return unless vault_auth_method.valid?

queue.create(name: _('Push %s data to Vault') % self, priority: 100,
action: [self, :set_vault])
action: [self, :set_vault])
end

def queue_vault_destroy
Expand All @@ -30,10 +30,9 @@ def queue_vault_destroy
return unless vault_auth_method.valid?

queue.create(name: _('Clear %s Vault data') % self, priority: 60,
action: [self, :del_vault])
action: [self, :del_vault])
end

# rubocop:disable Metrics/AbcSize
def set_vault
logger.info "Pushing #{name} data to Vault"

Expand All @@ -44,7 +43,6 @@ def set_vault
Foreman::Logging.exception("Failed to push #{name} data to Vault.", e)
failure format(_('Failed to push %{name} data to Vault: %{message}\n '), name: name, message: e.message), e
end
# rubocop:enable Metrics/AbcSize

def del_vault
logger.info "Clearing #{name} Vault data"
Expand Down
6 changes: 3 additions & 3 deletions app/models/vault_connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class VaultConnection < ApplicationRecord
validates :name, presence: true, uniqueness: true
validates :name, inclusion: { in: ->(i) { [i.name_was] }, message: _('cannot be changed after creation') }, on: :update
validates :url, presence: true
validates :url, format: URI.regexp(['http', 'https'])
validates :url, format: URI::DEFAULT_PARSER.make_regexp(['http', 'https'])

validates :token, presence: true, if: -> { role_id.nil? || secret_id.nil? }
validates :token, inclusion: { in: [nil], message: _('AppRole or token must be blank') }, unless: -> { role_id.nil? || secret_id.nil? }
Expand All @@ -25,8 +25,8 @@ class VaultConnection < ApplicationRecord
scope :with_valid_token, -> { with_token.where(vault_error: nil).where('expire_time > ?', Time.zone.now) }

delegate :fetch_expire_time, :fetch_secret, :issue_certificate,
:policy, :policies, :put_policy, :delete_policy,
:set_certificate, :certificates, :delete_certificate, to: :client
:policy, :policies, :put_policy, :delete_policy,
:set_certificate, :certificates, :delete_certificate, to: :client

def with_token?
token.present?
Expand Down
3 changes: 2 additions & 1 deletion app/services/foreman_vault/vault_auth_method.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def delete
private

attr_reader :host

delegate :vault_policy, :vault_connection, :fqdn, to: :host
delegate :name, to: :vault_policy, prefix: true
delegate :set_certificate, :delete_certificate, to: :vault_connection
Expand All @@ -39,7 +40,7 @@ def options
{
certificate: certificate,
token_policies: vault_policy_name,
allowed_common_names: allowed_common_names
allowed_common_names: allowed_common_names,
}
end

Expand Down
1 change: 1 addition & 0 deletions app/services/foreman_vault/vault_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def delete
private

attr_reader :host

delegate :params, :render_template, :vault_connection, to: :host
delegate :policy, :policies, :put_policy, :delete_policy, to: :vault_connection

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

class FixVaultSettingsCategoryToDsl < ActiveRecord::Migration[6.0]
def up
# rubocop:disable Rails/SkipsModelValidations
Setting.where(category: 'Setting::Vault').update_all(category: 'Setting') if column_exists?(:settings, :category)
# rubocop:enable Rails/SkipsModelValidations
end
end
4 changes: 2 additions & 2 deletions db/seeds.d/103-provisioning_templates.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
{
name: 'Default Vault Policy',
source: 'VaultPolicy/default.erb',
template_kind: TemplateKind.find_or_create_by(name: 'VaultPolicy')
}
template_kind: TemplateKind.find_or_create_by(name: 'VaultPolicy'),
},
]

templates.each do |template|
Expand Down
4 changes: 3 additions & 1 deletion foreman_vault.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ Gem::Specification.new do |s|
s.files = Dir['{app,config,db,lib,locale}/**/*'] + ['LICENSE', 'Rakefile', 'README.md']
s.test_files = Dir['test/**/*']

s.required_ruby_version = '>= 2.5', '< 4'

s.add_dependency 'vault', '~> 0.1'

s.add_development_dependency 'rdoc'
s.add_development_dependency 'rubocop', '0.54.0'
s.add_development_dependency 'theforeman-rubocop', '~> 0.1.2'
end
46 changes: 22 additions & 24 deletions lib/foreman_vault/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,24 +40,24 @@ class Engine < ::Rails::Engine
settings do
category(:vault, N_('Vault')) do
setting('vault_connection',
full_name: N_('Default Vault connection'),
type: :string,
description: N_('Default Vault Connection that can be override using parameters'),
default: VaultConnection.table_exists? && VaultConnection.unscoped.count == 1 ? VaultConnection.unscoped.first.name : nil,
collection: VaultConnection.table_exists? ? proc { Hash[VaultConnection.unscoped.all.map { |vc| [vc.name, vc.name] }] } : [],
include_blank: _('Select Vault Connection'))
full_name: N_('Default Vault connection'),
type: :string,
description: N_('Default Vault Connection that can be override using parameters'),
default: VaultConnection.table_exists? && VaultConnection.unscoped.count == 1 ? VaultConnection.unscoped.first.name : nil,
collection: VaultConnection.table_exists? ? proc { Hash[VaultConnection.unscoped.all.map { |vc| [vc.name, vc.name] }] } : [],
include_blank: _('Select Vault Connection'))
setting('vault_policy_template',
full_name: N_('Vault Policy template name'),
type: :string,
description: N_('The name of the ProvisioningTemplate that will be used for Vault Policy'),
default: ProvisioningTemplate.unscoped.of_kind(:VaultPolicy).find_by(name: 'Default Vault Policy')&.name,
collection: proc { Hash[ProvisioningTemplate.unscoped.of_kind(:VaultPolicy).map { |tmpl| [tmpl.name, tmpl.name] }] },
include_blank: _('Select Template'))
full_name: N_('Vault Policy template name'),
type: :string,
description: N_('The name of the ProvisioningTemplate that will be used for Vault Policy'),
default: ProvisioningTemplate.unscoped.of_kind(:VaultPolicy).find_by(name: 'Default Vault Policy')&.name,
collection: proc { Hash[ProvisioningTemplate.unscoped.of_kind(:VaultPolicy).map { |tmpl| [tmpl.name, tmpl.name] }] },
include_blank: _('Select Template'))
setting('vault_orchestration_enabled',
full_name: N_('Vault Orchestration enabled'),
type: :boolean,
description: N_('Enable or disable the Vault orchestration step for managing policies and auth methods'),
default: false)
full_name: N_('Vault Orchestration enabled'),
type: :boolean,
description: N_('Enable or disable the Vault orchestration step for managing policies and auth methods'),
default: false)
end
end

Expand All @@ -69,14 +69,12 @@ class Engine < ::Rails::Engine
end

config.to_prepare do
begin
::Host::Managed.include(ForemanVault::HostExtensions)
::ProvisioningTemplate.include(ForemanVault::ProvisioningTemplateExtensions)
::Foreman::Renderer::Scope::Base.include(ForemanVault::Macros)
::Foreman::Renderer.configure { |c| c.allowed_generic_helpers += [:vault_secret, :vault_issue_certificate] }
rescue StandardError => e
Rails.logger.warn "ForemanVault: skipping engine hook (#{e})"
end
::Host::Managed.include(ForemanVault::HostExtensions)
::ProvisioningTemplate.include(ForemanVault::ProvisioningTemplateExtensions)
::Foreman::Renderer::Scope::Base.include(ForemanVault::Macros)
::Foreman::Renderer.configure { |c| c.allowed_generic_helpers += [:vault_secret, :vault_issue_certificate] }
rescue StandardError => e
Rails.logger.warn "ForemanVault: skipping engine hook (#{e})"
end

initializer 'foreman_vault.register_gettext', after: :load_config_initializers do |_app|
Expand Down
Loading