Skip to content

Commit

Permalink
Merge pull request #13 from idb-project/feature/cloudproviders
Browse files Browse the repository at this point in the history
Feature cloudproviders
  • Loading branch information
rbns committed Dec 9, 2016
2 parents 790b5ef + 8ecb41c commit 9f5e7cc
Show file tree
Hide file tree
Showing 26 changed files with 697 additions and 6 deletions.
4 changes: 4 additions & 0 deletions Gemfile
Expand Up @@ -56,3 +56,7 @@ group :development do
gem 'guard-rspec', require: false
gem 'ruby-ldapserver', require: false
end

group :test do
gem 'rails-controller-testing'
end
5 changes: 5 additions & 0 deletions Gemfile.lock
Expand Up @@ -227,6 +227,10 @@ GEM
bundler (>= 1.3.0, < 2.0)
railties (= 5.0.0.1)
sprockets-rails (>= 2.0.0)
rails-controller-testing (1.0.1)
actionpack (~> 5.x)
actionview (~> 5.x)
activesupport (~> 5.x)
rails-dom-testing (2.0.1)
activesupport (>= 4.2.0, < 6.0)
nokogiri (~> 1.6.0)
Expand Down Expand Up @@ -366,6 +370,7 @@ DEPENDENCIES
paranoia
puma
rails
rails-controller-testing
rails-jquery-autocomplete
rake
redcarpet
Expand Down
1 change: 1 addition & 0 deletions app/api/v2/api.rb
@@ -1,5 +1,6 @@
module V2
class API < Grape::API
mount V2::Machines
mount V2::CloudProviders
end
end
66 changes: 66 additions & 0 deletions app/api/v2/cloud_providers.rb
@@ -0,0 +1,66 @@
module V2
class CloudProviders < Grape::API
helpers do
def get_token
if params[:idb_api_token]
return params[:idb_api_token]
elsif request.headers["X-Idb-Api-Token"]
return request.headers["X-Idb-Api-Token"]
else
error!("Unauthorized.", 401)
end
end

def authenticate!
token = params[:idb_api_token] ? params[:idb_api_token] : request.headers["X-Idb-Api-Token"]
if ApiToken.where("token = ?", token).empty?
error!("Unauthorized.", 401)
end
end

def can_read!
token = params[:idb_api_token] ? params[:idb_api_token] : request.headers["X-Idb-Api-Token"]
unless ApiToken.where("token = ?", token).first.read
error!("Unauthorized.", 401)
end
end

def can_write!
token = params[:idb_api_token] ? params[:idb_api_token] : request.headers["X-Idb-Api-Token"]
unless ApiToken.where("token = ?", token).first.write
error!("Unauthorized.", 401)
end
end
end

version 'v2'
format :json

resource :cloud_providers do
desc "Return a list of all cloud providers"
get do
authenticate!
can_read!
unless IDB.config.modules.api.v2_enabled
status 501
return {}
end

p = params.to_hash

unless p["owner"].to_i != 0
CloudProvider.all
else
m = CloudProvider.where("owner_id = ?", p["owner"].to_i)
if m.empty?
status 404
{}
else
m
end
end
end
end

end
end
75 changes: 75 additions & 0 deletions app/controllers/cloud_providers_controller.rb
@@ -0,0 +1,75 @@
class CloudProvidersController < ApplicationController
def index
@cloud_providers = CloudProvider.all
end

def new
@cloud_provider = CloudProvider.new
@cloud_providers = {}
@all_cloud_providers = CloudProvider.all
@owners = Owner.all
end

def create
@cloud_provider = CloudProvider.new(params.require(:cloud_provider).permit(:name, :description, :owner_id, :config, :apidocs))
@owners = Owner.all

if params["check"] == "json"
begin
JSON.parse(@cloud_provider.config)
rescue JSON::ParserError
flash.alert = "JSON validation failed, check the config for errors!"
render :new
return
end
end

if @cloud_provider.save
flash.notice = "Cloud provider created"
redirect_to cloud_providers_path
else
render :new
end
end

def show
@cloud_provider = CloudProvider.find(params[:id])
@all_cloud_providers = CloudProvider.all
end

def edit
@cloud_provider = CloudProvider.find(params[:id])
@cloud_providers = {}
@all_cloud_providers = CloudProvider.all
@owners = Owner.all
end

def update
@cloud_provider = CloudProvider.find(params[:id])
@owners = Owner.all

if params["check"] == "json"
begin
JSON.parse(params[:cloud_provider][:config])
rescue JSON::ParserError
flash.alert = "JSON validation failed, check the config for errors!"
render :new
return
end
end

if @cloud_provider.update(params.require(:cloud_provider).permit(:name, :description, :owner_id, :config, :apidocs))
redirect_to cloud_providers_path, notice: 'Cloud Provider updated.'
else
render :edit
end
end

def destroy
@cloud_provider = CloudProvider.find(params[:id])
@cloud_provider.destroy

redirect_to cloud_providers_path, notice: 'Cloud Provider deleted!'
end

end
1 change: 1 addition & 0 deletions app/controllers/owners_controller.rb
Expand Up @@ -53,6 +53,7 @@ def summary
@owner = Owner.find(params[:owner])
@machines = @owner.machines
@networks = Network.where(owner: @owner)
@cloud_providers = @owner.cloud_providers
render :summary
end

Expand Down
4 changes: 4 additions & 0 deletions app/models/cloud_provider.rb
@@ -0,0 +1,4 @@
class CloudProvider < ActiveRecord::Base
validates :name, presence: true, uniqueness: true
belongs_to :owner
end
3 changes: 2 additions & 1 deletion app/models/owner.rb
Expand Up @@ -8,6 +8,7 @@ class Owner < ActiveRecord::Base
has_many :inventories, :dependent => :destroy
has_many :machines, :dependent => :destroy
has_many :attachments, :dependent => :destroy
has_many :cloud_providers, :dependent => :destroy

validates :name, :nickname, presence: true
validates :name, :nickname, uniqueness: true
Expand All @@ -16,7 +17,7 @@ class Owner < ActiveRecord::Base
after_initialize { self.data ||= {} }

def self.eager_find(id)
includes(:machines, machines: [{nics: [:ip_address]}, :owner]).find(id)
includes(:cloud_providers, :machines, machines: [{nics: [:ip_address]}, :owner]).find(id)
end

def display_name
Expand Down
17 changes: 17 additions & 0 deletions app/presenters/cloud_provider_presenter.rb
@@ -0,0 +1,17 @@

class CloudProviderPresenter < Keynote::Presenter
presents :cloud_provider

delegate :id, :name, :owner, :description, :config,
to: :cloud_provider

def name_link
link_to(cloud_provider.name, cloud_provider)
end

def apidocs_link
link_to(cloud_provider.apidocs, cloud_provider.apidocs).html_safe
end


end
51 changes: 51 additions & 0 deletions app/views/cloud_providers/_form.html.erb
@@ -0,0 +1,51 @@
<div id="cloud-provider-form">

<div class="row-fluid">
<div class="span12">
<div class="navbar">
<div class="navbar-inner">
<div class="container-fluid">
<%- if @cloud_provider.new_record? -%>
<a class="brand" href="<%= new_cloud_provider_path %>">New Cloud Provider</a>
<%- else-%>
<a class="brand" href="<%= edit_cloud_provider_path(@cloud_provider) %>"><%= @cloud_provider.name %></a>
<%- end -%>
<ul class="nav pull-right">
<%- unless @cloud_provider.new_record? -%>
<li><%= link_to '<i class="icon-remove-sign"></i> Delete'.html_safe, cloud_providers_path(@cloud_provider), class: 'cloud-provider-delete', method: 'delete' %></li>
<li><%= link_to '<i class="icon-level-up"></i> Cancel'.html_safe, cloud_providers_path(@cloud_provider) %></li>
<%- else -%>
<li><%= link_to '<i class="icon-level-up"></i> Cancel'.html_safe, cloud_providers_path(@cloud_provider) %></li>
<%- end -%>
</ul>
</div>
</div>
</div>
</div>
</div>

<div class="tab-content">
<div class="tab-pane active" id="base">
<div class="row-fluid">
<div class="span6">
<%= simple_form_for(@cloud_provider, html: {class: 'form-horizontal', multipart: true },
defaults: {input_html: {class: 'span6'}}) do |f| %>
<%= f.input :name %>
<%= f.input :owner_id, collection: @owners.order(:name), include_blank: false, label: "Owner" %>
<%= f.input :description %>
<%= f.input :apidocs, label: "API Documentation" %>
<%= f.input :config %>
<div class="control-group text optional cloud_provider_check">
<label class="text optional control-label" for="cloud_provider_check">Validate JSON config</label>
<div class="controls">
<%= check_box_tag 'check', 'json', true %>
</div>
</div>
<%= f.button :submit %>
<%- end -%>
</div>
</div>
</div>
</div>

</div>
22 changes: 22 additions & 0 deletions app/views/cloud_providers/_table.html.erb
@@ -0,0 +1,22 @@
<table id="cloud-provider-table" class="table tablesorter custom-popup">
<thead>
<tr>
<th>Name</th>
<th>Owner</th>
<th>API Documentation</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<%- cloud_providers.each do |cloud_provider| -%>
<%- owner = k(:owner, cloud_provider.owner) -%>
<%- cloud_provider = k(:cloud_provider, cloud_provider) -%>
<tr id="#cloud-provider-<%= cloud_provider.name %>">
<td><%= cloud_provider.name_link %></td>
<td><%= owner.name_link %></td>
<td><%= cloud_provider.apidocs_link %></td>
<td><%= cloud_provider.description %></td>
</tr>
<%- end -%>
</tbody>
</table>
1 change: 1 addition & 0 deletions app/views/cloud_providers/edit.html.erb
@@ -0,0 +1 @@
<%= render 'form' %>
30 changes: 30 additions & 0 deletions app/views/cloud_providers/index.html.erb
@@ -0,0 +1,30 @@
<div id="cloud_providers-index">

<div class="row-fluid">
<div class="span12">
<div class="navbar">
<div class="navbar-inner">
<div class="container-fluid">
<a class="brand" href="<%= cloud_providers_path %>">Cloud Providers</a>
<ul class="nav">
<li>
<div class="columnSelectorWrapper">
<input id="colSelect1" type="checkbox" class="hidden">
<label style="margin-bottom: 0px; color: #777777; margin-right: 15px;" class="columnSelectorButton" for="colSelect1"><i class="icon-cog">&nbsp;</i>Columns</label>
<div id="columnSelector" class="columnSelector"></div>
</div>
</li>
<li><%= link_to '<i class="icon-plus"></i> New Cloud Provider'.html_safe, new_cloud_provider_path %></li>
</ul>
</div>
</div>
</div>
</div>
</div>

<div class="row-fluid">
<div class="span12">
<%= render partial: 'table', locals: {cloud_providers: @cloud_providers} %>
</div>
</div>

1 change: 1 addition & 0 deletions app/views/cloud_providers/new.html.erb
@@ -0,0 +1 @@
<%= render 'form' %>
45 changes: 45 additions & 0 deletions app/views/cloud_providers/show.html.erb
@@ -0,0 +1,45 @@
<div id="cloud-provider-show">

<div class="row-fluid tabbable">
<div class="span12">
<div class="navbar">
<div class="navbar-inner">
<div class="container-fluid">
<span class="brand"><%= @cloud_provider.name %></span>
<ul class="nav pull-right">
<li><%= link_to '<i class="icon-edit"></i> Edit'.html_safe, edit_cloud_provider_path(@cloud_provider) %></li>
<li><%= link_to '<i class="icon-remove-sign"></i> Delete'.html_safe, cloud_provider_path(@cloud_provider), class: 'cloud-provider-delete', method: 'delete' %></li>
<li><%= link_to '<i class="icon-level-up"></i> Cancel'.html_safe, cloud_providers_path %></li>
</ul>
</div>
</div>
</div>
</div>
</div>

<div class="row-fluid">
<div class="span6 tab-content">
<div class="tab-pane active" id="data">
<table class="table table-condensed">
<tr>
<th>Name</th>
<th>Owner</th>
<th>API Documentation</th>
<th>Description</th>
</tr>
<tr>
<%- owner = k(:owner, @cloud_provider.owner) -%>
<%- cloud_provider = k(:cloud_provider, @cloud_provider) -%>
<td><%= @cloud_provider.name %></td>
<td><%= owner.name_link %></td>
<td><%= cloud_provider.apidocs_link %></td>
<td><%= @cloud_provider.description %></td>
</tr>
</table>
</div>
<h5>Configuration</h5>
<pre><code><%= @cloud_provider.config %></code></pre>
</div>
</div>

</div>
9 changes: 5 additions & 4 deletions app/views/layouts/application.html.erb
Expand Up @@ -38,13 +38,14 @@
<a href="" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-user"></i> <%= current_user.display_name %>
<ul class="dropdown-menu text-right">
<li><%= link_to '<i class="fa fa-tasks"></i> Api Tokens'.html_safe, api_tokens_path %></li>
<li><%= BackgroundJobs.new.link('Background Jobs', 'fa fa-tasks', background_jobs_sidekiq_path) %></li>
<li><%= link_to '<i class="fa fa-tasks"></i> Location Levels'.html_safe, location_levels_path %></li>
<li><%= link_to '<i class="icon-tasks"></i> Api Tokens'.html_safe, api_tokens_path %></li>
<li><%= link_to '<i class="icon-tasks"></i> Cloud Providers'.html_safe, cloud_providers_path %></li>
<li><%= BackgroundJobs.new.link('Background Jobs', 'icon-tasks', background_jobs_sidekiq_path) %></li>
<li><%= link_to '<i class="icon-tasks"></i> Location Levels'.html_safe, location_levels_path %></li>
<%- if IDB.config.modules.inventory -%>
<li><%= link_to '<i class="fa fa-tasks"></i> Inventory Status'.html_safe, inventory_status_index_path %></li>
<%- end -%>
<li><%= link_to '<i class="fa fa-frown"></i> Logout'.html_safe, logout_path, method: :delete %></li>
<li><%= link_to '<i class="icon-frown"></i> Logout'.html_safe, logout_path, method: :delete %></li>
</ul>
</a>
</li>
Expand Down

0 comments on commit 9f5e7cc

Please sign in to comment.