Skip to content

Commit

Permalink
Version 1.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
LissaGreense committed May 4, 2022
1 parent 395bd87 commit f28aa99
Show file tree
Hide file tree
Showing 71 changed files with 6,534 additions and 0 deletions.
18 changes: 18 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories
vendor/

# Go workspace file
go.work
29 changes: 29 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Build the manager binary
FROM golang:1.16.15 AS builder
WORKDIR /

# COPY . ./

# Copy the Go Modules manifests
COPY go.mod go.mod
COPY go.sum go.sum
COPY vendor/ vendor/

# Copy the go source
COPY main.go main.go
COPY api/ api/
COPY pkg/pkiutil pkiutil/
COPY pkg/controllers controllers/

# Build
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 env GO111MODULE=on go build -mod=vendor -o builds/manager main.go


FROM scratch

WORKDIR /
COPY --from=builder /builds/manager .
USER 65532:65532

ENTRYPOINT ["/manager"]

178 changes: 178 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
# Add proxy
export GOFLAGS=-mod=vendor
export GO111MODULE=on

BUILD_VERSION ?= 1.0.0
IMG_NAME ?= ncm-issuer

# Image URL to use all building/pushing image targets
IMG ?= ncm-issuer:${BUILD_VERSION}
# Produce CRDs that work back to Kubernetes 1.11 (no version conversion)
CRD_OPTIONS ?= "crd:trivialVersions=true,preserveUnknownFields=false"

APP_NAME ?= ncm-issuer
APP_VERSION ?= 1.0.1

# DevOPS Artifactory Repositories
ARTIFACTORY_URL ?= repo.lab.pl.alcatel-lucent.com

CSF_DOCKER_CANDIDATES ?= csf-docker-candidates.${ARTIFACTORY_URL}
CSF_DOCKER_INPROGRESS ?= csf-docker-inprogress.${ARTIFACTORY_URL}

NEO_CANDIDATES_REPO ?= neo-docker-candidates.${ARTIFACTORY_URL}


# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
ifeq (,$(shell go env GOBIN))
GOBIN=$(shell go env GOPATH)/bin
else
GOBIN=$(shell go env GOBIN)
endif

# Setting SHELL to bash allows bash commands to be executed by recipes.
# This is a requirement for 'setup-envtest.sh' in the test target.
# Options are set to exit when a recipe line exits non-zero or a piped command fails.
SHELL = /usr/bin/env bash -o pipefail
.SHELLFLAGS = -ec

all: build

##@ General

# The help target prints out all targets with their descriptions organized
# beneath their categories. The categories are represented by '##@' and the
# target descriptions by '##'. The awk commands is responsible for reading the
# entire set of makefiles included in this invocation, looking for lines of the
# file as xyz: ## something, and then pretty-format the target and help. Then,
# if there's a line with ##@ something, that gets pretty-printed as a category.
# More info on the usage of ANSI control characters for terminal formatting:
# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters
# More info on the awk command:
# http://linuxcommand.org/lc3_adv_awk.php

help: ## Display this help.
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)

##@ Development

manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
$(CONTROLLER_GEN) $(CRD_OPTIONS) rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases

generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."

fmt: ## Run go fmt against code.
go fmt ./...

vet: ## Run go vet against code.
go vet ./...

ENVTEST_ASSETS_DIR=$(shell pwd)/testbin
test: manifests generate fmt vet ## Run tests.
mkdir -p ${ENVTEST_ASSETS_DIR}
${PROXY} test -f ${ENVTEST_ASSETS_DIR}/setup-envtest.sh || curl -sSLo ${ENVTEST_ASSETS_DIR}/setup-envtest.sh https://raw.githubusercontent.com/kubernetes-sigs/controller-runtime/v0.8.3/hack/setup-envtest.sh
${PROXY} source ${ENVTEST_ASSETS_DIR}/setup-envtest.sh; fetch_envtest_tools $(ENVTEST_ASSETS_DIR); setup_envtest_env $(ENVTEST_ASSETS_DIR); go test ./... -coverprofile cover.out


##@ Build

build: generate fmt vet ## Build manager binary.
go build -o bin/manager main.go

run: manifests generate fmt vet ## Run a controller from your host.
go run ./main.go

docker-push: ## Push docker image with the manager.
docker push ${IMG}

# Build the docker image
docker-build: docker_build_img docker-tag

docker_build_img:
docker build . -t ${IMG}

# docker tag
docker-tag:
> inprogressPushList
# tag for both inprogress and candidates so both can be pushed
docker tag ${IMG} ${CSF_DOCKER_INPROGRESS}/${IMG}
docker tag ${IMG} ${CSF_DOCKER_CANDIDATES}/${IMG}
docker tag ${IMG} ${CSF_DOCKER_CANDIDATES}/${IMG_NAME}:latest
# save the image name:tag so Jenkins can retrieve it later
echo ${CSF_DOCKER_INPROGRESS}/${IMG} >>inprogressPushList
echo ${CSF_DOCKER_CANDIDATES}/${IMG} >>inprogressPushList
echo ${CSF_DOCKER_CANDIDATES}/${IMG_NAME}:latest >>inprogressPushList
cat inprogressPushList
docker images |grep ${IMG_NAME}

# save the built docker image
#
#save: docker_build_img
save:
rm -rf builds/$(APP_NAME)-images && mkdir -p builds/$(APP_NAME)-images
docker save ${IMG} | gzip > builds/$(APP_NAME)-images/${IMG}.tgz

##@ Deployment

install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config.
$(KUSTOMIZE) build config/crd | kubectl apply -f -

uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config.
$(KUSTOMIZE) build config/crd | kubectl delete -f -

deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
$(KUSTOMIZE) build config/default | kubectl apply -f -

undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/config.
$(KUSTOMIZE) build config/default | kubectl delete -f -


CONTROLLER_GEN = $(shell pwd)/bin/controller-gen
controller-gen: ## Download controller-gen locally if necessary.
${PROXY} $(call go-get-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@v0.4.1)

KUSTOMIZE = $(shell pwd)/bin/kustomize
kustomize: ## Download kustomize locally if necessary.
${PROXY} $(call go-get-tool,$(KUSTOMIZE),sigs.k8s.io/kustomize/kustomize/v3@v3.8.7)

# go-get-tool will 'go get' any package $2 and install it to $1.
PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST))))
define go-get-tool
[ -f $(1) ] || { \
set -e ;\
TMP_DIR=$$(mktemp -d) ;\
cd $$TMP_DIR ;\
go mod init tmp ;\
echo "Downloading $(2)" ;\
GOBIN=$(PROJECT_DIR)/bin go get $(2) ;\
rm -rf $$TMP_DIR ;\
}
endef

# create helm package
helm-create:
rm -rf builds/helm && mkdir -p builds/helm
cp -r helm builds/helm/$(APP_NAME)
cp helm/README.md builds/helm/$(APP_NAME)
helmValidationAndPackage.sh --helmtarget builds

# create BCMT APP2.0 package
#
# after the step: Build and Publish docker images
#
ncmapp-create: save
rm -rf builds/$(APP_NAME) && mkdir -p builds/$(APP_NAME)
cp -rf app2.0/* builds/$(APP_NAME)
# some update on the new built
sed -i '3s|version: 0.1.0|version: $(BUILD_VERSION)|' builds/$(APP_NAME)/profile/app_list.yaml
mkdir -p builds/$(APP_NAME)/images builds/$(APP_NAME)/charts
cp -rf builds/$(APP_NAME)-images/*.tgz builds/$(APP_NAME)/images/
cp -rf builds/helm/$(APP_NAME)-$(BUILD_VERSION).tgz builds/$(APP_NAME)/charts/
# tar ball
cd builds && tar czvf ../${APP_NAME}-${APP_VERSION}.tgz $(APP_NAME)

clean:
rm -rf builds
rm -rf ncm-issuer*.tgz

24 changes: 24 additions & 0 deletions PROJECT
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
domain: ncm.nokia.com
layout:
- go.kubebuilder.io/v3
projectName: ncm-issuer
repo: cm
resources:
- api:
crdVersion: v1
controller: true
domain: ncm.nokia.com
group: certmanager
kind: ClusterIssuer
path: cm/api/v1
version: v1
- api:
crdVersion: v1
namespaced: true
controller: true
domain: ncm.nokia.com
group: certmanager
kind: Issuer
path: cm/api/v1
version: v1
version: "3"
116 changes: 116 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# NCM Issuer
NCM Issuer allows to integrate cert-manager plugin with [Nokia Netguard Certificate Manager (NCM)](https://www.nokia.com/networks/products/pki-authority-with-netguard-certificate-manager/).

Cert-manager is a native Kubernetes certificate management controller which allows CNFs to get their certificates from a variety of CAs (Certification Authorities). It ensures certificates are valid and up to date, it also attempts to renew certificates at a configured time before expiration.

## Requirements
### To build:

- **[Golang](https://go.dev/doc/install)** 1.16.15
- **[Make](https://www.gnu.org/software/make/)**
- **[Docker](https://docs.docker.com/engine/install/)** >= 20.10.0
> **IMPORTANT:** if you use CentOS/RedHat/Fedora do not use the default one, but install docker-ce
### To use:
- **[NCM 21 release](https://www.nokia.com/networks/products/pki-authority-with-netguard-certificate-manager/)** (or higher)
- **[kubernetes](https://kubernetes.io/)** 1.18-1.21
- **[cert-manager](https://cert-manager.io/docs/installation/)** >= 1.0.0
- **[Helm](https://helm.sh/docs/intro/install/)**

## Build from source
Building process generates an docker image that can be loaded at target machine.

1. Download the source code
2. Vendor dependencies
`$ go mod vendor`
4. Create an image
`$ make docker_build_img`
6. Save the image
`$ make save`

The image of NCM Issuer will be saved in ./builds/ncm-issuer-images/ directory.

## Installation
NCM Issuer uses Helm chart in installation process. You can read more about Helm [here](https://helm.sh/).

1. Load an image with NCM Issuer
```$ docker load -i IMAGE_NAME```
2. Create a namespace for NCM Issuer resources
```$ kubectl create namespace ncm-issuer```
3. Install package using Helm
```$ helm install -n ncm-issuer ncm-issuer /helm/.```

To check if the package has been installed properly type:
```$ helm list -A | grep -i ncm-issuer```

Output of this command should look like this:
```ncm-issuer ncm-issuer 1 2022-04-12 17:36:12.120909878 +0200 CEST deployed ncm-issuer-1.0.0 1.0.1```

Great! Everything is working right now!

## Configuration
NCM Issuer requires to create some k8s secrets with credentials to NCM REST API and TLS client configuration.

### NCM REST API credentials
```$ kubectl create secret generic SECRET_NAME -n NAMESPACE --from-literal=username=USERNAME --from-literal=usrPassword=PASSWORD```

### TLS without client auth
```$ kubectl create -n NAMESPACE secret generic SECRET_NAME --from-file=cacert=CA_FOR_REST_API.pem```

### TLS with client auth
```$ kubectl create -n NAMESPACE secret generic SECRET_NAME --from-file=cacert=CA_FOR_REST_API.pem --from-file=key=CLIENT_AUTH_PKEY.pem --from-file=cert=CLIENT_AUTH_CERT.pem ```


You can check if the secret has been properly created by running this command:
```$ kubectl -n NAMESPACE describe secrets SECRET_NAME```

## Usage
NCM Issuer extends [cert-manager](https://cert-manager.io/) functionalities but way of usage stays the same. There are additional fields in .yaml file (Issuer definition) that are needed to be filled.

### Create an issuer

Issuer .yaml file with all available options:
```
apiVersion: certmanager.ncm.nokia.com/v1
kind: Issuer (or ClusterIssuer)
metadata:
name: ISSUER_NAME
namespace: NAMESPACE_NAME
spec:
secretName: SECRET_NAME_WITH_REST_CREDS
tlsSecretName: SECRET_NAME_WITH_TLS_CERT
CASNAME: CERTIFICATE_NAME_FROM_NCM
CASHREF: HREF_FROM_NCM
ncmSERVER: ADDR_TO_NCM
profileId: PROFILE_ID
reenrollmentOnRenew: false (or true)
useProfileIDForRenew: false (or true)
noRoot: false (or true)
```
For **kind** variable use either Issuer for namespaced one or ClusterIssuer for cluster level issuer.

For **name** variable use some descriptive name of your choice for your issuing CA. This name will be used by your CNFs / applications.

For **namespace** use the one you have created before.

For **secretName** use the secret name with rest credentials.

For **tlsSecretName** use the secret name with TLS certificate.

For **CASNAME** use the CA name from NCM web UI visible under 'CA Hierarchy'. Please do not use CA's CN or DN, but CA name as plainly visible in the UI.

For **ncmSERVER** please use your NCM REST API service URL.

If the **profileId** field is defined, then the profile ID will be set in enrollment requests, so it is included in the issued certificates.

Setting the **useProfileIDForRenew** field to “true” is necessary to include the defined profileID value in the */update* request during the renewal process. Otherwise, certificate update operations won’t include it.

Setting the **reenrollmentOnRenew** field to “true” will force new enrollment of the certificate when renewal process is executed. In this case NCM Issuer uses the NCM */requests* REST API endpoint to get a renewed certificate. By default (when this field is not included or set to “false”) the */update* REST API endpoint is used to renew the certificate (it is the default recommended setting).

The **noRoot** field is responsible for controlling the value of ca.crt secret. By default (when this field is not included or set to “false”) Root CA of the certificate is saved to the ca.crt. If noRoot field is set to “true” then issuer of the certificate is saved there.

To create an issuer from created .yaml file type:
```$ kubectl apply -f issuer.yaml```

### Enroll a certificate
To enroll a certificate just follow instructions from [cert-manager site](https://cert-manager.io/docs/usage/). The enroll process is exactly the same!
Loading

0 comments on commit f28aa99

Please sign in to comment.