Skip to content

Commit

Permalink
Enhanced CLI configuration, render cluster config
Browse files Browse the repository at this point in the history
Your can now setup clusters configuration:
  ```
  clusters:
    - name: mycluster
      server: https://mycluster.org
      certificate-authority: |
        -----BEGIN CERTIFICATE-----
        MIIC/zCCAeegAwIBAgIULkYvGJPRl50tMoVE4BNM0laRQncwDQYJKoZIhvcNAQEL
        BQAwDzENMAsGA1UEAwwEbXljYTAeFw0xOTAyMTgyMjA5NTJaFw0xOTAyMjgyMjA5
        NTJaMA8xDTALBgNVBAMMBG15Y2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
        -----END CERTIFICATE-----
  ```

Loginapp now uses [bootstrap](https://getbootstrap.com/)
  • Loading branch information
fydrah committed Apr 22, 2019
1 parent 850e030 commit b62510c
Show file tree
Hide file tree
Showing 27 changed files with 554 additions and 116 deletions.
24 changes: 22 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

- Custom copy/paste fields (ex: `kubectl config set-cluster [...]`)
- More prometheus exports
- UX improvements
- More UX improvements

## [2.7.0] - 2019-04-22
### Added
- Custom copy/paste fields (ex: `kubectl config set-cluster [...]`). Your can now setup clusters configuration:
```
clusters:
- name: mycluster
server: https://mycluster.org
certificate-authority: |
-----BEGIN CERTIFICATE-----
MIIC/zCCAeegAwIBAgIULkYvGJPRl50tMoVE4BNM0laRQncwDQYJKoZIhvcNAQEL
BQAwDzENMAsGA1UEAwwEbXljYTAeFw0xOTAyMTgyMjA5NTJaFw0xOTAyMjgyMjA5
NTJaMA8xDTALBgNVBAMMBG15Y2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
-----END CERTIFICATE-----
```

- UX improvements, css/js has been changed for [bootstrap](https://getbootstrap.com/)

### Removed
- `web_output.skip_main_page` does not longer exists, the index page was
useless

## [2.6.0] - 2019-04-02
### Added
Expand Down
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,23 @@ web_output:
assets_dir: /assets
# Skip main page of login app
# default: false
skip_main_page: false
# Prometheus exporter configuration
prometheus:
# Port to use. Metrics are available at
# http://IP:PORT/metrics
# default: 9090
port: 9090
# Clusters list for CLI configuration
clusters:
- name: mycluster
server: https://mycluster.org
certificate-authority: |
-----BEGIN CERTIFICATE-----
MIIC/zCCAeegAwIBAgIULkYvGJPRl50tMoVE4BNM0laRQncwDQYJKoZIhvcNAQEL
BQAwDzENMAsGA1UEAwwEbXljYTAeFw0xOTAyMTgyMjA5NTJaFw0xOTAyMjgyMjA5
NTJaMA8xDTALBgNVBAMMBG15Y2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
-----END CERTIFICATE-----
insecure-skip-tls-verify: false
```
Two main examples are available:
Expand Down
6 changes: 6 additions & 0 deletions assets/css/bootstrap-theme.min.css

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions assets/css/bootstrap-theme.min.css.map

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions assets/css/bootstrap.min.css

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions assets/css/bootstrap.min.css.map

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion assets/css/form-style.min.css

This file was deleted.

26 changes: 26 additions & 0 deletions assets/css/loginapp.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
.loginapp {
font-family: Georgia, "Times New Roman", Times, serif;
}

.loginapp h1 {
color: #5C5C5C;
}

.loginapp label {
color: #B9B9B9;
font-family: Arial, Helvetica, sans-serif;
}

.loginapp input {
background: #2471FF;
padding: 6px 20px;
border-bottom: 3px solid #5994FF;
border-radius: 3px;
color: #D2E2FF;
text-align: center;
}

.loginapp input:hover {
background: #6B9FFF;
color: #fff;
}
Binary file added assets/fonts/glyphicons-halflings-regular.eot
Binary file not shown.
288 changes: 288 additions & 0 deletions assets/fonts/glyphicons-halflings-regular.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/fonts/glyphicons-halflings-regular.ttf
Binary file not shown.
Binary file added assets/fonts/glyphicons-halflings-regular.woff
Binary file not shown.
Binary file added assets/fonts/glyphicons-halflings-regular.woff2
Binary file not shown.
6 changes: 6 additions & 0 deletions assets/js/bootstrap.min.js

Large diffs are not rendered by default.

31 changes: 30 additions & 1 deletion assets/js/code-box-copy.min.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,33 @@
* Copyright jablonczay
* https://github.com/jablonczay/code-box-copy
*/
!function(t,o){var i="codeBoxCopy",e={tooltipText:"Copied",tooltipShowTime:1e3,tooltipFadeInTime:300,tooltipFadeOutTime:300};function n(o,n){this.element=o,this.options=t.extend({},e,n),this._defaults=e,this._name=i,this.init()}n.prototype={init:function(){var o,i,e,n,p;(e=this.element.querySelector(".code-box-copy__btn"))&&(p=this.options,new Clipboard(e).on("success",function(e){(o=t(e.trigger)).prop("disabled",!0),n='<span class="code-box-copy__tooltip">',n+=p.tooltipText,t(n+="</span>").prependTo(o),(i=o.find(".code-box-copy__tooltip")).fadeIn(p.tooltipFadeInTime),setTimeout(function(){i.fadeOut(p.tooltipFadeOutTime,function(){i.remove()}),o.prop("disabled",!1)},p.tooltipShowTime)}))}},t.fn[i]=function(o){return this.each(function(){t.data(this,"plugin_"+i)||t.data(this,"plugin_"+i,new n(this,o))})}}(jQuery);
//!function(t,o){var i="codeBoxCopy",e={tooltipText:"Copied",tooltipShowTime:1e3,tooltipFadeInTime:300,tooltipFadeOutTime:300};function n(o,n){this.element=o,this.options=t.extend({},e,n),this._defaults=e,this._name=i,this.init()}n.prototype={init:function(){var o,i,e,n,p;(e=this.element.querySelector(".code-box-copy__btn"))&&(p=this.options,new Clipboard(e).on("success",function(e){(o=t(e.trigger)).prop("disabled",!0),n='<span class="code-box-copy__tooltip">',n+=p.tooltipText,t(n+="</span>").prependTo(o),(i=o.find(".code-box-copy__tooltip")).fadeIn(p.tooltipFadeInTime),setTimeout(function(){i.fadeOut(p.tooltipFadeOutTime,function(){i.remove()}),o.prop("disabled",!1)},p.tooltipShowTime)}))}},t.fn[i]=function(o){return this.each(function(){t.data(this,"plugin_"+i)||t.data(this,"plugin_"+i,new n(this,o))})}}(jQuery);
! function(t, o) {
var i = "codeBoxCopy",
e = {
tooltipText: "Copied",
tooltipShowTime: 1e3,
tooltipFadeInTime: 300,
tooltipFadeOutTime: 300
};

function n(o, n) {
this.element = o, this.options = t.extend({}, e, n), this._defaults = e, this._name = i, this.init()
}
n.prototype = {
init: function() {
var o, i, e, n, p;
(e = this.element.querySelector(".code-box-copy__btn")) && (p = this.options, new Clipboard(e).on("success", function(e) {
(o = t(e.trigger)).prop("disabled", !0), n = '<span class="code-box-copy__tooltip">', n += p.tooltipText, t(n += "</span>").prependTo(o), (i = o.find(".code-box-copy__tooltip")).fadeIn(p.tooltipFadeInTime), setTimeout(function() {
i.fadeOut(p.tooltipFadeOutTime, function() {
i.remove()
}), o.prop("disabled", !1)
}, p.tooltipShowTime)
}))
}
}, t.fn[i] = function(o) {
return this.each(function() {
t.data(this, "plugin_" + i) || t.data(this, "plugin_" + i, new n(this, o))
})
}
}(jQuery);
23 changes: 23 additions & 0 deletions clusters.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright 2018 fydrah
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

// Cluster describes a kubernetes cluster
type Cluster struct {
Name string `yaml:"name"`
Server string `yaml:"server"`
InsecureSkipTLSVerify bool `yaml:"insecure-skip-tls-verify"`
CertificateAuthority string `yaml:"certificate-authority"`
}
6 changes: 3 additions & 3 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@ type AppConfig struct {
MainUsernameClaim string `yaml:"main_username_claim"`
MainClientID string `yaml:"main_client_id"`
AssetsDir string `yaml:"assets_dir"`
SkipMainPage bool `yaml:"skip_main_page"`
} `yaml:"web_output"`
Prometheus struct {
Port int `yaml:"port"`
} `yaml:"prometheus"`
Clusters []Cluster `yaml:"clusters"`
}

// appCheck struct
Expand Down Expand Up @@ -165,10 +165,10 @@ func (a *AppConfig) Init(config string) error {
return fmt.Errorf("error while loading configuration")
}
/*
Default checks: list of check which make loginapp setup a default value
Default checks: list of checks which makes loginapp setup default values
Even if logger report this as an error log, this is not handle as an error.
Hope the following issue will be merged to use loglevel as a parameter:
This issue could help to use loglevel as a parameter once merged:
https://github.com/sirupsen/logrus/issues/646
*/
defaultChecks := []appCheck{
Expand Down
1 change: 0 additions & 1 deletion example/config-loginapp-docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,3 @@ log:
format: json
web_output:
main_client_id: titi
skip_main_page: false
12 changes: 11 additions & 1 deletion example/config-loginapp-full.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,14 @@ web_output:
main_client_id: "loginapp"
main_username_claim: "email"
assets_dir: "./assets/"
skip_main_page: true
skip_main_page: false
clusters:
- name: myfakecluster
server: https://myfakecluster.org
certificate-authority: |
-----BEGIN CERTIFICATE-----
MIIC/zCCAeegAwIBAgIULkYvGJPRl50tMoVE4BNM0laRQncwDQYJKoZIhvcNAQEL
BQAwDzENMAsGA1UEAwwEbXljYTAeFw0xOTAyMTgyMjA5NTJaFw0xOTAyMjgyMjA5
NTJaMA8xDTALBgNVBAMMBG15Y2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
-----END CERTIFICATE-----
insecure-skip-tls-verify: false
2 changes: 0 additions & 2 deletions example/config-loginapp.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,3 @@ tls:
log:
level: Debug
format: json
web_output:
skip_main_page: true
6 changes: 0 additions & 6 deletions handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,6 @@ import (
"strings"
)

// HandleGetIndex serves
// requests to index.html page
func (s *Server) HandleGetIndex(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
renderTemplate(w, indexTmpl, s.config)
}

// HandleGetHealthz serves
// healthchecks requests (mainly
// used by kubernetes healthchecks)
Expand Down
15 changes: 6 additions & 9 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,12 @@ var (
// KubeUserInfo contains all values
// needed by a user for OIDC authentication
type KubeUserInfo struct {
ClientID string
IDToken string
RefreshToken string
RedirectURL string
ExtraAuthCodeOpts interface{}
Claims interface{}
ClientSecret string
UsernameClaim string
Name string
IDToken string
RefreshToken string
RedirectURL string
Claims interface{}
UsernameClaim string
AppConfig AppConfig
}

func main() {
Expand Down
10 changes: 2 additions & 8 deletions routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,11 @@ import (

// Routes setup the server router
func (s *Server) Routes() {
if s.config.WebOutput.SkipMainPage {
s.router.GET("/", s.HandleLogin)
logger.Debug("routes loaded, skipping main page")
} else {
s.router.GET("/", s.HandleGetIndex)
s.router.POST("/login", s.HandleLogin)
logger.Debug("routes loaded, using main page")
}
s.router.GET("/", s.HandleLogin)
s.router.GET("/callback", s.HandleGetCallback)
s.router.GET("/healthz", s.HandleGetHealthz)
s.router.ServeFiles("/assets/*filepath", http.Dir(s.config.WebOutput.AssetsDir))
logger.Debug("routes loaded")
}

// PrometheusRoutes setup the prometheus router
Expand Down
15 changes: 6 additions & 9 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,15 +146,12 @@ func (s *Server) ProcessCallback(w http.ResponseWriter, r *http.Request) (KubeUs
}
logger.Debugf("token issued with claims: %v", jsonClaims)
return KubeUserInfo{
IDToken: rawIDToken,
RefreshToken: token.RefreshToken,
RedirectURL: oauth2Config.RedirectURL,
Claims: jsonClaims,
ClientSecret: s.config.OIDC.Client.Secret,
ClientID: s.config.WebOutput.MainClientID,
UsernameClaim: usernameClaim.(string),
Name: s.config.Name,
ExtraAuthCodeOpts: s.config.OIDC.ExtraAuthCodeOpts,
IDToken: rawIDToken,
RefreshToken: token.RefreshToken,
RedirectURL: oauth2Config.RedirectURL,
Claims: jsonClaims,
UsernameClaim: usernameClaim.(string),
AppConfig: s.config,
}, nil
}

Expand Down
6 changes: 2 additions & 4 deletions templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ package main

import (
"html/template"
"log"
"net/http"
)

Expand All @@ -26,11 +25,11 @@ func renderTemplate(w http.ResponseWriter, tmpl *template.Template, data interfa
if err == nil {
return
}

logger.Debugf("data: %v", data)
switch err := err.(type) {
case *template.Error:
// An ExecError guarantees that Execute has not written to the underlying reader.
log.Printf("error rendering template %s: %s", tmpl.Name(), err)
logger.Errorf("error rendering template %s: %s", tmpl.Name(), err)

// TODO(ericchiang): replace with better internal server error.
http.Error(w, "internal server error", http.StatusInternalServerError)
Expand All @@ -40,5 +39,4 @@ func renderTemplate(w http.ResponseWriter, tmpl *template.Template, data interfa
}
}

var indexTmpl = template.Must(template.ParseFiles("templates/index.html"))
var tokenTmpl = template.Must(template.ParseFiles("templates/token.html"))
21 changes: 0 additions & 21 deletions templates/index.html

This file was deleted.

Loading

0 comments on commit b62510c

Please sign in to comment.