Skip to content
This repository has been archived by the owner on Jul 15, 2021. It is now read-only.

Improve UI and add command line instructions #137

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ WORKDIR /go/src/github.com/heptiolabs/gangway

RUN go get -u github.com/mjibson/esc/...
COPY . .
RUN esc -o cmd/gangway/bindata.go templates/
ADD https://raw.githubusercontent.com/PrismJS/prism/v1.16.0/components/prism-bash.js assets/
ADD https://raw.githubusercontent.com/PrismJS/prism/v1.16.0/prism.js assets/
ADD https://raw.githubusercontent.com/PrismJS/prism/v1.16.0/themes/prism.css assets/
ADD https://raw.githubusercontent.com/PrismJS/prism/v1.16.0/components/prism-powershell.js assets/
ADD https://raw.githubusercontent.com/Dogfalo/materialize/v1-dev/dist/css/materialize.min.css assets/
ADD https://raw.githubusercontent.com/Dogfalo/materialize/v1-dev/dist/js/materialize.min.js assets/
RUN esc -o cmd/gangway/bindata.go templates/ assets/

ENV GO111MODULE on
RUN go mod verify
Expand Down
8 changes: 7 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ install:

setup:
go get -u github.com/mjibson/esc/...
curl -o assets/prism-bash.js https://raw.githubusercontent.com/PrismJS/prism/v1.16.0/components/prism-bash.js
curl -o assets/prism.js https://raw.githubusercontent.com/PrismJS/prism/v1.16.0/prism.js
curl -o assets/prism.css https://raw.githubusercontent.com/PrismJS/prism/v1.16.0/themes/prism.css
curl -o assets/prism-powershell.js https://raw.githubusercontent.com/PrismJS/prism/v1.16.0/components/prism-powershell.js
curl -o assets/materialize.min.css https://raw.githubusercontent.com/Dogfalo/materialize/v1-dev/dist/css/materialize.min.css
curl -o assets/materialize.min.js https://raw.githubusercontent.com/Dogfalo/materialize/v1-dev/dist/js/materialize.min.js
jbrunner marked this conversation as resolved.
Show resolved Hide resolved

check: test vet gofmt staticcheck misspell

Expand All @@ -41,7 +47,7 @@ vet: | test
go vet ./...

bindata:
esc -o cmd/gangway/bindata.go templates/
esc -o cmd/gangway/bindata.go templates/ assets/

test:
go test -v ./...
Expand Down
6 changes: 6 additions & 0 deletions assets/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
materialize.min.css
materialize.min.js
prism.css
prism.js
prism-bash.js
prism-powershell.js
34 changes: 34 additions & 0 deletions assets/gangway.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
h1.header {
margin-top:1.6em;
}

pre {
overflow:auto;
margin:0;
padding:.66em 0;
}
textarea.visually-hidden {
position:absolute;
left:-100%;
}

h5 {
margin-top:1.6em
}
.tabs .tab a{
color:#1E88E5 ; /* .blue.darken-1 */
}

.tabs .tab a.active, .tabs .tab a:focus, .tabs .tab a:focus.active {
background-color:rgb(249, 252, 255);
color:#42A5F5; /* .blue.lighten-1*/
}

.tabs .tab a:hover {
color:#42A5F5 ; /* .blue.lighten-1*/
background-color:transparent;
}

.tabs .indicator {
background-color:#64B5F6; /* .blue.lighten-2 */
}
25 changes: 25 additions & 0 deletions assets/gangway.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
(function(){
var clickCopy = function(e) {
e.preventDefault();
console.log(e.target.parentNode.parentNode);
var el = e.target.parentNode.parentNode.querySelector(".active");
var textarea = document.createElement("textarea");
textarea.classList.add("visually-hidden");
textarea.textContent = el.textContent;
document.body.appendChild(textarea);
textarea.select();
document.execCommand("copy");
textarea.remove();
M.toast({html: "Code has been copied to clipboard."});
};

var btnCopy = document.querySelectorAll(".btn-copy");
for (var i = 0; i < btnCopy.length; i++) {
btnCopy[i].addEventListener("click", clickCopy)
}

var tabs = document.querySelectorAll(".tabs");
for (var i = 0; i < tabs.length; i++) {
M.Tabs.init(tabs[i]);
}
})();
3 changes: 3 additions & 0 deletions cmd/gangway/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ func main() {
http.Handle(fmt.Sprintf("%s/commandline", cfg.HTTPPath), loginRequiredHandlers.ThenFunc(commandlineHandler))
http.Handle(fmt.Sprintf("%s/kubeconf", cfg.HTTPPath), loginRequiredHandlers.ThenFunc(kubeConfigHandler))

// Static assets
http.Handle("/assets/", http.FileServer(FS(false)))

bindAddr := fmt.Sprintf("%s:%d", cfg.Host, cfg.Port)
// create http server with timeouts
httpServer := &http.Server{
Expand Down
148 changes: 93 additions & 55 deletions templates/commandline.tmpl
Original file line number Diff line number Diff line change
@@ -1,61 +1,52 @@
<!DOCTYPE html>
<html lang="en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0"/>
<title>Gangway</title>

<!-- CSS -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.min.css">

<!-- Prism -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.14.0/prism.min.js" integrity="sha256-jTGzLAqOAcOL+ALD2f2tvFY7fs6dwkOeo88xiuVHaRk=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.14.0/components/prism-bash.min.js" integrity="sha256-Ch5rv5tgAdVMCh7Wqb0UOcXkQAHNFSezi+0v/0z6xfw=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.14.0/themes/prism-tomorrow.min.css" integrity="sha256-4S9ufRr1EqaUFFeM9/52GH68Hs1Sbvx8eFXBWpl8zPI=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.14.0/plugins/toolbar/prism-toolbar.min.css" integrity="sha256-xY7/SUa769r0PZ1ytZPFj2WqnOZYaYSKbX1hVTiQlcA=" crossorigin="anonymous" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.14.0/plugins/toolbar/prism-toolbar.min.js" integrity="sha256-OvKYJLcYRP3ZIPilT03rynyZfkdGFwzCwU82NB4/AT4=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.14.0/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js" integrity="sha256-s+Z1sBUQFaaw7xeAnWb/oS8gBM4MEKiEWMRJ0p+/xbc=" crossorigin="anonymous"></script>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Gangway</title>
<base href="{{ .HTTPPath }}/">
<link type="text/css" rel="stylesheet" href="assets/materialize.min.css" media="screen"/>
<link type="text/css" rel="stylesheet" href="assets/prism.css" media="screen"/>
<link type="text/css" rel="stylesheet" href="assets/gangway.css" media="screen"/>
</head>
<body>
<nav class="light-blue blue" role="navigation">
<div class="nav-wrapper container"><a id="logo-container" href="#" class="brand-logo">gangway</a>
<ul class="right hide-on-med-and-down">

<body>
<nav class="light-blue blue">
<div class="nav-wrapper container">
<a href="#" class="brand-logo">gangway</a>
<ul id="nav-mobile" class="right hide-on-med-and-down">
<li><a href="/logout">Logout</a></li>
</ul>
</div>
</nav>


<ul id="nav-mobile" class="side-nav">
<li><a href="#">Decode JWT</a></li>
</ul>
<a href="#" data-activates="nav-mobile" class="button-collapse"><i class="material-icons">menu</i></a>
</div>
</nav>
<div class="container">
<h4 class="header center darken-3">
Welcome {{ .Username }}.
</h4>
<h5>
In order to get command-line access to the {{ .ClusterName }} Kubernetes cluster, you will need to configure OpenID Connect (OIDC) authentication for your client.
</h5>
<br>
<p>
The Kubernetes command-line utility, kubectl, may be installed like so:
</p>
<pre>
<code class="language-bash">
$ curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/$(uname | awk '{print tolower($0)}')/amd64/kubectl
$ chmod +x ./kubectl
$ sudo mv ./kubectl /usr/local/bin/kubectl
</code>
</pre>
<div class="row">
<div class="col s12 right-align"><a href="{{ .HTTPPath }}/kubeconf" class="btn-large waves-effect waves-light blue">Download Kubeconfig</a></div>
<div class="col s12">Once kubectl is installed, you may execute the following:</div>
<div class="container">
<h4 class="center">Welcome {{ .Username }}.</h4>
<p class="flow-text">In order to get command-line access to the {{ .ClusterName }} Kubernetes cluster, you will need to configure OpenID Connect (OIDC) authentication for your client.</p>
<p>
<a href="{{ .HTTPPath }}/kubeconf" class="waves-effect waves-light btn-large blue">Download Kubeconfig</a>
</p>
</div>


<div class="container">
<h5>Config cluster context</h5>
<p>Once kubectl is installed (see below), you may execute the following:</p>
<div class="card">
<div class="card-tabs">
<ul class="tabs">
<li class="tab"><a class="active" href="#config-section-bash">Bash</a></li>
<li class="tab"><a href="#config-section-ps">PowerShell</a></li>
</ul>
</div>
<pre>
<code class="language-bash">
echo "{{ .ClusterCA }}" \ > "ca-{{ .ClusterName }}.pem"

<div class="card-content grey lighten-4">
<div class="right-align">
<a class="waves-effect waves-light btn-small btn-copy blue">Copy to clipboard</a>
</div>

<pre id="config-section-bash"><code class="language-bash">echo "{{ .ClusterCA }}" \ > "ca-{{ .ClusterName }}.pem"
kubectl config set-cluster "{{ .ClusterName }}" --server={{ .APIServerURL }} --certificate-authority="ca-{{ .ClusterName }}.pem" --embed-certs
kubectl config set-credentials "{{ .KubeCfgUser }}" \
--auth-provider=oidc \
Expand All @@ -66,9 +57,56 @@ kubectl config set-credentials "{{ .KubeCfgUser }}" \
--auth-provider-arg='id-token={{ .IDToken }}'
kubectl config set-context "{{ .ClusterName }}" --cluster="{{ .ClusterName }}" --user="{{ .KubeCfgUser }}"
kubectl config use-context "{{ .ClusterName }}"
rm "ca-{{ .ClusterName }}.pem"
</code>
</pre>
rm "ca-{{ .ClusterName }}.pem"</code></pre>
<pre id="config-section-ps"><code class="language-powershell">$ClusterCA = "{{ .ClusterCA }}"
Set-Content -Path "ca-{{ .ClusterName }}.pem" -Value $ClusterCA
kubectl config set-cluster "{{ .ClusterName }}" --server={{ .APIServerURL }} --certificate-authority="ca-{{ .ClusterName }}.pem" --embed-certs
kubectl config set-credentials "{{ .KubeCfgUser }}" `
--auth-provider=oidc `
--auth-provider-arg='idp-issuer-url={{ .IssuerURL }}' `
--auth-provider-arg='client-id={{ .ClientID }}' `
--auth-provider-arg='client-secret={{ .ClientSecret }}' `
--auth-provider-arg='refresh-token={{ .RefreshToken }}' `
--auth-provider-arg='id-token={{ .IDToken }}'
kubectl config set-context "{{ .ClusterName }}" --cluster="{{ .ClusterName }}" --user="{{ .KubeCfgUser }}"
kubectl config use-context "{{ .ClusterName }}"
Remove-Item "ca-{{ .ClusterName }}.pem"</code></pre>
</div>
</div>
</body>
</div>


<div class="container">
<h5>Install kubectl</h5>
<p>The Kubernetes command-line utility, kubectl, may be installed like so:</p>
<div class="card">
<div class="card-tabs">
<ul class="tabs">
<li class="tab"><a class="active" href="#install-section-bash">Bash</a></li>
<li class="tab"><a href="#install-section-ps">PowerShell</a></li>
</ul>
</div>

<div class="card-content grey lighten-4">
<div class="right-align">
<a class="waves-effect waves-light btn-small btn-copy blue">Copy to clipboard</a>
</div>

<pre id="install-section-bash"><code class="language-bash">curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/$(uname | awk '{print tolower($0)}')/amd64/kubectl
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl</code></pre>
<pre id="install-section-ps"><code class="language-powershell">Install-Script -Name install-kubectl -Scope CurrentUser -Force
New-Item -Path 'C:\Program Files\Kubectl' -ItemType Directory
install-kubectl.ps1 -DownloadLocation 'C:\Program Files\Kubectl'</code></pre>
</div>
</div>
</div>


<script type="text/javascript" src="assets/materialize.min.js"></script>
<script type="text/javascript" src="assets/prism.js"></script>
<script type="text/javascript" src="assets/prism-bash.js"></script>
<script type="text/javascript" src="assets/prism-powershell.js"></script>
<script type="text/javascript" src="assets/gangway.js"></script>
</body>
</html>
95 changes: 30 additions & 65 deletions templates/home.tmpl
Original file line number Diff line number Diff line change
@@ -1,65 +1,30 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0"/>
<title>Heptio Gangway</title>

<!-- CSS -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.min.css">
<style>
pre.bash {
background-color: black;
color: #49fb35;
font-size: small;
font-family: Consolas,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New, monospace;
overflow: auto;
word-wrap: normal;
white-space: pre;
}

.icon-block {
padding: 0 15px;
}
.icon-block .material-icons {
font-size: inherit;
}
</style>
</head>
<body>
<nav class="light-blue blue" role="navigation">
<div class="nav-wrapper container"><a id="logo-container" href="#" class="brand-logo">gangway</a>
<ul class="right hide-on-med-and-down">

</ul>

<ul id="nav-mobile" class="side-nav">

</ul>
<a href="#" data-activates="nav-mobile" class="button-collapse"><i class="material-icons">menu</i></a>
</div>
</nav>
<div class="section no-pad-bot" id="index-banner">
<div class="container">
<br><br>
<h1 class="header center darken-3">Heptio Gangway Kubernetes Authentication</h1>
<div class="row center">
<h5 class="header col s12 light">This utility will help you authenticate with your Kubernetes cluster with an OpenID Connect (OIDC) flow. Sign in to get started.</h5>
</div>
<div class="row center">
<a href="{{ .HTTPPath }}/login" id="download-button" class="btn-large waves-effect waves-light blue">Sign In</a>
</div>
<br><br>

</div>
</div>


<!-- Scripts-->
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="js/materialize.js"></script>
<script src="js/init.js"></script>

</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Heptio Gangway</title>
<base href="{{ .HTTPPath }}/">
<link type="text/css" rel="stylesheet" href="assets/materialize.min.css" media="screen"/>
<link type="text/css" rel="stylesheet" href="assets/gangway.css" media="screen"/>
</head>

<body>
<nav class="light-blue blue">
<div class="nav-wrapper container">
<a href="#" class="brand-logo">gangway</a>
</div>
</nav>


<div class="container">
<h1 class="center header">Heptio Gangway Kubernetes Authentication</h1>
<p class="flow-text center">This utility will help you authenticate with your Kubernetes cluster with an OpenID Connect (OIDC) flow. Sign in to get started.</p>
<p class="center">
<a href="{{ .HTTPPath }}/login" class="waves-effect waves-light btn-large blue">Sign in</a>
</p>
</div>

<script type="text/javascript" src="assets/materialize.min.js"></script>
</body>
</html>