Hello community,

here is the log from the commit of package velum for openSUSE:Factory checked 
in at 2018-08-06 11:54:46
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/velum (Old)
 and      /work/SRC/openSUSE:Factory/.velum.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "velum"

Mon Aug  6 11:54:46 2018 rev:41 rq:627588 
version:4.0.0+dev+git_r863_622d86735c2699c568fa8881c0d94cd4bf448d1b

Changes:
--------
--- /work/SRC/openSUSE:Factory/velum/velum.changes      2018-07-23 
18:03:41.932730660 +0200
+++ /work/SRC/openSUSE:Factory/.velum.new/velum.changes 2018-08-06 
11:54:49.153300784 +0200
@@ -1,0 +2,14 @@
+Mon Jul 30 06:38:41 UTC 2018 - [email protected]
+
+- Commit f8d65aa by James Mason [email protected]
+ Add support for bootstrapping in Google Compute
+
+
+-------------------------------------------------------------------
+Tue Jul 24 23:05:23 UTC 2018 - [email protected]
+
+- Commit 971c792 by Ty Daines [email protected]
+ Add ability to add, modify, delete and list LDAP connections in the ui
+
+
+-------------------------------------------------------------------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ velum.spec ++++++
--- /var/tmp/diff_new_pack.9SY14z/_old  2018-08-06 11:54:49.641301632 +0200
+++ /var/tmp/diff_new_pack.9SY14z/_new  2018-08-06 11:54:49.645301639 +0200
@@ -23,7 +23,7 @@
 # Version:      1.0.0
 # %%define branch 1.0.0
 
-Version:        4.0.0+dev+git_r859_b55671441cd42c71da60f5c1dab26591651f4af1
+Version:        4.0.0+dev+git_r863_622d86735c2699c568fa8881c0d94cd4bf448d1b
 Release:        0
 %define branch master
 Summary:        Dashboard for CaasP
@@ -93,7 +93,7 @@
 %description
 velum is the dashboard for CaasP to manage and deploy kubernetes clusters on 
top of MicroOS
 
-This package has been built with commit 
b55671441cd42c71da60f5c1dab26591651f4af1 from branch master on date Thu, 19 Jul 
2018 09:16:04 +0000
+This package has been built with commit 
622d86735c2699c568fa8881c0d94cd4bf448d1b from branch master on date Mon, 30 Jul 
2018 06:38:01 +0000
 
 %prep
 %setup -q -n velum-%{branch}

++++++ master.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/velum-master/app/assets/javascripts/settings/index.js 
new/velum-master/app/assets/javascripts/settings/index.js
--- old/velum-master/app/assets/javascripts/settings/index.js   2018-07-19 
11:18:06.000000000 +0200
+++ new/velum-master/app/assets/javascripts/settings/index.js   2018-07-30 
08:40:27.000000000 +0200
@@ -2,6 +2,7 @@
   var $mirrorForm = $('.mirror-form');
   var $registryForm = $('.registry-form');
   var $systemCertificateForm = $('.system-certificate-form');
+  var $dexConnectorForm = $('.dex-connector-form');
 
   if ($mirrorForm.length) {
     new RegistryForm($mirrorForm);
@@ -14,4 +15,8 @@
   if ($systemCertificateForm.length) {
     new SystemCertificateForm($systemCertificateForm);
   }
+
+  if ($dexConnectorForm.length) {
+    new DexConnectorForm($dexConnectorForm);
+  }
 });
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/velum-master/app/controllers/internal_api/v1/pillars_controller.rb 
new/velum-master/app/controllers/internal_api/v1/pillars_controller.rb
--- old/velum-master/app/controllers/internal_api/v1/pillars_controller.rb      
2018-07-19 11:18:06.000000000 +0200
+++ new/velum-master/app/controllers/internal_api/v1/pillars_controller.rb      
2018-07-30 08:40:27.000000000 +0200
@@ -68,6 +68,8 @@
       ec2_cloud_contents
     when "azure"
       azure_cloud_contents
+    when "gce"
+      gce_cloud_contents
     else
       {}
     end
@@ -126,6 +128,21 @@
           }
         }
       }
+    }
+  end
+
+  def gce_cloud_contents
+    {
+      cloud: {
+        framework: "gce",
+        profiles:  {
+          cluster_node: {
+            size:       Pillar.value(pillar: :cloud_worker_type),
+            network:    Pillar.value(pillar: :cloud_worker_net),
+            subnetwork: Pillar.value(pillar: :cloud_worker_subnet)
+          }
+        }
+      }
     }
   end
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/velum-master/app/controllers/settings/dex_connector_ldaps_controller.rb 
new/velum-master/app/controllers/settings/dex_connector_ldaps_controller.rb
--- old/velum-master/app/controllers/settings/dex_connector_ldaps_controller.rb 
1970-01-01 01:00:00.000000000 +0100
+++ new/velum-master/app/controllers/settings/dex_connector_ldaps_controller.rb 
2018-07-30 08:40:27.000000000 +0200
@@ -0,0 +1,49 @@
+# Settings::DexConnectorLdapsController is responsible to manage requests
+# related to LDAP connectors.
+class Settings::DexConnectorLdapsController < 
Settings::BaseCertificateController
+  def index
+    @ldap_connectors = DexConnectorLdap.all
+  end
+
+  def new
+    @certificate_holder = certificate_holder_type.new
+    @cert = Certificate.new
+  end
+
+  def destroy
+    @certificate_holder.destroy
+    redirect_to settings_dex_connector_ldaps_path,
+                notice: "LDAP Connector was successfully removed."
+  end
+
+  protected
+
+  def certificate_holder_type
+    DexConnectorLdap
+  end
+
+  def certificate_holder_params
+    ldap_connector_params
+  end
+
+  def certificate_holder_update_params
+    ldap_connector_params.except(:certificate)
+  end
+
+  private
+
+  def certificate_param
+    ldap_connector_params[:certificate].strip if
+      ldap_connector_params[:certificate].present?
+  end
+
+  def ldap_connector_params
+    params.require(:dex_connector_ldap).permit(:name, :host, :port,
+                                               :start_tls, :certificate, 
:bind_anon,
+                                               :bind_dn, :bind_pw, 
:username_prompt,
+                                               :user_base_dn, :user_filter, 
:user_attr_username,
+                                               :user_attr_id, 
:user_attr_email, :user_attr_name,
+                                               :group_base_dn, :group_filter, 
:group_attr_user,
+                                               :group_attr_group, 
:group_attr_name)
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/velum-master/app/controllers/setup_controller.rb 
new/velum-master/app/controllers/setup_controller.rb
--- old/velum-master/app/controllers/setup_controller.rb        2018-07-19 
11:18:06.000000000 +0200
+++ new/velum-master/app/controllers/setup_controller.rb        2018-07-30 
08:40:27.000000000 +0200
@@ -224,6 +224,7 @@
 
   def cloud_cluster_params
     cloud_cluster = params.require(:cloud_cluster).permit(
+      :cloud_framework,
       :subscription_id, :tenant_id, :client_id, :secret,
       :instance_type, :instance_type_custom, :instance_count,
       :resource_group, :storage_account,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/velum-master/app/helpers/settings_helper.rb 
new/velum-master/app/helpers/settings_helper.rb
--- old/velum-master/app/helpers/settings_helper.rb     2018-07-19 
11:18:06.000000000 +0200
+++ new/velum-master/app/helpers/settings_helper.rb     2018-07-30 
08:40:27.000000000 +0200
@@ -24,6 +24,10 @@
     request.fullpath.starts_with?(settings_system_certificates_path)
   end
 
+  def settings_dex_connector_ldaps_path?
+    request.fullpath.starts_with?(settings_dex_connector_ldaps_path)
+  end
+
   def registries_options_for_select
     registries = Registry.suse + Registry.displayable
     registries_for_options = registries.collect { |r| [r.name, r.id] }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/velum-master/app/models/cloud_cluster.rb 
new/velum-master/app/models/cloud_cluster.rb
--- old/velum-master/app/models/cloud_cluster.rb        2018-07-19 
11:18:06.000000000 +0200
+++ new/velum-master/app/models/cloud_cluster.rb        2018-07-30 
08:40:27.000000000 +0200
@@ -47,6 +47,8 @@
       parts.push("in EC2")
     when "azure"
       parts.push("in Azure")
+    when "gce"
+      parts.push("in GCE")
     end
     parts.compact.join(" ")
   end
@@ -96,13 +98,13 @@
   def string_scope_if(attribute)
     value = send(attribute)
     description = attribute.to_s.humanize(capitalize: false)
-    return unless value
+    return if value.blank?
 
     "in the #{value} #{description}"
   end
 
   def persist_to_pillar!(key, value)
-    return unless value && Pillar.all_pillars[key]
+    return unless value.present? && Pillar.all_pillars[key]
 
     pillar = Pillar.find_or_initialize_by(pillar: Pillar.all_pillars[key])
     pillar.value = value
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/velum-master/app/models/dex_connector_ldap.rb 
new/velum-master/app/models/dex_connector_ldap.rb
--- old/velum-master/app/models/dex_connector_ldap.rb   2018-07-19 
11:18:06.000000000 +0200
+++ new/velum-master/app/models/dex_connector_ldap.rb   2018-07-30 
08:40:27.000000000 +0200
@@ -3,4 +3,22 @@
   has_one :certificate_service, as: :service, dependent: :destroy
   has_one :certificate, through: :certificate_service
   self.table_name = "dex_connectors_ldap"
+
+  validates :name, presence: true
+  validates :host, presence: true
+  validates :port, presence: true, numericality: { only_integer: true }
+  validates :bind_dn, presence: true, unless: :bind_anon
+  validates :bind_pw, presence: true, unless: :bind_anon
+  validates :username_prompt, presence: true
+  validates :user_base_dn, presence: true
+  validates :user_filter, presence: true
+  validates :user_attr_username, presence: true
+  validates :user_attr_id, presence: true
+  validates :user_attr_email, presence: true
+  validates :user_attr_name, presence: true
+  validates :group_base_dn, presence: true
+  validates :group_filter, presence: true
+  validates :group_attr_user, presence: true
+  validates :group_attr_group, presence: true
+  validates :group_attr_name, presence: true
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/velum-master/app/models/pillar.rb 
new/velum-master/app/models/pillar.rb
--- old/velum-master/app/models/pillar.rb       2018-07-19 11:18:06.000000000 
+0200
+++ new/velum-master/app/models/pillar.rb       2018-07-30 08:40:27.000000000 
+0200
@@ -90,7 +90,7 @@
         cloud_worker_type:
           "cloud:profiles:cluster_node:size",
         cloud_worker_subnet:
-          "cloud:profiles:cluster_node:network_interfaces:SubnetId",
+          "cloud:profiles:cluster_node:subnet",
         cloud_worker_security_group:
           "cloud:profiles:cluster_node:network_interfaces:SecurityGroupId",
         cloud_worker_net:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/velum-master/app/views/settings/_sidebar.html.slim 
new/velum-master/app/views/settings/_sidebar.html.slim
--- old/velum-master/app/views/settings/_sidebar.html.slim      2018-07-19 
11:18:06.000000000 +0200
+++ new/velum-master/app/views/settings/_sidebar.html.slim      2018-07-30 
08:40:27.000000000 +0200
@@ -7,6 +7,10 @@
       = link_to "Mirrors", settings_registry_mirrors_path
     li class="#{active_class?(settings_system_certificates_path?)}"
       = link_to "System wide certificates", settings_system_certificates_path
+  h5.title External Authentication
+  ul.list
+    li class="#{active_class?(settings_dex_connector_ldaps_path?)}"
+      = link_to "LDAP Connectors", settings_dex_connector_ldaps_path
   h5.title Kubernetes
   ul.list
     li 
class="#{active_class?(settings_kubelet_compute_resources_reservations_path?)}"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/velum-master/app/views/settings/dex_connector_ldaps/_form.html.slim 
new/velum-master/app/views/settings/dex_connector_ldaps/_form.html.slim
--- old/velum-master/app/views/settings/dex_connector_ldaps/_form.html.slim     
1970-01-01 01:00:00.000000000 +0100
+++ new/velum-master/app/views/settings/dex_connector_ldaps/_form.html.slim     
2018-07-30 08:40:27.000000000 +0200
@@ -0,0 +1,138 @@
+= form_for [:settings, @certificate_holder], html: { class: 
"dex-connectors-form"} do |f|
+  .form-group class="#{error_class_for(@certificate_holder, :name)}"
+    = f.label :name
+    = f.text_field :name, class: "form-control", value: 
@certificate_holder.name
+    = error_messages_for(@certificate_holder, :name)
+
+  hr
+  h4 Server
+
+  .form-group class="#{error_class_for(@certificate_holder, :host)}"
+    = f.label :host
+    = f.text_field :host, class: "form-control", value: 
@certificate_holder.host
+    = error_messages_for(@certificate_holder, :host)
+
+  .form-group class="#{error_class_for(@certificate_holder, :port)}"
+    = f.label :port
+    = f.text_field :port, class: "form-control", value: 
@certificate_holder.port
+    = error_messages_for(@certificate_holder, :port)
+
+  .form-group class="#{error_class_for(@certificate_holder, :start_tls)}"
+    = f.label :start_tls, "StartTLS"
+    br
+    .btn-group.btn-group-toggle data-toggle="buttons"
+      = f.label :start_tls, nil, class: "btn btn-default #{'btn-primary 
active' if @certificate_holder.start_tls}"
+        = f.radio_button :start_tls, "true", checked: 
@certificate_holder.start_tls
+        | On
+      = f.label :start_tls, nil, class: "btn btn-default #{'btn-primary 
active' unless @certificate_holder.start_tls}"
+        = f.radio_button :start_tls, "false", checked: 
!@certificate_holder.start_tls
+        | Off
+    = error_messages_for(@certificate_holder, :start_tls)
+
+
+  .form-group class="#{error_class_for(@cert, :certificate)}"
+    = f.label :certificate
+    p Paste the certificate for the LDAP server here.
+    = f.text_area :certificate, value: @cert.certificate, class: 
"form-control", rows: 5, required: true
+    = error_messages_for(@cert, :certificate)
+
+  br
+  h4 Authentication
+
+  .form-group class="#{error_class_for(@certificate_holder, :bind_anon)}"
+    = f.label :bind_anon, "Anonymous"
+    br
+    .btn-group.btn-group-toggle data-toggle="buttons"
+      = f.label :bind_anon, nil, class: "btn btn-default #{'btn-primary 
active' if @certificate_holder.bind_anon}", data: {toggle: "collapse", target: 
".ldap-dn-authentication"}
+        = f.radio_button :bind_anon, "true", checked: 
@certificate_holder.bind_anon
+        | True
+      = f.label :bind_anon, nil, class: "btn btn-default #{'btn-primary 
active' unless @certificate_holder.bind_anon}", data: {toggle: "collapse", 
target: ".ldap-dn-authentication"}
+        = f.radio_button :bind_anon, "false", checked: 
!@certificate_holder.bind_anon
+        | False
+    = error_messages_for(@certificate_holder, :bind_anon)
+
+  .ldap-dn-authentication.collapse class="#{'in' if 
!@certificate_holder.bind_anon}"
+    .form-group class="#{error_class_for(@certificate_holder, :bind_dn)}"
+      = f.label :bind_dn, "DN"
+      = f.text_field :bind_dn, class: "form-control", value: 
@certificate_holder.bind_dn, required: !@certificate_holder.bind_anon, disable: 
@certificate_holder.bind_anon
+      = error_messages_for(@certificate_holder, :bind_dn)
+
+    .form-group class="#{error_class_for(@certificate_holder, :bind_pw)}"
+      = f.label :bind_pw, "Password"
+      = f.password_field :bind_pw, class: "form-control", value: 
@certificate_holder.bind_pw, required: !@certificate_holder.bind_anon, disable: 
@certificate_holder.bind_anon
+      = error_messages_for(@certificate_holder, :bind_pw)
+
+  hr
+  h4 User Search
+  .form-group class="#{error_class_for(@certificate_holder, :username_prompt)}"
+    = f.label :username_prompt, "Username Prompt"
+    = f.text_field :username_prompt, class: "form-control", value: 
@certificate_holder.username_prompt
+    = error_messages_for(@certificate_holder, :username_prompt)
+
+  .form-group class="#{error_class_for(@certificate_holder, :user_base_dn)}"
+    = f.label :user_base_dn, "Base DN"
+    = f.text_field :user_base_dn, class: "form-control", value: 
@certificate_holder.user_base_dn
+    = error_messages_for(@certificate_holder, :user_base_dn)
+
+  .form-group class="#{error_class_for(@certificate_holder, :user_filter)}"
+    = f.label :user_filter, "Filter"
+    = f.text_field :user_filter, class: "form-control", value: 
@certificate_holder.user_filter
+    = error_messages_for(@certificate_holder, :user_filter)
+
+  br
+  h4 User Attribute Map
+
+  .form-group class="#{error_class_for(@certificate_holder, 
:user_attr_username)}"
+    = f.label :user_attr_username, "Username"
+    = f.text_field :user_attr_username, class: "form-control", value: 
@certificate_holder.user_attr_username
+    = error_messages_for(@certificate_holder, :user_attr_username)
+
+  .form-group class="#{error_class_for(@certificate_holder, :user_attr_id)}"
+    = f.label :user_attr_id, "ID"
+    = f.text_field :user_attr_id, class: "form-control", value: 
@certificate_holder.user_attr_id
+    = error_messages_for(@certificate_holder, :user_attr_id)
+
+  .form-group class="#{error_class_for(@certificate_holder, :user_attr_email)}"
+    = f.label :user_attr_email, "Email"
+    = f.text_field :user_attr_email, class: "form-control", value: 
@certificate_holder.user_attr_email
+    = error_messages_for(@certificate_holder, :user_attr_email)
+
+  .form-group class="#{error_class_for(@certificate_holder, :user_attr_name)}"
+    = f.label :user_attr_name, "Name"
+    = f.text_field :user_attr_name, class: "form-control", value: 
@certificate_holder.user_attr_name
+    = error_messages_for(@certificate_holder, :user_attr_name)
+
+  hr
+  h4 Group Search
+
+  .form-group class="#{error_class_for(@certificate_holder, :group_base_dn)}"
+    = f.label :group_base_dn, "Base DN"
+    = f.text_field :group_base_dn, class: "form-control", value: 
@certificate_holder.group_base_dn
+    = error_messages_for(@certificate_holder, :group_base_dn)
+
+  .form-group class="#{error_class_for(@certificate_holder, :group_filter)}"
+    = f.label :group_filter, "Filter"
+    = f.text_field :group_filter, class: "form-control", value: 
@certificate_holder.group_filter
+    = error_messages_for(@certificate_holder, :group_filter)
+
+  br
+  h4 Group Attribute Map
+
+  .form-group class="#{error_class_for(@certificate_holder, :group_attr_user)}"
+    = f.label :group_attr_user, "User"
+    = f.text_field :group_attr_user, class: "form-control", value: 
@certificate_holder.group_attr_user
+    = error_messages_for(@certificate_holder, :group_attr_user)
+
+  .form-group class="#{error_class_for(@certificate_holder, 
:group_attr_group)}"
+    = f.label :group_attr_group, "Group"
+    = f.text_field :group_attr_group, class: "form-control", value: 
@certificate_holder.group_attr_group
+    = error_messages_for(@certificate_holder, :group_attr_group)
+
+  .form-group class="#{error_class_for(@certificate_holder, :group_attr_name)}"
+    = f.label :group_attr_name, "Name"
+    = f.text_field :group_attr_name, class: "form-control", value: 
@certificate_holder.group_attr_name
+    = error_messages_for(@certificate_holder, :group_attr_name)
+
+  .form-actions.clearfix
+    = f.submit "Save", class: "btn btn-primary action"
+    = link_to "Cancel", settings_dex_connector_ldaps_path, class: "btn 
btn-default action"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/velum-master/app/views/settings/dex_connector_ldaps/edit.html.slim 
new/velum-master/app/views/settings/dex_connector_ldaps/edit.html.slim
--- old/velum-master/app/views/settings/dex_connector_ldaps/edit.html.slim      
1970-01-01 01:00:00.000000000 +0100
+++ new/velum-master/app/views/settings/dex_connector_ldaps/edit.html.slim      
2018-07-30 08:40:27.000000000 +0200
@@ -0,0 +1,3 @@
+h2 Edit
+
+= render 'form'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/velum-master/app/views/settings/dex_connector_ldaps/index.html.slim 
new/velum-master/app/views/settings/dex_connector_ldaps/index.html.slim
--- old/velum-master/app/views/settings/dex_connector_ldaps/index.html.slim     
1970-01-01 01:00:00.000000000 +0100
+++ new/velum-master/app/views/settings/dex_connector_ldaps/index.html.slim     
2018-07-30 08:40:27.000000000 +0200
@@ -0,0 +1,25 @@
+= render 'settings/apply'
+
+h2 LDAP Connectors
+
+= link_to "Add LDAP connector", new_settings_dex_connector_ldap_path, class: 
"btn btn-primary add-entry-btn"
+
+- if @ldap_connectors.present?
+    section
+      table.table
+        thead
+          tr
+            th Name
+            th width="110"
+        tbody
+          - @ldap_connectors.each do |conn|
+            tr class="dex_connector_ldap#{conn.id}"
+              td
+                = link_to conn.name, settings_dex_connector_ldap_path(conn)
+              td.actions
+                = link_to edit_settings_dex_connector_ldap_path(conn), class: 
"btn btn-default icon-only edit-btn" do
+                  i.fa.fa-pencil
+                = link_to settings_dex_connector_ldap_path(conn), method: 
"delete", class: "btn btn-danger icon-only delete-btn", data: { confirm: "Are 
you sure?" } do
+                  i.fa.fa-trash-o
+- else
+  p No LDAP connectors found.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/velum-master/app/views/settings/dex_connector_ldaps/new.html.slim 
new/velum-master/app/views/settings/dex_connector_ldaps/new.html.slim
--- old/velum-master/app/views/settings/dex_connector_ldaps/new.html.slim       
1970-01-01 01:00:00.000000000 +0100
+++ new/velum-master/app/views/settings/dex_connector_ldaps/new.html.slim       
2018-07-30 08:40:27.000000000 +0200
@@ -0,0 +1,3 @@
+h2  New LDAP Connector
+
+= render 'form'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/velum-master/app/views/settings/dex_connector_ldaps/show.html.slim 
new/velum-master/app/views/settings/dex_connector_ldaps/show.html.slim
--- old/velum-master/app/views/settings/dex_connector_ldaps/show.html.slim      
1970-01-01 01:00:00.000000000 +0100
+++ new/velum-master/app/views/settings/dex_connector_ldaps/show.html.slim      
2018-07-30 08:40:27.000000000 +0200
@@ -0,0 +1,100 @@
+= render 'settings/apply'
+
+header.settings-content-header.clearfix
+  .title.pull-left
+    h2 #{@certificate_holder.name} details
+  .actions.pull-right
+    = link_to settings_dex_connector_ldap_path(@certificate_holder), method: 
"delete", class: "btn btn-danger", data: { confirm: "Are you sure?" } do
+      | Delete
+    = link_to edit_settings_dex_connector_ldap_path(@certificate_holder), 
class: "btn btn-primary" do
+      | Edit
+
+section.settings-details
+  .field
+    .details-label Name
+    .details-value
+      = @certificate_holder.name
+
+  h4 Server
+  .field
+    .details-label Host
+    .details-value
+      = @certificate_holder.host
+  .field
+    .details-label Port
+    .details-value
+      = @certificate_holder.port
+  .field
+    .details-label StartTLS
+    .details-value
+      = @certificate_holder.start_tls
+
+  - if @certificate_holder.certificate.present?
+    .field
+      .details-label Certificate
+      .details-value
+        = @certificate_holder.certificate.certificate
+
+  h4 Authentication
+  .field
+    .details-label Anonymous
+    .details-value
+      = @certificate_holder.bind_anon
+  .field
+    .details-label DN
+    .details-value
+      = @certificate_holder.bind_dn
+
+  h4 User Search
+  .field
+    .details-label Username Prompt
+    .details-value
+      = @certificate_holder.username_prompt
+  .field
+    .details-label Base DN
+    .details-value
+      = @certificate_holder.user_base_dn
+  .field
+    .details-label Filter
+    .details-value
+      = @certificate_holder.user_filter
+  h4 User Attribute Map
+  .field
+    .details-label Username
+    .details-value
+      = @certificate_holder.user_attr_username
+  .field
+    .details-label ID
+    .details-value
+      = @certificate_holder.user_attr_id
+  .field
+    .details-label Email
+    .details-value
+      = @certificate_holder.user_attr_email
+  .field
+    .details-label Name
+    .details-value
+      = @certificate_holder.user_attr_name
+
+  h4 Group Search
+  .field
+    .details-label Base DN
+    .details-value
+      = @certificate_holder.group_base_dn
+  .field
+    .details-label Filter
+    .details-value
+      = @certificate_holder.group_filter
+  h4 Group Attribute Map
+  .field
+    .details-label User
+    .details-value
+      = @certificate_holder.group_attr_user
+  .field
+    .details-label Group
+    .details-value
+      = @certificate_holder.group_attr_group
+  .field
+    .details-label Name
+    .details-value
+      = @certificate_holder.group_attr_name
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/velum-master/app/views/setup/worker_bootstrap_gce.html.slim 
new/velum-master/app/views/setup/worker_bootstrap_gce.html.slim
--- old/velum-master/app/views/setup/worker_bootstrap_gce.html.slim     
1970-01-01 01:00:00.000000000 +0100
+++ new/velum-master/app/views/setup/worker_bootstrap_gce.html.slim     
2018-07-30 08:40:27.000000000 +0200
@@ -0,0 +1,38 @@
+= content_for :body_class, "worker_bootstrap"
+
+h1
+  ' Bootstrap your #{product_name}
+  small in Google Compute Engine
+
+
+= form_for @cloud_cluster, url: setup_build_cloud_cluster_path do |form|
+  = form.hidden_field :cloud_framework
+  p
+    ' In order to complete the installation, it is necessary to bootstrap a few
+    ' additional nodes, those will be the Kubernetes Master and Workers.
+
+  = render "instance_type_panel",
+    form: form,
+    list_url: "https://cloud.google.com/compute/docs/machine-types";
+
+  = render "cluster_size_panel", form: form
+
+  .panel.panel-default
+    .panel-heading
+      h3.panel-title Networking
+    .panel-body
+      .col-lg-3.col-md-6
+        .form-group.required
+          label for="cloud_cluster_network_id" Network
+          = form.text_field :network_id, class: "form-control", required: true
+      .col-lg-3.col-md-6
+        .form-group
+          label for="cloud_cluster_subnet_id" Subnetwork
+          = form.text_field :subnet_id, class: "form-control"
+
+  .clearfix.text-right.steps-container
+    = link_to "Back", setup_path, class: "btn btn-danger"
+    = form.submit "Next", class: "btn btn-primary"
+
+- content_for :page_javascript do
+  = javascript_include_tag 'cloud/bootstrap', defer: true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/velum-master/config/initializers/filter_parameter_logging.rb 
new/velum-master/config/initializers/filter_parameter_logging.rb
--- old/velum-master/config/initializers/filter_parameter_logging.rb    
2018-07-19 11:18:06.000000000 +0200
+++ new/velum-master/config/initializers/filter_parameter_logging.rb    
2018-07-30 08:40:27.000000000 +0200
@@ -1,4 +1,4 @@
 # Be sure to restart your server when you modify this file.
 
 # Configure sensitive parameters which will be filtered from the log file.
-Rails.application.config.filter_parameters += [:password, :certificate]
+Rails.application.config.filter_parameters += [:password, :certificate, 
:bind_pw]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/velum-master/config/routes.rb 
new/velum-master/config/routes.rb
--- old/velum-master/config/routes.rb   2018-07-19 11:18:06.000000000 +0200
+++ new/velum-master/config/routes.rb   2018-07-30 08:40:27.000000000 +0200
@@ -64,6 +64,7 @@
     resources :kubelet_compute_resources_reservations, only: [:index, :create]
     resources :auditing, only: [:index, :create]
     resources :system_certificates
+    resources :dex_connector_ldaps, path: :ldap_connectors
   end
 end
 # rubocop:enable Metrics/BlockLength
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/velum-master/spec/controllers/internal_api/v1/pillars_controller_spec.rb 
new/velum-master/spec/controllers/internal_api/v1/pillars_controller_spec.rb
--- 
old/velum-master/spec/controllers/internal_api/v1/pillars_controller_spec.rb    
    2018-07-19 11:18:06.000000000 +0200
+++ 
new/velum-master/spec/controllers/internal_api/v1/pillars_controller_spec.rb    
    2018-07-30 08:40:27.000000000 +0200
@@ -180,7 +180,7 @@
       )
       create(
         :pillar,
-        pillar: "cloud:profiles:cluster_node:network_interfaces:SubnetId",
+        pillar: "cloud:profiles:cluster_node:subnet",
         value:  subnet_id
       )
       create(
@@ -275,7 +275,7 @@
       )
       create(
         :pillar,
-        pillar: "cloud:profiles:cluster_node:network_interfaces:SubnetId",
+        pillar: "cloud:profiles:cluster_node:subnet",
         value:  subnet_id
       )
       create(
@@ -301,6 +301,57 @@
     end
   end
 
+  context "when in GCE framework" do
+    let(:custom_instance_type) { "custom-instance-type" }
+    let(:network_id) { "gcenetwork" }
+    let(:subnet_id) { "gcesubnetwork" }
+
+    let(:expected_response) do
+      {
+        registries:          [],
+        system_certificates: [],
+        kubelet:             {
+          :"compute-resources" => {},
+          :"eviction-hard"     => ""
+        },
+        cloud:               {
+          framework: "gce",
+          profiles:  {
+            cluster_node: {
+              size:       custom_instance_type,
+              network:    network_id,
+              subnetwork: subnet_id
+            }
+          }
+        }
+      }
+    end
+
+    before do
+      create(:gce_pillar)
+      create(
+        :pillar,
+        pillar: "cloud:profiles:cluster_node:size",
+        value:  custom_instance_type
+      )
+      create(
+        :pillar,
+        pillar: "cloud:profiles:cluster_node:network",
+        value:  network_id
+      )
+      create(
+        :pillar,
+        pillar: "cloud:profiles:cluster_node:subnet",
+        value:  subnet_id
+      )
+    end
+
+    it "has cloud configuration" do
+      get :show
+      expect(json).to eq(expected_response)
+    end
+  end
+
   context "with Openstack provider" do
     let(:expected_response) do
       {
@@ -388,7 +439,7 @@
       bind:            {
         anonymous: false,
         dn:        "cn=admin,dc=ldap_host_#{num},dc=com",
-        pw:        nil
+        pw:        "pass"
       },
       username_prompt: "Username",
       user:            {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/velum-master/spec/controllers/settings/dex_connector_ldaps_controller_spec.rb
 
new/velum-master/spec/controllers/settings/dex_connector_ldaps_controller_spec.rb
--- 
old/velum-master/spec/controllers/settings/dex_connector_ldaps_controller_spec.rb
   1970-01-01 01:00:00.000000000 +0100
+++ 
new/velum-master/spec/controllers/settings/dex_connector_ldaps_controller_spec.rb
   2018-07-30 08:40:27.000000000 +0200
@@ -0,0 +1,201 @@
+require "rails_helper"
+
+RSpec.describe Settings::DexConnectorLdapsController, type: :controller do
+  let(:user) { create(:user) }
+
+  before do
+    setup_done
+    sign_in user
+  end
+
+  describe "GET #index" do
+    let!(:connector) { create(:dex_connector_ldap) }
+
+    before do
+      get :index
+    end
+
+    it "populates an array of ldap dex connectors" do
+      expect(assigns(:ldap_connectors)).to match_array([connector])
+    end
+  end
+
+  describe "GET #new" do
+    before do
+      get :new
+    end
+
+    it "assigns a new ldap dex connector to @certificate_holder" do
+      expect(assigns(:certificate_holder)).to be_a_new(DexConnectorLdap)
+    end
+
+    it "assigns a new certificate to @cert" do
+      expect(assigns(:cert)).to be_a_new(Certificate)
+    end
+  end
+
+  describe "GET #edit" do
+    let!(:certificate) { create(:certificate) }
+    let!(:dex_connector_ldap) { create(:dex_connector_ldap) }
+    let!(:dex_connector_ldap_with_cert) { create(:dex_connector_ldap) }
+
+    context "without certificate" do
+      before do
+        get :edit, id: dex_connector_ldap.id
+      end
+
+      it "assigns dex_connector_ldap to @dex_connector_ldap" do
+        expect(assigns(:dex_connector_ldap)).not_to be_a_new(DexConnectorLdap)
+      end
+
+      it "assigns a new Certificate to @cert" do
+        expect(assigns(:cert)).to be_a_new(Certificate)
+      end
+    end
+
+    context "with certificate" do
+      before do
+        CertificateService.create!(service:     dex_connector_ldap_with_cert,
+                                   certificate: certificate)
+        get :edit, id: dex_connector_ldap_with_cert.id
+      end
+
+      it "assigns dex_connector_ldap to @certificate_holder" do
+        expect(assigns(:certificate_holder)).not_to be_a_new(DexConnectorLdap)
+      end
+
+      it "assigns the existing certificate to @cert" do
+        expect(assigns(:cert)).not_to be_a_new(Certificate)
+      end
+    end
+
+    it "return 404 if ldap connector does not exist" do
+      get :edit, id: DexConnectorLdap.last.id + 1
+      expect(response).to have_http_status(:not_found)
+    end
+  end
+
+  describe "POST #create" do
+    it "can not save ldap connector with invalid field" do
+      expect do
+        post :create, dex_connector_ldap: { name:      "ldap_fail",
+                                            start_tls: nil }
+      end.not_to change(DexConnectorLdap, :count)
+      expect(response).to have_http_status(:unprocessable_entity)
+    end
+
+    context "with ldap connector saved in the database" do
+      let!(:certificate) { create(:certificate) }
+      let(:dex_connector_ldap) { DexConnectorLdap.find_by(name: "ldap1") }
+
+      before do
+        post :create, dex_connector_ldap: { name:               "ldap1",
+                                            host:               "test.com",
+                                            port:               389,
+                                            start_tls:          false,
+                                            certificate:        
certificate.certificate,
+                                            bind_anon:          false,
+                                            bind_dn:            
"cn=admin,dc=example,dc=org",
+                                            bind_pw:            "admin",
+                                            username_prompt:    "Username",
+                                            user_base_dn:       
"dc=example,dc=org",
+                                            user_filter:        
"(objectClass=person)",
+                                            user_attr_username: "uid",
+                                            user_attr_id:       "uid",
+                                            user_attr_email:    "mail",
+                                            user_attr_name:     "fn",
+                                            group_base_dn:      
"dc=example,dc=org",
+                                            group_filter:       
"(objectClass=group)",
+                                            group_attr_user:    "uid",
+                                            group_attr_group:   "member",
+                                            group_attr_name:    "name" }
+
+      end
+      it "saves the corrent name" do
+        expect(dex_connector_ldap.name).to eq("ldap1")
+      end
+      it "saves the correct host" do
+        expect(dex_connector_ldap.host).to eq("test.com")
+      end
+      it "saves the correct port" do
+        expect(dex_connector_ldap.port).to eq(389)
+      end
+      it "saves the correct start_tls value" do
+        expect(dex_connector_ldap.start_tls).to eq(false)
+      end
+      it "saves the correct certificate" do
+        expect(dex_connector_ldap.certificate.certificate).to 
eq(certificate.certificate.strip)
+      end
+      it "saves the correct bind_anon value" do
+        expect(dex_connector_ldap.bind_anon).to eq(false)
+      end
+      it "saves the correct bind_dn" do
+        expect(dex_connector_ldap.bind_dn).to eq("cn=admin,dc=example,dc=org")
+      end
+      it "saves the correct bind_pw" do
+        expect(dex_connector_ldap.bind_pw).to eq("admin")
+      end
+      it "saves the correct username_prompt" do
+        expect(dex_connector_ldap.username_prompt).to eq("Username")
+      end
+      it "saves the correct user_base_dn" do
+        expect(dex_connector_ldap.user_base_dn).to eq("dc=example,dc=org")
+      end
+      it "saves the correct user_filter" do
+        expect(dex_connector_ldap.user_filter).to eq("(objectClass=person)")
+      end
+      it "saves the correct user_attr_username" do
+        expect(dex_connector_ldap.user_attr_username).to eq("uid")
+      end
+      it "saves the correct user_attr_id" do
+        expect(dex_connector_ldap.user_attr_id).to eq("uid")
+      end
+      it "saves the correct user_attr_email" do
+        expect(dex_connector_ldap.user_attr_email).to eq("mail")
+      end
+      it "saves the correct user_attr_name" do
+        expect(dex_connector_ldap.user_attr_name).to eq("fn")
+      end
+      it "saves the correct group_base_dn" do
+        expect(dex_connector_ldap.group_base_dn).to eq("dc=example,dc=org")
+      end
+      it "saves the correct group_filter" do
+        expect(dex_connector_ldap.group_filter).to eq("(objectClass=group)")
+      end
+      it "saves the correct group_attr_user" do
+        expect(dex_connector_ldap.group_attr_user).to eq("uid")
+      end
+      it "saves the correct group_attr_group" do
+        expect(dex_connector_ldap.group_attr_group).to eq("member")
+      end
+      it "saves the correct group_attr_name" do
+        expect(dex_connector_ldap.group_attr_name).to eq("name")
+      end
+    end
+  end
+
+  describe "PATCH #update" do
+    let!(:certificate) { create(:certificate) }
+    let!(:dex_connector_ldap) { create(:dex_connector_ldap) }
+
+    before do
+      CertificateService.create!(service: dex_connector_ldap, certificate: 
certificate)
+    end
+
+    it "updates a ldap connector" do
+      dex_connector_ldap_params = { name: "new name" }
+      put :update, id: dex_connector_ldap.id, dex_connector_ldap: 
dex_connector_ldap_params
+      expect(DexConnectorLdap.find(dex_connector_ldap.id).name).to eq("new 
name")
+    end
+  end
+
+  describe "DELETE #destroy" do
+    let!(:dex_connector_ldap) { create(:dex_connector_ldap) }
+
+    it "deletes a ldap connector" do
+      expect do
+        delete :destroy, id: dex_connector_ldap.id
+      end.to change(DexConnectorLdap, :count).by(-1)
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/velum-master/spec/controllers/setup_controller_spec.rb 
new/velum-master/spec/controllers/setup_controller_spec.rb
--- old/velum-master/spec/controllers/setup_controller_spec.rb  2018-07-19 
11:18:06.000000000 +0200
+++ new/velum-master/spec/controllers/setup_controller_spec.rb  2018-07-30 
08:40:27.000000000 +0200
@@ -152,6 +152,21 @@
         expect(response).to render_template(:worker_bootstrap_azure)
       end
     end
+
+    context "when in GCE framework" do
+      before do
+        create(:gce_pillar)
+        get :worker_bootstrap
+      end
+
+      it "assigns @instance_sizes" do
+        expect(assigns(:instance_types)).to all(be_a(Velum::InstanceType))
+      end
+
+      it "renders GCE view" do
+        expect(response).to render_template(:worker_bootstrap_gce)
+      end
+    end
   end
 
   describe "POST /setup/worker-boostrap via HTML in EC2" do
@@ -328,6 +343,89 @@
       end
     end
   end
+
+  describe "POST /setup/worker-boostrap via HTML in GCE" do
+    let(:instance_type) { "n1-standard-8" }
+    let(:instance_count) { 5 }
+    let(:network_id) { "gcenetwork" }
+    let(:subnet_id) { "gcesubnetwork" }
+    let(:cloud_cluster_params) do
+      {
+        instance_type:  instance_type,
+        instance_count: instance_count,
+        network_id:     network_id,
+        subnet_id:      subnet_id
+      }
+    end
+
+    before do
+      sign_in user
+      create(:gce_pillar)
+      Pillar.create pillar: "dashboard", value: "localhost"
+
+      allow(Velum::Salt).to receive(:build_cloud_cluster)
+    end
+
+    context "when saving succeeds" do
+      before do
+        ensure_pillar_refresh do
+          post :build_cloud_cluster, cloud_cluster: cloud_cluster_params
+        end
+      end
+
+      it "always uses the framework pillar" do
+        expect(assigns(:cloud_cluster).cloud_framework).to eq("gce")
+      end
+
+      it "assigns the instance type" do
+        expect(assigns(:cloud_cluster).instance_type).to eq(instance_type)
+      end
+
+      it "assigns the quantity of workers" do
+        expect(assigns(:cloud_cluster).instance_count).to eq(instance_count)
+      end
+
+      it "assigns the EC2 security group ID" do
+        expect(assigns(:cloud_cluster).network_id).to eq(network_id)
+      end
+
+      it "assigns the EC2 subnet ID" do
+        expect(assigns(:cloud_cluster).subnet_id).to eq(subnet_id)
+      end
+
+      it "calls salt-cloud" do
+        expect(Velum::Salt).to 
have_received(:build_cloud_cluster).with(instance_count).once
+      end
+
+      it "uses a flash to provide confirmation" do
+        expect(flash[:notice]).to be_present
+      end
+    end
+
+    context "when saving fails" do
+      let(:error_message) { "Nope!" }
+      let(:mock_cloud_cluster) do
+        mock = CloudCluster.new(cloud_cluster_params)
+        allow(mock).to receive(:save!).and_raise(
+          ActiveRecord::ActiveRecordError.new(error_message)
+        )
+        mock
+      end
+
+      before do
+        allow(CloudCluster).to receive(:new).and_return(mock_cloud_cluster)
+        post :build_cloud_cluster, cloud_cluster: cloud_cluster_params
+      end
+
+      it "redirects back to bootstrap" do
+        expect(controller).to redirect_to(:setup_worker_bootstrap)
+      end
+
+      it "uses a flash to show error messages" do
+        expect(flash[:error]).to be_present
+      end
+    end
+  end
 
   describe "POST /setup/discovery via HTML" do
     before do
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/velum-master/spec/factories/dex_connectors_ldap_factory.rb 
new/velum-master/spec/factories/dex_connectors_ldap_factory.rb
--- old/velum-master/spec/factories/dex_connectors_ldap_factory.rb      
2018-07-19 11:18:06.000000000 +0200
+++ new/velum-master/spec/factories/dex_connectors_ldap_factory.rb      
2018-07-30 08:40:27.000000000 +0200
@@ -27,7 +27,7 @@
     trait :regular_admin do
       bind_anon false
       bind_dn { "cn=admin,dc=#{host.chomp(".com")},dc=com" }
-      bind_pw nil
+      bind_pw "pass"
     end
 
     username_prompt "Username"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/velum-master/spec/factories/pillar_factory.rb 
new/velum-master/spec/factories/pillar_factory.rb
--- old/velum-master/spec/factories/pillar_factory.rb   2018-07-19 
11:18:06.000000000 +0200
+++ new/velum-master/spec/factories/pillar_factory.rb   2018-07-30 
08:40:27.000000000 +0200
@@ -19,4 +19,8 @@
     pillar { Pillar.all_pillars[:cloud_framework] }
     value "azure"
   end
+  factory :gce_pillar, parent: :pillar do
+    pillar { Pillar.all_pillars[:cloud_framework] }
+    value "gce"
+  end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/velum-master/spec/features/bootstrap_in_gce_feature_spec.rb 
new/velum-master/spec/features/bootstrap_in_gce_feature_spec.rb
--- old/velum-master/spec/features/bootstrap_in_gce_feature_spec.rb     
1970-01-01 01:00:00.000000000 +0100
+++ new/velum-master/spec/features/bootstrap_in_gce_feature_spec.rb     
2018-07-30 08:40:27.000000000 +0200
@@ -0,0 +1,32 @@
+require "rails_helper"
+require "velum/instance_type"
+
+describe "Feature: Bootstrap a cluster in GCE" do
+  let(:user) { create(:user) }
+  let(:instance_types) { Velum::InstanceType.for("gce") }
+  let(:custom_instance_type) { OpenStruct.new(key: "CUSTOM") }
+
+  before do
+    login_as user, scope: :user
+    create(:gce_pillar)
+    visit setup_worker_bootstrap_path
+  end
+
+  it "refers to GCE in the heading" do
+    expect(page).to have_css("h1", text: "Google Compute Engine")
+  end
+
+  it "allows selection of an instance type" do
+    instance_types.each do |instance_type|
+      expect(page).to have_css(instance_type_radio_finder(instance_type))
+    end
+  end
+
+  it "displays the category of the selected instance type", js: true do
+    instance_types.each do |instance_type|
+      click_instance_type_radio(instance_type)
+      expect(page).to have_text(:visible, instance_type.category.name)
+      expect(page).to have_text(:visible, instance_type.category.description)
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/velum-master/spec/features/settings/dex_connector_ldap_feature_spec.rb 
new/velum-master/spec/features/settings/dex_connector_ldap_feature_spec.rb
--- old/velum-master/spec/features/settings/dex_connector_ldap_feature_spec.rb  
1970-01-01 01:00:00.000000000 +0100
+++ new/velum-master/spec/features/settings/dex_connector_ldap_feature_spec.rb  
2018-07-30 08:40:27.000000000 +0200
@@ -0,0 +1,131 @@
+require "rails_helper"
+
+# rubocop:disable RSpec/ExampleLength
+describe "Feature: LDAP connector settings", js: true do
+  let!(:user) { create(:user) }
+  let!(:dex_connector_ldap) { create(:dex_connector_ldap) }
+  let!(:dex_connector_ldap2) { create(:dex_connector_ldap) }
+  let!(:dex_connector_ldap3) { create(:dex_connector_ldap) }
+  let(:admin_cert_text) { file_fixture("admin.crt").read.strip }
+
+  before do
+    setup_done
+    login_as user, scope: :user
+  end
+
+  describe "#index" do
+    before do
+      visit settings_dex_connector_ldaps_path
+    end
+
+    it "allows a user to delete an ldap connector" do
+      expect(page).to have_content(dex_connector_ldap.name)
+      accept_alert do
+        find(".dex_connector_ldap#{dex_connector_ldap.id} .delete-btn").click
+      end
+
+      expect(page).to have_content("LDAP Connector was successfully removed.")
+      expect(page).not_to have_content(dex_connector_ldap.name)
+    end
+
+    it "allows a user to go to an ldap connector's details page" do
+      click_link(dex_connector_ldap.name)
+
+      expect(page).to 
have_current_path(settings_dex_connector_ldap_path(dex_connector_ldap))
+    end
+
+    it "allows an user to go to an ldap connector's edit page" do
+      find(".dex_connector_ldap#{dex_connector_ldap.id} .edit-btn").click
+
+      expect(page).to 
have_current_path(edit_settings_dex_connector_ldap_path(dex_connector_ldap))
+    end
+
+    it "allows a user to go to the new ldap connector page" do
+      click_link("Add LDAP connector")
+
+      expect(page).to have_current_path(new_settings_dex_connector_ldap_path)
+    end
+
+    it "lists all the ldap connectors" do
+      expect(page).to have_content(dex_connector_ldap.name)
+      expect(page).to have_content(dex_connector_ldap2.name)
+      expect(page).to have_content(dex_connector_ldap3.name)
+    end
+  end
+
+  describe "#new" do
+    before do
+      visit new_settings_dex_connector_ldap_path
+    end
+
+    it "allows a user to create an ldap connector (w/ certificate)" do
+      fill_in id: "dex_connector_ldap_name", with: "openldap"
+      fill_in "Host", with: "ldaptest.com"
+      fill_in "Certificate", with: admin_cert_text
+      fill_in id: "dex_connector_ldap_bind_dn", with: 
"cn=admin,dc=ldaptest,dc=com"
+      fill_in "Password", with: "pass"
+      click_button("Save")
+
+      last_ldap_connector = DexConnectorLdap.last
+      expect(page).to have_content(admin_cert_text)
+      expect(page).to have_content("DexConnectorLdap was successfully 
created.")
+      expect(page).to 
have_current_path(settings_dex_connector_ldap_path(last_ldap_connector))
+    end
+
+    it "shows an error message if model validation fails" do
+      fill_in "Port", with: "AAA"
+      fill_in "Certificate", with: admin_cert_text
+      fill_in "Password", with: "pass"
+      click_button("Save")
+
+      expect(page).to have_content("Name can't be blank")
+      expect(page).to have_content("Host can't be blank")
+      expect(page).to have_content("Port is not a number")
+    end
+  end
+
+  describe "#edit" do
+    before do
+      visit edit_settings_dex_connector_ldap_path(dex_connector_ldap)
+    end
+
+    it "allows a user to edit an ldap connector" do
+      fill_in "Port", with: 626
+      fill_in "Certificate", with: admin_cert_text
+      click_button("Save")
+
+      expect(page).to have_content("DexConnectorLdap was successfully 
updated.")
+    end
+
+    it "shows an error message if model validation fails" do
+      fill_in "Port", with: "AAA"
+      fill_in "Certificate", with: admin_cert_text
+      click_button("Save")
+
+      expect(page).to have_content("Port is not a number")
+    end
+  end
+
+  describe "#show" do
+    before do
+      visit settings_dex_connector_ldap_path(dex_connector_ldap)
+    end
+
+    it "allows a user to delete an ldap connector" do
+      accept_alert do
+        click_on("Delete")
+      end
+
+      expect(page).not_to have_content(dex_connector_ldap.name)
+      expect(page).to have_content("LDAP Connector was successfully removed.")
+      expect(page).to have_current_path(settings_dex_connector_ldaps_path)
+    end
+
+    it "allows a user to go to an ldap connector's edit page" do
+      click_on("Edit")
+
+      expect(page).to 
have_current_path(edit_settings_dex_connector_ldap_path(dex_connector_ldap))
+    end
+  end
+end
+# rubocop:enable RSpec/ExampleLength
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/velum-master/spec/models/cloud_cluster_spec.rb 
new/velum-master/spec/models/cloud_cluster_spec.rb
--- old/velum-master/spec/models/cloud_cluster_spec.rb  2018-07-19 
11:18:06.000000000 +0200
+++ new/velum-master/spec/models/cloud_cluster_spec.rb  2018-07-30 
08:40:27.000000000 +0200
@@ -248,6 +248,44 @@
     end
   end
 
+  context "when framework is GCE" do
+    let(:framework) { "gce" }
+    let(:cluster) do
+      described_class.new(
+        cloud_framework: framework,
+        instance_type:   custom_instance_type,
+        network_id:      network_id,
+        subnet_id:       subnet_id
+      )
+    end
+
+    it "stores instance type as :cloud_worker_type Pillar and refreshes" do
+      ensure_pillar_refresh do
+        expect(cluster.save).to be(true)
+      end
+      expect(Pillar.value(pillar: :cloud_worker_type)).to 
eq(custom_instance_type)
+    end
+
+    it "stores network name as :cloud_worker_net Pillar and refreshes" do
+      ensure_pillar_refresh do
+        expect(cluster.save).to be(true)
+      end
+      expect(Pillar.value(pillar: :cloud_worker_net)).to eq(network_id)
+    end
+
+    it "stores subnet name as :cloud_worker_subnetwork Pillar and refreshes" do
+      ensure_pillar_refresh do
+        expect(cluster.save).to be(true)
+      end
+      expect(Pillar.value(pillar: :cloud_worker_subnet)).to eq(subnet_id)
+    end
+
+    it "describes the framework in string representation" do
+      substring = "in GCE"
+      expect(cluster.to_s).to match(substring)
+    end
+  end
+
   context "when building" do
     let(:cluster) do
       described_class.new(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/velum-master/spec/models/dex_connector_ldap_spec.rb 
new/velum-master/spec/models/dex_connector_ldap_spec.rb
--- old/velum-master/spec/models/dex_connector_ldap_spec.rb     2018-07-19 
11:18:06.000000000 +0200
+++ new/velum-master/spec/models/dex_connector_ldap_spec.rb     2018-07-30 
08:40:27.000000000 +0200
@@ -1,6 +1,24 @@
 require "rails_helper"
 
 describe DexConnectorLdap, type: :model do
+  subject { create(:dex_connector_ldap) }
+
+  it { is_expected.to validate_presence_of(:name) }
+  it { is_expected.to validate_presence_of(:port) }
+  it { is_expected.to validate_numericality_of(:port).only_integer }
+  it { is_expected.to validate_presence_of(:username_prompt) }
+  it { is_expected.to validate_presence_of(:user_base_dn) }
+  it { is_expected.to validate_presence_of(:user_filter) }
+  it { is_expected.to validate_presence_of(:user_attr_username) }
+  it { is_expected.to validate_presence_of(:user_attr_id) }
+  it { is_expected.to validate_presence_of(:user_attr_email) }
+  it { is_expected.to validate_presence_of(:user_attr_name) }
+  it { is_expected.to validate_presence_of(:group_base_dn) }
+  it { is_expected.to validate_presence_of(:group_filter) }
+  it { is_expected.to validate_presence_of(:group_attr_user) }
+  it { is_expected.to validate_presence_of(:group_attr_group) }
+  it { is_expected.to validate_presence_of(:group_attr_name) }
+
   describe "#configure_dex_ldap_connector" do
     let(:dex_connector_ldap) { create(:dex_connector_ldap) }
     let(:certificate)        { create(:certificate) }
@@ -18,4 +36,37 @@
         .to include("BEGIN CERTIFICATE")
     end
   end
+
+  describe "#host_validations" do
+
+    it { is_expected.to validate_presence_of(:host) }
+  end
+
+  describe "#bind_dn_validations" do
+
+    context "when bind_anon is false" do
+      let(:dex_connector_ldap) { create(:dex_connector_ldap, :regular_admin) }
+
+      it { expect(dex_connector_ldap).to validate_presence_of(:bind_dn) }
+    end
+
+    context "when bind_anon is true" do
+
+      it { is_expected.not_to validate_presence_of(:bind_dn) }
+    end
+  end
+
+  describe "#bind_pw_validations" do
+
+    context "when bind_anon is false" do
+      let(:dex_connector_ldap) { create(:dex_connector_ldap, :regular_admin) }
+
+      it { expect(dex_connector_ldap).to validate_presence_of(:bind_pw) }
+    end
+
+    context "when bind_anon is true" do
+
+      it { is_expected.not_to validate_presence_of(:bind_pw) }
+    end
+  end
 end


Reply via email to