From c09c501ef41a177751de4189e96f0aa72e398e96 Mon Sep 17 00:00:00 2001 From: Adam Cooke Date: Fri, 21 Apr 2017 11:09:31 +0100 Subject: [PATCH] admin UI for managing ip pools & ip addresses --- .../application/global/_utility.scss | 4 ++ app/controllers/ip_addresses_controller.rb | 39 ++++++++++++++++ app/controllers/ip_pools_controller.rb | 44 +++++++++++++++++++ app/views/ip_addresses/_form.html.haml | 19 ++++++++ app/views/ip_addresses/edit.html.haml | 17 +++++++ app/views/ip_addresses/new.html.haml | 17 +++++++ app/views/ip_pools/_form.html.haml | 37 ++++++++++++++++ app/views/ip_pools/edit.html.haml | 15 +++++++ app/views/ip_pools/index.html.haml | 27 ++++++++++++ app/views/ip_pools/new.html.haml | 10 +++++ config/routes.rb | 3 ++ 11 files changed, 232 insertions(+) create mode 100644 app/controllers/ip_addresses_controller.rb create mode 100644 app/controllers/ip_pools_controller.rb create mode 100644 app/views/ip_addresses/_form.html.haml create mode 100644 app/views/ip_addresses/edit.html.haml create mode 100644 app/views/ip_addresses/new.html.haml create mode 100644 app/views/ip_pools/_form.html.haml create mode 100644 app/views/ip_pools/edit.html.haml create mode 100644 app/views/ip_pools/index.html.haml create mode 100644 app/views/ip_pools/new.html.haml diff --git a/app/assets/stylesheets/application/global/_utility.scss b/app/assets/stylesheets/application/global/_utility.scss index c1db584..d8a5fa0 100644 --- a/app/assets/stylesheets/application/global/_utility.scss +++ b/app/assets/stylesheets/application/global/_utility.scss @@ -2,6 +2,10 @@ margin-bottom:25px; } +.u-margin-half { + margin-bottom:10px; +} + .u-center { text-align:center; } diff --git a/app/controllers/ip_addresses_controller.rb b/app/controllers/ip_addresses_controller.rb new file mode 100644 index 0000000..088b82c --- /dev/null +++ b/app/controllers/ip_addresses_controller.rb @@ -0,0 +1,39 @@ +class IPAddressesController < ApplicationController + + before_action :admin_required + before_action { @ip_pool = IPPool.find_by_uuid!(params[:ip_pool_id]) } + before_action { params[:id] && @ip_address = @ip_pool.ip_addresses.find(params[:id]) } + + def new + @ip_address = @ip_pool.ip_addresses.build + end + + def create + @ip_address = @ip_pool.ip_addresses.build(safe_params) + if @ip_address.save + redirect_to_with_json [:edit, @ip_pool] + else + render_form_errors 'new', @ip_address + end + end + + def update + if @ip_address.update(safe_params) + redirect_to_with_json [:edit, @ip_pool] + else + render_form_errors 'edit', @ip_address + end + end + + def destroy + @ip_address.destroy + redirect_to_with_json [:edit, @ip_pool] + end + + private + + def safe_params + params.require(:ip_address).permit(:ipv4, :ipv6, :hostname) + end + +end diff --git a/app/controllers/ip_pools_controller.rb b/app/controllers/ip_pools_controller.rb new file mode 100644 index 0000000..d38a1a7 --- /dev/null +++ b/app/controllers/ip_pools_controller.rb @@ -0,0 +1,44 @@ +class IPPoolsController < ApplicationController + + before_action :admin_required + before_action { params[:id] && @ip_pool = IPPool.find_by_uuid!(params[:id]) } + + def index + @ip_pools = IPPool.order(:name).to_a + end + + def new + @ip_pool = IPPool.new + end + + def create + @ip_pool = IPPool.new(safe_params) + if @ip_pool.save + redirect_to_with_json [:edit, @ip_pool], :notice => "IP Pool has been added successfully. You can now add IP addresses to it." + else + render_form_errors 'new', @ip_pool + end + end + + def update + if @ip_pool.update(safe_params) + redirect_to_with_json [:edit, @ip_pool], :notice => "IP Pool has been updated." + else + render_form_errors 'edit', @ip_pool + end + end + + def destroy + @ip_pool.destroy + redirect_to_with_json :ip_pools, :notice => "IP pool has been removed successfully." + rescue ActiveRecord::DeleteRestrictionError => e + redirect_to_with_json [:edit, @ip_pool], :alert => "IP pool cannot be removed because it is still assigned to servers/rules." + end + + private + + def safe_params + params.require(:ip_pool).permit(:name, :type, :default) + end + +end diff --git a/app/views/ip_addresses/_form.html.haml b/app/views/ip_addresses/_form.html.haml new file mode 100644 index 0000000..d8249ed --- /dev/null +++ b/app/views/ip_addresses/_form.html.haml @@ -0,0 +1,19 @@ += form_for [@ip_pool, @ip_address], :remote => true do |f| + = f.error_messages + %fieldset.fieldSet + .fieldSet__field + = f.label :ipv4, :class => 'fieldSet__label' + .fieldSet__input= f.text_field :ipv4, :autofocus => true, :class => 'input input--text' + .fieldSet__field + = f.label :ipv6, :class => 'fieldSet__label' + .fieldSet__input= f.text_field :ipv6, :class => 'input input--text' + .fieldSet__field + = f.label :hostname, :class => 'fieldSet__label' + .fieldSet__input= f.text_field :hostname, :class => 'input input--text' + + .fieldSetSubmit.buttonSet + = f.submit :class => 'button button--positive js-form-submit' + .fieldSetSubmit__delete + - if @ip_address.persisted? + = link_to "Delete IP address", [@ip_pool, @ip_address], :class => 'button button--danger', :method => :delete, :remote => true, :data => {:confirm => "Are you sure you wish to remove this IP from the pool?"} + diff --git a/app/views/ip_addresses/edit.html.haml b/app/views/ip_addresses/edit.html.haml new file mode 100644 index 0000000..114964d --- /dev/null +++ b/app/views/ip_addresses/edit.html.haml @@ -0,0 +1,17 @@ +- page_title << "IP Pools" +- page_title << @ip_pool.name +- page_title << "Edit IP address" +.pageHeader + %h1.pageHeader__title + %span.pageHeader__titlePrevious + = link_to "IP Pools", :ip_pools + → + = @ip_pool.name + → + Edit + → + Edit IP address + +.pageContent.pageContent--compact + = render 'form' + diff --git a/app/views/ip_addresses/new.html.haml b/app/views/ip_addresses/new.html.haml new file mode 100644 index 0000000..93fde66 --- /dev/null +++ b/app/views/ip_addresses/new.html.haml @@ -0,0 +1,17 @@ +- page_title << "IP Pools" +- page_title << @ip_pool.name +- page_title << "Add new IP address" +.pageHeader + %h1.pageHeader__title + %span.pageHeader__titlePrevious + = link_to "IP Pools", :ip_pools + → + = @ip_pool.name + → + Edit + → + Add new IP address + +.pageContent.pageContent--compact + = render 'form' + diff --git a/app/views/ip_pools/_form.html.haml b/app/views/ip_pools/_form.html.haml new file mode 100644 index 0000000..0742894 --- /dev/null +++ b/app/views/ip_pools/_form.html.haml @@ -0,0 +1,37 @@ += form_for @ip_pool, :remote => true do |f| + = f.error_messages + %fieldset.fieldSet.u-margin + .fieldSet__field + = f.label :name, :class => 'fieldSet__label' + .fieldSet__input= f.text_field :name, :autofocus => true, :class => 'input input--text' + .fieldSet__field + = f.label :type, :class => 'fieldSet__label' + .fieldSet__input= f.select :type, IPPool::TYPES, {}, :class => 'input input--select' + + - if @ip_pool.persisted? + %table.dataTable.u-margin-half + %thead + %tr + %td IPv4 + %td IPv6 + %td Hostname + %tbody + - if @ip_pool.ip_addresses.empty? + %tr + %td.dataTable__empty{:colspan => 3} There are no IP addresses assigned to this pool yet. + - else + - for ip in @ip_pool.ip_addresses + %tr + %td{:width => "20%"}= link_to ip.ipv4, [:edit, @ip_pool, ip], :class => "u-link" + %td{:width => "40%"}= ip.ipv6 + %td{:width => "40%"}= ip.hostname + %p= link_to "Add an IP address to pool", [:new, @ip_pool, :ip_address], :class => "u-link" + + + .fieldSetSubmit.buttonSet + = f.submit :class => 'button button--positive js-form-submit' + .fieldSetSubmit__delete + - if @ip_pool.persisted? + = link_to "Delete IP pool", [@ip_pool], :class => 'button button--danger', :method => :delete, :remote => true, :data => {:confirm => "Are you sure you wish to remove this IP pool?"} + + diff --git a/app/views/ip_pools/edit.html.haml b/app/views/ip_pools/edit.html.haml new file mode 100644 index 0000000..721b99a --- /dev/null +++ b/app/views/ip_pools/edit.html.haml @@ -0,0 +1,15 @@ +- page_title << "IP Pools" +- page_title << @ip_pool.name + +.pageHeader + %h1.pageHeader__title + %span.pageHeader__titlePrevious + = link_to "IP Pools", :ip_pools + → + = @ip_pool.name + → + Edit + +.pageContent.pageContent--compact + = render 'form' + diff --git a/app/views/ip_pools/index.html.haml b/app/views/ip_pools/index.html.haml new file mode 100644 index 0000000..3806fd2 --- /dev/null +++ b/app/views/ip_pools/index.html.haml @@ -0,0 +1,27 @@ +- page_title << "Welcome" + +.pageHeader + %h1.pageHeader__title IP Pools + +.pageContent.pageContent--compact + + - if @ip_pools.empty? + .noData.noData--cat2.noData--clean + %p.noData__title There are no IP pools configured. + %p.noData__text + All messages sent from your mail server can be sent from certain pools of + IP addresses. Each server can be assigned to a pool and rules can be configured + to route certain email through certain pools. + %p.noData__button= link_to "Create the first IP pool", :new_ip_pool, :class => 'button button--positive' + - else + %p.pageContent__intro.u-margin + IP pools are the addresses that your outgoing messages are sent from. You can + create as many pools as you wish. + + %ul.largeList.u-margin + - for ip_pool in @ip_pools + %li.largeList__item + = link_to edit_ip_pool_path(ip_pool), :class => 'largeList__link' do + = ip_pool.name + + %p.u-center= link_to "Add another IP pool", :new_ip_pool, :class => 'button button--positive' diff --git a/app/views/ip_pools/new.html.haml b/app/views/ip_pools/new.html.haml new file mode 100644 index 0000000..5251044 --- /dev/null +++ b/app/views/ip_pools/new.html.haml @@ -0,0 +1,10 @@ +- page_title << "Create a new IP pool" +.pageHeader + %h1.pageHeader__title + %span.pageHeader__titlePrevious + = link_to "IP Pools", :ip_pools + → + Create a new IP pool +.pageContent.pageContent--compact + = render 'form' + diff --git a/config/routes.rb b/config/routes.rb index e4fc4e6..85d8008 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -69,6 +69,9 @@ Rails.application.routes.draw do end resources :organizations, :except => [:index] + resources :ip_pools do + resources :ip_addresses + end get 'settings' => 'user#edit' patch 'settings' => 'user#update'