Skip to content

Commit

Permalink
Merge pull request #1 from mrtazz/mrtazz/initial-structure
Browse files Browse the repository at this point in the history
initial version
  • Loading branch information
mrtazz authored Feb 26, 2022
2 parents 7b27702 + de01a2c commit 2eaf81e
Show file tree
Hide file tree
Showing 16 changed files with 689 additions and 1 deletion.
15 changes: 15 additions & 0 deletions .github/workflows/docker-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: docker

on:
pull_request:

jobs:
build:
runs-on: ubuntu-latest
name: build

steps:
- uses: actions/checkout@v2

- name: Build image
run: docker build . --file Dockerfile --tag github.com/mrtazz/certcal
57 changes: 57 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: release
on:
push:
tags:
- '*'

jobs:
release:
name: github
runs-on: ubuntu-latest
env:
BUILDER_NAME: "GitHub Actions"
BUILDER_EMAIL: [email protected]

steps:

- name: Set up Go 1.17
uses: actions/setup-go@v2
with:
go-version: 1.17
id: go

- name: Check out code
uses: actions/checkout@v2
with:
fetch-depth: 1

- name: build for platforms
run: |
BUILD_GOARCH=amd64 BUILD_GOOS=freebsd make build-artifact
BUILD_GOARCH=amd64 BUILD_GOOS=linux make build-artifact
BUILD_GOARCH=amd64 BUILD_GOOS=darwin make build-artifact
- name: create release
run: make github-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

docker:
name: docker
env:
BUILDER_NAME: "GitHub Actions"
BUILDER_EMAIL: [email protected]

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Build the Docker image
run: docker build . --file Dockerfile --tag mrtazz/certcal:${GITHUB_SHA} --tag mrtazz/certcal:latest

- name: push to ghcr
run: |
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
docker push mrtazz/certcal:${GITHUB_SHA}
docker push mrtazz/certcal:latest
docker logout ghcr.io
23 changes: 23 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: CI
on: push
jobs:

test:
name: test
runs-on: ubuntu-latest
steps:

- name: Set up Go 1.17
uses: actions/setup-go@v2
with:
go-version: 1.17
id: go

- name: Check out code
uses: actions/checkout@v2
with:
fetch-depth: 1

- name: Run tests
run: |
make test
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
certcal
.release_artifacts
21 changes: 21 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
FROM golang:1.17-alpine3.15 AS builder

RUN mkdir /app

WORKDIR /app

ADD . /app/

RUN go build -o certcal certcal.go

FROM alpine:3.15
RUN apk --no-cache add ca-certificates

WORKDIR /app
COPY --from=builder /app/certcal /app/certcal
RUN chown -R nobody /app && chmod +x /app/certcal

USER nobody
ENV PORT=3000
ENV CERTCAL_HOSTS="unwiredcouch.com,github.com"
ENTRYPOINT ["/app/certcal"]
19 changes: 19 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Copyright (C) 2022 Daniel Schauenberg

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
75 changes: 75 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#
# some housekeeping tasks
#

# variable definitions
NAME := certcal
DESC := provide an iCal web feed for certificate expiration
PREFIX ?= usr/local
VERSION := $(shell git describe --tags --always --dirty)
GOVERSION := $(shell go version)

BUILD_GOOS ?= $(shell go env GOOS)
BUILD_GOARCH ?= $(shell go env GOARCH)

RELEASE_ARTIFACTS_DIR := .release_artifacts
CHECKSUM_FILE := checksums.txt

$(RELEASE_ARTIFACTS_DIR):
install -d $@

BUILDER := $(shell echo "${BUILDER_NAME} <${EMAIL}>")

PKG_RELEASE ?= 1
PROJECT_URL := "https://github.com/mrtazz/$(NAME)"
LDFLAGS := -X 'main.version=$(VERSION)' \
-X 'main.goversion=$(GOVERSION)'

TARGETS := certcal
INSTALLED_TARGETS = $(addprefix $(PREFIX)/bin/, $(TARGETS))

.PHONY: certcal
certcal: certcal.go
GOOS=$(BUILD_GOOS) GOARCH=$(BUILD_GOARCH) go build -ldflags "$(LDFLAGS)" -o $@ $<
.DEFAULT_GOAL:=certcal

# development tasks
.PHONY: test
test:
go test -v ./...

.PHONY: coverage
coverage:
go test -v -race -coverprofile=cover.out ./...
@-go tool cover -html=cover.out -o cover.html

.PHONY: benchmark
benchmark:
@echo "Running tests..."
@go test -bench=. ${NAME}

# install tasks
$(PREFIX)/bin/%: %
install -d $$(dirname $@)
install -m 755 $< $@

.PHONY: install
install: $(INSTALLED_TARGETS) $(INSTALLED_MAN_TARGETS)

.PHONY: local-install
local-install:
$(MAKE) install PREFIX=usr/local

.PHONY: build-artifact
build-artifact: certcal $(RELEASE_ARTIFACTS_DIR)
mv certcal $(RELEASE_ARTIFACTS_DIR)/certcal-$(VERSION).$(BUILD_GOOS).$(BUILD_GOARCH)
cd $(RELEASE_ARTIFACTS_DIR) && shasum -a 256 certcal-$(VERSION).$(BUILD_GOOS).$(BUILD_GOARCH) >> $(CHECKSUM_FILE)

.PHONY: github-release
github-release:
gh release create $(VERSION) --title 'Release $(VERSION)' --notes-file docs/releases/$(VERSION).md $(RELEASE_ARTIFACTS_DIR)/*

# clean up tasks
.PHONY: clean
clean:
git clean -fdx
80 changes: 79 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,80 @@
# certcal
provide an iCal web feed for certificate expiry

Provide an iCal web feed for certificate expiry.


## Usage

There are a couple of ways to run this

### Standalone
You can download one of the binaries and run it as a standalone:

```shell
% ./certcal serve --help
Usage: certcal serve --hosts=HOSTS,... --interval="24h"

run the server.

Flags:
-h, --help Show context-sensitive help.

--hosts=HOSTS,... hosts to check certs for ($CERTCAL_HOSTS).
--interval="24h" interval in which to check certs ($CERTCAL_INTERVAL)
--port=3000 port for the server to listen on ($PORT)

% PORT=3000 CERTCAL_INTERVAL=5h CERTCAL_HOSTS="unwiredcouch.com" ./certcal
```


### As part of an existing http mux

You can include the handler in your existing mux, something along the lines
of:

```go
import (
"github.com/mrtazz/certcal/handler"
"github.com/mrtazz/certcal/hosts"
"net/http"
"time"
)

func Run() {

...

hosts.AddHosts([]string{"unwiredcouch.com"})
hosts.UpdateEvery(5 * time.Hour)

http.HandleFunc("/hosts", handler.Handler)
http.ListenAndServe(":3000", nil)

}
```


### Via Docker
There is a docker image as well that you can use:

```sh
docker pull ghcr.io/mrtazz/certcal
```


## FAQ

### Shouldn't certs renew automatically?
Probably. But sometimes they aren't.

### Shouldn't this be an alert somewhere?
Maybe, up to you.

### Old expiry events are disappearing!
That is by design. The UID of the `VEVENT` is the `sha256sum` of the summary
of the event. Because generally if the cert got renewed the old event is just
cruft.


## Inspiration
[genuinetools/certok](https://github.com/genuinetools/certok) inspired this
59 changes: 59 additions & 0 deletions certcal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package main

import (
"fmt"
"github.com/alecthomas/kong"
"github.com/mrtazz/certcal/handler"
"github.com/mrtazz/certcal/hosts"
log "github.com/sirupsen/logrus"
"net/http"
"time"
)

var (
version = ""
goversion = ""
)

// CLI defines the command line arguments
var CLI struct {
Serve struct {
Hosts []string `required:"" help:"hosts to check certs for." env:"CERTCAL_HOSTS"`
Interval string `required:"" help:"interval in which to check certs" env:"CERTCAL_INTERVAL" default:"24h"`
Port int `help:"port for the server to listen on" env:"PORT" default:"3000"`
} `cmd:"" help:"run the server."`
}

func main() {

log.SetFormatter(&log.TextFormatter{
FullTimestamp: true,
})
logger := log.WithFields(log.Fields{
"package": "main",
})

ctx := kong.Parse(&CLI)
switch ctx.Command() {
case "serve":
duration, err := time.ParseDuration(CLI.Serve.Interval)
if err != nil {
logger.Error("unable to parse CERTCAL_INTERVAL, defaulting to 1 day")
duration = 24 * time.Hour
}
hosts.AddHosts(CLI.Serve.Hosts)
hosts.UpdateEvery(duration)

address := fmt.Sprintf(":%d", CLI.Serve.Port)

logger.WithFields(log.Fields{
"address": address,
}).Info("starting web server")
http.HandleFunc("/hosts", handler.Handler)
http.ListenAndServe(address, nil)

default:
logger.Error("Unknown command: " + ctx.Command())
}

}
3 changes: 3 additions & 0 deletions docs/releases/0.1.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## v0.1.0 (2022-??-??)
- initial version

17 changes: 17 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module github.com/mrtazz/certcal

go 1.17

require (
github.com/sirupsen/logrus v1.8.1
github.com/stretchr/testify v1.7.0
)

require (
github.com/alecthomas/kong v0.4.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)
Loading

0 comments on commit 2eaf81e

Please sign in to comment.