Skip to content
This repository has been archived by the owner on Aug 8, 2022. It is now read-only.

Commit

Permalink
Merge pull request #2 from chef-base-plans/gavindidrichsen/master/pr/…
Browse files Browse the repository at this point in the history
…add_to_organization

[dex] Add inspec tests and update documentation
  • Loading branch information
Davy McAleer authored Aug 27, 2020
2 parents 5681660 + 353317c commit 4c1315c
Show file tree
Hide file tree
Showing 16 changed files with 393 additions and 13 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
results
results/
inspec.lock
104 changes: 102 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,102 @@
# base-plan-skeleton
Template for all new Chef Base Plans to simplify creation of repositories.
[![Build Status](https://dev.azure.com/chefcorp-partnerengineering/Chef%20Base%20Plans/_apis/build/status/chef-base-plans.dex?branchName=master)](https://dev.azure.com/chefcorp-partnerengineering/Chef%20Base%20Plans/_build/latest?definitionId=206&branchName=master)

# dex

Dex is an identity service that uses OpenID Connect to drive authentication for other apps. Dex acts as a portal to other identity providers through "connectors." See [documentation](https://github.com/dexidp/dex)

## Maintainers

* The Core Planners: <chef-core-planners@chef.io>

## Type of Package

Service package

### Use as Dependency

Service packages can be set as runtime (as well as build time) dependencies. See [Defining your dependencies](https://www.habitat.sh/docs/developing-packages/developing-packages/#sts=Define%20Your%20Dependencies) for more information.

To add core/dex as a runtime dependency, you can add the following to your plan file.

> pkg_deps=(core/dex)
If for some reason, this package is only needed as a build time dependency then do not include it in pkg_deps, but only in pkg_build_deps:

> pkg_build_deps=(core/dex)
### Using dex as a habitat service

Simple usage from a hab studio:

```bash
$ # build and install dex
$ build .
$ source ./results/last_build.env
$ hab pkg install ./results/$pkg_artifact
$
$ # export and run as a docker container
$ hab pkg install core/docker core/hab-pkg-export-docker
$ hab pkg export docker ./results/$pkg_artifact
$ hab pkg exec core/docker docker run --name core_dex -p 9000:9000 --rm -de HAB_LICENSE=accept core/dex
```

For more information see:

* [Running Chef Habitat Packages](https://www.habitat.sh/docs/using-habitat/using-packages/) for more information.
* [Service Groups](https://www.habitat.sh/docs/using-habitat/service-groups/)
* [Topologies](https://www.habitat.sh/docs/using-habitat/topologies/)
* [Update Strategy](https://www.habitat.sh/docs/using-habitat/using-updates/)
* [Binds and Exports](https://www.habitat.sh/docs/developing-packages/#runtime-binds-and-exports)

## Further development of the dex plan

The hab studio provides an excellent way to further develop and or troubleshoot the dex hab service. Since dex provides an http endpoint on port 5556, then enter a hab studio with the following command.

``HAB_DOCKER_OPTS="-p 5556:5556" hab studio enter -D``

Once in the studio, then build and load the service:

```bash
build .
source ./results/last_build.env
hab pkg install ./results/$pkg_artifact
hab svc load $pkg_ident
```

Verify the http endpoint, e.g., open a browser at http://localhost:5556/

For example:

```bash
# build dex
[21][default:/src/dex:0]# build .
building artifact
...
...
'/hab/cache/artifacts/core-dex-2.24.0-20200826103442-x86_64-linux.hart' -> '/src/dex/results/core-dex-2.24.0-20200826103442-x86_64-linux.hart'
dex: hab-plan-build cleanup
dex:
dex: Source Path: /hab/cache/src/dex-2.24.0
dex: Installed Path: /hab/pkgs/core/dex/2.24.0/20200826103442
dex: Artifact: /src/dex/results/core-dex-2.24.0-20200826103442-x86_64-linux.hart
dex: Build Report: /src/dex/results/last_build.env
dex: SHA256 Checksum: 86d51165eadc82d9bd29a59dad5f2289830f99b78eb8b4b5bc0754977170c3fd
dex: Blake2b Checksum: 6cbd551048d0e73aa21d7636b2d697740fa14da449242b6a1c5e7bf291afed0b
dex:
dex: I love it when a plan.sh comes together.
dex:
dex: Build time: 0m33s

# install dex
[22][default:/src/dex:0]# source ./results/last_build.env
[23][default:/src/dex:0]# hab pkg install ./results/$pkg_artifact

# load as a habitat service
[25][default:/src/dex:0]# hab svc load $pkg_ident
The core/dex/2.24.0/20200826103442 service was successfully loaded

# verify that the service is running
[26][default:/src/dex:0]# hab svc status
package type desired state elapsed (s) pid group
core/dex/2.24.0/20200826103442 standalone up down 2 <none> dex.default
```
2 changes: 2 additions & 0 deletions attributes.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
plan_name: 'dex'
listening_port: '5556'
4 changes: 4 additions & 0 deletions botanist.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
owners:
- "@smacfarlane"
- "@habitat-sh/habitat-core-plans-maintainers"
22 changes: 22 additions & 0 deletions config/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
logger:
level: {{cfg.log.level}}
format: {{cfg.log.format}}

issuer: https://{{cfg.service.fqdn}}/dex

storage:
type: sqlite3
config:
file: {{pkg.svc_var_path}}/dex.db

frontend:
dir: {{pkg.svc_static_path}}/web
theme: coreos

web:
http: {{cfg.service.host}}:{{cfg.service.port}}

connectors:
- type: mockCallback
id: mock
name: Example
28 changes: 28 additions & 0 deletions controls/dex_exists.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
title 'Tests to confirm dex exists'

plan_origin = ENV['HAB_ORIGIN']
plan_name = input('plan_name', value: 'dex')

control 'core-plans-dex-exists' do
impact 1.0
title 'Ensure dex exists'
desc '
Verify dex by ensuring bin/dex
(1) exists and
(2) is executable'

plan_installation_directory = command("hab pkg path #{plan_origin}/#{plan_name}")
describe plan_installation_directory do
its('exit_status') { should eq 0 }
its('stdout') { should_not be_empty }
its('stderr') { should be_empty }
end

["dex"].each do |binary_name|
command_full_path = File.join(plan_installation_directory.stdout.strip, "bin", binary_name)
describe file(command_full_path) do
it { should exist }
it { should be_executable }
end
end
end
48 changes: 48 additions & 0 deletions controls/dex_habservice_works.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
title 'Tests to confirm dex habitat service works as expected'

plan_origin = ENV['HAB_ORIGIN']
plan_name = input('plan_name', value: 'dex')

control 'core-plans-dex-habservice-works' do
impact 1.0
title 'Ensure dex habitat service works as expected'
desc '
Verify dex habitat service by ensuring that
(1) the default.dex habitat service is "up";
(2) the dex process is LISTENing on the expected port. Note the
regex that detects the LISTENing <program> works in both a habitat studio environment
and a docker one. In studio the program is displayed as "1234/dex";
whereas in docker as "-".
'

plan_installation_directory = command("hab pkg path #{plan_origin}/#{plan_name}")
describe plan_installation_directory do
its('exit_status') { should eq 0 }
its('stdout') { should_not be_empty }
its('stderr') { should be_empty }
end

plan_pkg_ident = ((plan_installation_directory.stdout.strip).match /(?<=pkgs\/)(.*)/)[1]
describe command("hab svc status") do
its('exit_status') { should eq 0 }
its('stdout') { should_not be_empty }
its('stdout') { should match /(?<package>#{plan_pkg_ident})\s+(?<type>standalone)\s+(?<desired>up)\s+(?<state>up)/ }
its('stderr') { should be_empty }
end

netstat_installation_directory = command("hab pkg path core/busybox-static")
describe netstat_installation_directory do
its('exit_status') { should eq 0 }
its('stdout') { should_not be_empty }
its('stderr') { should be_empty }
end

netstat_fullpath = File.join(netstat_installation_directory.stdout.strip, "bin/netstat" )
listening_port=input('listening_port', value: '5556')
describe command("#{netstat_fullpath} -peanut") do
its('exit_status') { should eq 0 }
its('stdout') { should_not be_empty }
its('stdout') { should match /:(?<port>#{listening_port}).*LISTEN\s+(?<program>-|\d+\/dex)/ }
its('stderr') { should be_empty }
end
end
32 changes: 32 additions & 0 deletions controls/dex_works.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
title 'Tests to confirm dex works as expected'

plan_origin = ENV['HAB_ORIGIN']
plan_name = input('plan_name', value: 'dex')

control 'core-plans-dex-works' do
impact 1.0
title 'Ensure dex works as expected'
desc '
Verify dex by ensuring that
(1) its installation directory exists
(2) it returns the expected version
'

plan_installation_directory = command("hab pkg path #{plan_origin}/#{plan_name}")
describe plan_installation_directory do
its('exit_status') { should eq 0 }
its('stdout') { should_not be_empty }
its('stderr') { should be_empty }
end

plan_pkg_version = plan_installation_directory.stdout.split("/")[5]
["dex"].each do |binary_name|
command_full_path = File.join(plan_installation_directory.stdout.strip, "bin", binary_name)
describe command("#{command_full_path} version") do
its('exit_status') { should eq 0 }
its('stdout') { should_not be_empty }
its('stdout') { should match /dex Version:\s+v#{plan_pkg_version}/ }
its('stderr') { should be_empty }
end
end
end
8 changes: 8 additions & 0 deletions default.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[log]
level = "INFO"
format = "text" # can also be "json"

[service]
fqdn = "localhost"
host = "0.0.0.0"
port = 5556
6 changes: 6 additions & 0 deletions hooks/init
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh

exec 2>&1

# put static files into place
cp -r {{pkg.path}}/web {{pkg.svc_static_path}}
8 changes: 2 additions & 6 deletions hooks/run
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
#!/bin/bash
#!/bin/sh

exec 2>&1

while true; do
echo "Sleeping ..."
sleep 10
done
exec dex serve {{pkg.svc_config_path}}/config.yml
8 changes: 4 additions & 4 deletions inspec.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: {plan}
title: Habitat Core Plan {plan}
name: dex
title: Habitat Core Plan dex
maintainer: "The Core Planners <chef-core-planners@chef.io>"
summary: InSpec controls for testing Habitat Core Plan {plan}
summary: InSpec controls for testing Habitat Core Plan dex
version: 0.1.0
license: Apache-2.0
inspec_version: '>= 4.18.108'
inspec_version: '>= 4.18.108'
50 changes: 50 additions & 0 deletions plan.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
gopkg="github.com/dexidp/dex"
pkg_name=dex
pkg_description="OpenID Connect Identity (OIDC) and OAuth 2.0 Provider with Pluggable Connectors"
pkg_origin=core
pkg_version="2.24.0"
pkg_maintainer="Chef Software Inc. <support@chef.io>"
pkg_license=("Apache-2.0")
pkg_source="https://$gopkg"
pkg_upstream_url=$pkg_source
pkg_exports=(
[port]=service.port
[host]=service.host
)
pkg_deps=(core/glibc)
pkg_build_deps=(core/go core/git core/gcc)
pkg_bin_dirs=(bin)

do_before() {
GOPATH=$HAB_CACHE_SRC_PATH/$pkg_dirname
export GOPATH
}

do_prepare() {
export GO_LDFLAGS="-w -X $gopkg/version.Version=v$pkg_version"
}

do_download() {
return 0
}

do_verify() {
return 0
}

# Use unpack instead of download, so that plan-build can manage the
# source path. This ensures us a clean checkout every time we build.
do_unpack() {
git clone "$pkg_source" "$GOPATH/src/$gopkg"
( cd "$GOPATH/src/$gopkg" || exit
git reset --hard "v$pkg_version"
)
}

do_build() {
go build --ldflags "${GO_LDFLAGS}" -o "$pkg_prefix/bin/dex" "$gopkg/cmd/dex"
}

do_install() {
cp -r "$GOPATH/src/$gopkg/web" "$pkg_prefix"
}
24 changes: 24 additions & 0 deletions tests/helpers.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Usage: test_listen <protocol> <port> [wait-duration]
# protocol: tcp or udp
# port: int
# wait-duration: time in seconds
test_listen() {
local proto="-z"
if [ "${1}" == "udp" ]; then
proto="-u"
fi
local wait=${3:-3}
nc "${proto}" -w"${wait}" 127.0.0.1 "${2}"
return $?
}

wait_listen() {
local proto="-z"
if [ "${1}" == "udp" ]; then
proto="-u"
fi
local wait=${3:-1}
while ! nc "${proto}" -w"${wait}" 127.0.0.1 "${2}"; do
sleep 1
done
}
20 changes: 20 additions & 0 deletions tests/test.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
source "${BATS_TEST_DIRNAME}/../plan.sh"
load helpers

@test "Port Listen TCP/5556" {
test_listen tcp 5556
[ "$?" -eq 0 ]
}

@test "/dex/healthz endpoint returns success" {
curl -f http://127.0.0.1:5556/dex/healthz
}

@test "OpenID Connect discovery document is returned with issuer set" {
jq -ne --argjson doc "$(curl http://127.0.0.1:5556/dex/.well-known/openid-configuration)" \
'$doc.issuer | test("https://localhost/dex")'
}

@test "'dex version' returns the correct version" {
hab pkg exec "${TEST_PKG_IDENT}" dex version | grep -q "dex Version: v${pkg_version}"
}
Loading

0 comments on commit 4c1315c

Please sign in to comment.