This repository has been archived by the owner on Feb 22, 2024. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit abc52d8
Showing
15 changed files
with
1,007 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
.bundle/ | ||
log/*.log | ||
pkg/ | ||
test/dummy/db/*.sqlite3 | ||
test/dummy/log/*.log | ||
test/dummy/tmp/ | ||
test/dummy/.sass-cache | ||
locale/*.mo | ||
locale/*/*.edit.po | ||
locale/*/*.po.time_stamp | ||
locale/*/*.pox | ||
Gemfile.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
Rails: | ||
Enabled: true | ||
|
||
# Don't enforce documentation | ||
Style/Documentation: | ||
Enabled: false | ||
|
||
Rails/ActionFilter: | ||
EnforcedStyle: action | ||
|
||
Metrics/MethodLength: | ||
Max: 20 | ||
|
||
Style/Next: | ||
Enabled: false | ||
|
||
# Support both ruby19 and hash_rockets | ||
Style/HashSyntax: | ||
Enabled: false | ||
|
||
Metrics/ClassLength: | ||
Exclude: | ||
- 'test/**/*' | ||
|
||
Performance/FixedSize: | ||
Exclude: | ||
- 'test/**/*' | ||
|
||
Metrics/LineLength: | ||
Max: 100 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
source 'https://rubygems.org' | ||
|
||
gemspec |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# ForemanUserdata | ||
|
||
This plug-in adds a user-data endpoint to [The Foreman](https://theforeman.org/) for usage with cloud-init. | ||
|
||
## Compatibility | ||
|
||
| Foreman Version | Plugin Version | | ||
| --------------- | -------------- | | ||
| >= 1.12 | any | | ||
|
||
## Installation | ||
|
||
See [Plugins install instructions](https://theforeman.org/plugins/) | ||
for how to install Foreman plugins. | ||
You need to install the package `tfm-rubygem-foreman_userdata`. | ||
|
||
## Client setup | ||
|
||
On RHEL7 using cloud-init from EPEL: | ||
|
||
``` | ||
yum install cloud-init -y | ||
cat << EOF > /etc/cloud/cloud.cfg.d/10_foreman.cfg | ||
datasource_list: [NoCloud] | ||
datasource: | ||
NoCloud: | ||
seedfrom: http://foreman.example.com/userdata/ | ||
EOF | ||
``` | ||
|
||
## Client debug | ||
|
||
``` | ||
# Purge all cloud-init data | ||
rm -rf /var/lib/cloud/* | ||
# Run in foreground with debug mode enabled | ||
/usr/bin/cloud-init -d init | ||
``` | ||
|
||
## Copyright | ||
|
||
Copyright (c) 2016 Timo Goebel | ||
|
||
This program is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 3 of the License, or | ||
(at your option) any later version. | ||
|
||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
|
||
You should have received a copy of the GNU General Public License | ||
along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#!/usr/bin/env rake | ||
begin | ||
require 'bundler/setup' | ||
rescue LoadError | ||
puts 'You must `gem install bundler` and `bundle install` to run rake tasks' | ||
end | ||
begin | ||
require 'rdoc/task' | ||
rescue LoadError | ||
require 'rdoc/rdoc' | ||
require 'rake/rdoctask' | ||
RDoc::Task = Rake::RDocTask | ||
end | ||
|
||
RDoc::Task.new(:rdoc) do |rdoc| | ||
rdoc.rdoc_dir = 'rdoc' | ||
rdoc.title = 'ForemanUserdata' | ||
rdoc.options << '--line-numbers' | ||
rdoc.rdoc_files.include('README.rdoc') | ||
rdoc.rdoc_files.include('lib/**/*.rb') | ||
end | ||
|
||
APP_RAKEFILE = File.expand_path('../test/dummy/Rakefile', __FILE__) | ||
|
||
Bundler::GemHelper.install_tasks | ||
|
||
require 'rake/testtask' | ||
|
||
Rake::TestTask.new(:test) do |t| | ||
t.libs << 'lib' | ||
t.libs << 'test' | ||
t.pattern = 'test/**/*_test.rb' | ||
t.verbose = false | ||
end | ||
|
||
task default: :test | ||
|
||
begin | ||
require 'rubocop/rake_task' | ||
RuboCop::RakeTask.new | ||
rescue => _ | ||
puts 'Rubocop not loaded.' | ||
end | ||
|
||
task :default do | ||
Rake::Task['rubocop'].execute | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
class UserdataController < ApplicationController | ||
# Skip default filters for user-data | ||
FILTERS = [ | ||
:require_login, | ||
:session_expiry, | ||
:update_activity_time, | ||
:set_taxonomy, | ||
:authorize, | ||
:verify_authenticity_token | ||
].freeze | ||
|
||
FILTERS.each do |f| | ||
skip_before_action f | ||
end | ||
|
||
before_action :skip_secure_headers | ||
before_action :find_host | ||
|
||
def userdata | ||
template = render_userdata_template | ||
render :plain => template if template | ||
end | ||
|
||
def metadata | ||
render :plain => '' | ||
end | ||
|
||
private | ||
|
||
def render_userdata_template | ||
template = @host.provisioning_template(:kind => 'user_data') | ||
unless template | ||
render_error( | ||
:message => 'Unable to find user-data template for host %{host} running %{os}', | ||
:status => :not_found, | ||
:host => @host.name, | ||
:os => @host.operatingsystem | ||
) | ||
return | ||
end | ||
safe_render(template) | ||
end | ||
|
||
def safe_render(template) | ||
@host.render_template(template) | ||
rescue StandardError => error | ||
Foreman::Logging.exception("Error rendering the #{template.name} template", error) | ||
render_error( | ||
:message => 'There was an error rendering the %{name} template: %{error}', | ||
:name => template.name, | ||
:error => error.message, | ||
:status => :internal_server_error | ||
) | ||
return false | ||
end | ||
|
||
def skip_secure_headers | ||
SecureHeaders.opt_out_of_all_protection(request) | ||
end | ||
|
||
def render_error(options) | ||
message = options.delete(:message) | ||
status = options.delete(:status) || :not_found | ||
logger.error message % options | ||
render :plain => "#{message % options}\n", :status => status | ||
end | ||
|
||
def find_host | ||
@host = find_host_by_ip | ||
return true if @host | ||
render_error( | ||
:message => 'Could not find host for request %{request_ip}', | ||
:status => :not_found, | ||
:request_ip => ip_from_request_env | ||
) | ||
false | ||
end | ||
|
||
def find_host_by_ip | ||
# try to find host based on our client ip address | ||
ip = ip_from_request_env | ||
|
||
# in case we got back multiple ips (see #1619) | ||
ip = ip.split(',').first | ||
|
||
# host is readonly because of association so we reload it if we find it | ||
host = Host.joins(:provision_interface).where(:nics => { :ip => ip }).first | ||
host ? Host.find(host.id) : nil | ||
end | ||
|
||
def ip_from_request_env | ||
ip = request.env['REMOTE_ADDR'] | ||
|
||
# check if someone is asking on behalf of another system (load balancer etc) | ||
if request.env['HTTP_X_FORWARDED_FOR'].present? && (ip =~ Regexp.new(Setting[:remote_addr])) | ||
ip = request.env['HTTP_X_FORWARDED_FOR'] | ||
end | ||
|
||
ip | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Rails.application.routes.draw do | ||
get 'userdata/meta-data', :controller => 'userdata', :action => 'metadata', :format => 'text' | ||
get 'userdata/user-data', :controller => 'userdata', :action => 'userdata', :format => 'text' | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
require File.expand_path('../lib/foreman_userdata/version', __FILE__) | ||
require 'date' | ||
|
||
Gem::Specification.new do |s| | ||
s.name = 'foreman_userdata' | ||
s.version = ForemanUserdata::VERSION | ||
# rubocop:disable Date | ||
s.date = Date.today.to_s | ||
# rubocop:enable Date | ||
s.authors = ['Timo Goebel'] | ||
s.email = ['mail@timogoebel.name'] | ||
s.homepage = 'http://github.com/theforeman/foreman_userdata' | ||
s.licenses = ['GPL-3'] | ||
s.summary = 'This plug-in adds support for serving user-data for cloud-init to The Foreman.' | ||
# also update locale/gemspec.rb | ||
s.description = 'This plug-in adds support for serving user-data for cloud-init to The Foreman.' | ||
|
||
s.files = Dir['{app,config,db,lib,locale}/**/*'] + ['LICENSE', 'Rakefile', 'README.md'] | ||
s.test_files = Dir['test/**/*'] | ||
|
||
s.add_development_dependency 'rubocop' | ||
s.add_development_dependency 'rdoc' | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
require 'foreman_userdata/engine' | ||
|
||
module ForemanUserdata | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
module ForemanUserdata | ||
class Engine < ::Rails::Engine | ||
engine_name 'foreman_userdata' | ||
|
||
initializer 'foreman_userdata.register_plugin', :before => :finisher_hook do |_app| | ||
Foreman::Plugin.register :foreman_userdata do | ||
requires_foreman '>= 1.12' | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module ForemanUserdata | ||
VERSION = '0.0.1'.freeze | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# Tasks | ||
namespace :foreman_userdata do | ||
namespace :example do | ||
desc 'Example Task' | ||
task task: :environment do | ||
# Task goes here | ||
end | ||
end | ||
end | ||
|
||
# Tests | ||
namespace :test do | ||
desc 'Test ForemanUserdata' | ||
Rake::TestTask.new(:foreman_userdata) do |t| | ||
test_dir = File.join(File.dirname(__FILE__), '../..', 'test') | ||
t.libs << ['test', test_dir] | ||
t.pattern = "#{test_dir}/**/*_test.rb" | ||
t.verbose = true | ||
t.warning = false | ||
end | ||
end | ||
|
||
namespace :foreman_userdata do | ||
task :rubocop do | ||
begin | ||
require 'rubocop/rake_task' | ||
RuboCop::RakeTask.new(:rubocop_foreman_userdata) do |task| | ||
task.patterns = ["#{ForemanUserdata::Engine.root}/app/**/*.rb", | ||
"#{ForemanUserdata::Engine.root}/lib/**/*.rb", | ||
"#{ForemanUserdata::Engine.root}/test/**/*.rb"] | ||
end | ||
rescue | ||
puts 'Rubocop not loaded.' | ||
end | ||
|
||
Rake::Task['rubocop_foreman_userdata'].invoke | ||
end | ||
end | ||
|
||
Rake::Task[:test].enhance ['test:foreman_userdata'] | ||
|
||
load 'tasks/jenkins.rake' | ||
if Rake::Task.task_defined?(:'jenkins:unit') | ||
Rake::Task['jenkins:unit'].enhance ['test:foreman_userdata', 'foreman_userdata:rubocop'] | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
require 'test_plugin_helper' | ||
|
||
class UserdataControllerTest < ActionController::TestCase | ||
let(:host) { FactoryGirl.create(:host, :managed) } | ||
let(:content) { 'template content' } | ||
let(:template_kind) { TemplateKind.create(:name => 'user_data') } | ||
let(:template) do | ||
FactoryGirl.create( | ||
:provisioning_template, | ||
:template_kind => template_kind, | ||
:template => content | ||
) | ||
end | ||
|
||
test 'should get rendered userdata template' do | ||
@request.env['REMOTE_ADDR'] = host.ip | ||
Host::Managed.any_instance.expects(:provisioning_template).returns(template) | ||
get :userdata | ||
assert_response :success | ||
assert_equal content, @response.body | ||
end | ||
|
||
test 'should get empty metadata' do | ||
@request.env['REMOTE_ADDR'] = host.ip | ||
get :metadata | ||
assert_response :success | ||
assert_empty @response.body | ||
end | ||
end |
Oops, something went wrong.