Skip to content

Commit cf384e4

Browse files
⚠️ Serve catalog over HTTPS (#263)
* make catalog server serve catalog contents over HTTPS adds cert-manager as a dependency again to create self-signed certs for the catalog server Signed-off-by: everettraven <[email protected]> * fix e2e Signed-off-by: everettraven <[email protected]> * Reorganize manifests for cert-manager overlay This allows the use of alternate certificate managers. Signed-off-by: Tayler Geiger <[email protected]> * Reconfigure TLS functionality to use Listener Fix a few manifest issues as well. Signed-off-by: Tayler Geiger <[email protected]> * Add certwatcher for TLS cert and key from controller-runtime - Add error for missing either tls-key or tls-cert arguments. - Move server creation and configuration to serverutil Signed-off-by: Tayler Geiger <[email protected]> * Update README and docs for HTTPS --------- Signed-off-by: everettraven <[email protected]> Signed-off-by: Tayler Geiger <[email protected]> Co-authored-by: everettraven <[email protected]>
1 parent 250e348 commit cf384e4

35 files changed

+303
-46
lines changed

.goreleaser.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ release:
6666
header: |
6767
## Installation
6868
```bash
69+
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.11.0/cert-manager.yaml
70+
kubectl wait --for=condition=Available --namespace=cert-manager deployment/cert-manager-webhook --timeout=60s
6971
kubectl apply -f https://github.com/operator-framework/catalogd/releases/download/{{ .Tag }}/catalogd.yaml
7072
kubectl wait --for=condition=Available --namespace=catalogd-system deployment/catalogd-controller-manager --timeout=60s
7173
```

Makefile

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ clean: ## Remove binaries and test artifacts
4848
.PHONY: generate
4949
generate: $(CONTROLLER_GEN) ## Generate code and manifests.
5050
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."
51-
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
51+
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/base/crd/bases
5252

5353
.PHONY: fmt
5454
fmt: ## Run go fmt against code.
@@ -152,20 +152,24 @@ kind-load: $(KIND) ## Load the built images onto the local cluster
152152
$(KIND) load docker-image $(IMAGE) --name $(KIND_CLUSTER_NAME)
153153

154154
.PHONY: install
155-
install: build-container kind-load deploy wait ## Install local catalogd
155+
install: build-container kind-load cert-manager deploy wait ## Install local catalogd
156156

157157
.PHONY: deploy
158158
deploy: $(KUSTOMIZE) ## Deploy Catalogd to the K8s cluster specified in ~/.kube/config.
159-
cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMAGE)
160-
$(KUSTOMIZE) build config/default | kubectl apply -f -
159+
cd config/base/manager && $(KUSTOMIZE) edit set image controller=$(IMAGE)
160+
$(KUSTOMIZE) build config/overlays/cert-manager | kubectl apply -f -
161161

162162
.PHONY: undeploy
163163
undeploy: $(KUSTOMIZE) ## Undeploy Catalogd from the K8s cluster specified in ~/.kube/config.
164-
$(KUSTOMIZE) build config/default | kubectl delete --ignore-not-found=true -f -
164+
$(KUSTOMIZE) build config/overlays/cert-manager | kubectl delete --ignore-not-found=true -f -
165165

166166
wait:
167167
kubectl wait --for=condition=Available --namespace=$(CATALOGD_NAMESPACE) deployment/catalogd-controller-manager --timeout=60s
168168

169+
.PHONY: cert-manager
170+
cert-manager:
171+
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/${CERT_MGR_VERSION}/cert-manager.yaml
172+
kubectl wait --for=condition=Available --namespace=cert-manager deployment/cert-manager-webhook --timeout=60s
169173
##@ Release
170174

171175
export ENABLE_RELEASE_PIPELINE ?= false
@@ -175,7 +179,7 @@ release: $(GORELEASER) ## Runs goreleaser for catalogd. By default, this will ru
175179
$(GORELEASER) $(GORELEASER_ARGS)
176180

177181
quickstart: $(KUSTOMIZE) generate ## Generate the installation release manifests and scripts
178-
$(KUSTOMIZE) build config/default | sed "s/:devel/:$(GIT_VERSION)/g" > catalogd.yaml
182+
$(KUSTOMIZE) build config/overlays/cert-manager | sed "s/:devel/:$(GIT_VERSION)/g" > catalogd.yaml
179183

180184
.PHONY: demo-update
181185
demo-update:

README.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ Catalogd helps customers discover installable content by hosting catalog metadat
88
[![asciicast](https://asciinema.org/a/624043.svg)](https://asciinema.org/a/624043)
99

1010
## Quickstart Steps
11-
**NOTE:** Procedure steps marked with an asterisk (`*`) are likely to change with future API updates.
11+
Procedure steps marked with an asterisk (`*`) are likely to change with future API updates.
12+
13+
**NOTE:** The examples below use the `-k` flag in curl to skip validating the TLS certificates. This is for demonstration purposes only.
1214

1315
1. To install catalogd, navigate to the [releases](https://github.com/operator-framework/catalogd/releases/) page, and follow the install instructions included in the release you want to install.
1416

@@ -95,13 +97,13 @@ Catalogd helps customers discover installable content by hosting catalog metadat
9597
9698
1. Port forward the `catalogd-catalogserver` service in the `catalogd-system` namespace:
9799
```sh
98-
$ kubectl -n catalogd-system port-forward svc/catalogd-catalogserver 8080:80
100+
$ kubectl -n catalogd-system port-forward svc/catalogd-catalogserver 8080:443
99101
```
100102
101103
1. Run the following command to get a list of packages:
102104
103105
```sh
104-
$ curl http://localhost:8080/catalogs/operatorhubio/all.json | jq -s '.[] | select(.schema == "olm.package") | .name'
106+
$ curl -k https://localhost:8080/catalogs/operatorhubio/all.json | jq -s '.[] | select(.schema == "olm.package") | .name'
105107
```
106108
107109
*Example output*
@@ -128,7 +130,7 @@ Catalogd helps customers discover installable content by hosting catalog metadat
128130
1. Run the following command to get a list of channels for the `ack-acm-controller` package:
129131
130132
```sh
131-
$ curl http://localhost:8080/catalogs/operatorhubio/all.json | jq -s '.[] | select(.schema == "olm.channel") | select(.package == "ack-acm-controller") | .name'
133+
$ curl -k https://localhost:8080/catalogs/operatorhubio/all.json | jq -s '.[] | select(.schema == "olm.channel") | select(.package == "ack-acm-controller") | .name'
132134
```
133135
134136
*Example output*
@@ -142,7 +144,7 @@ Catalogd helps customers discover installable content by hosting catalog metadat
142144
1. Run the following command to get a list of bundles belonging to the `ack-acm-controller` package:
143145
144146
```sh
145-
$ curl http://localhost:8080/catalogs/operatorhubio/all.json | jq -s '.[] | select(.schema == "olm.bundle") | select(.package == "ack-acm-controller") | .name'
147+
$ curl -k https://localhost:8080/catalogs/operatorhubio/all.json | jq -s '.[] | select(.schema == "olm.bundle") | select(.package == "ack-acm-controller") | .name'
146148
```
147149
148150
*Example output*

Tiltfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ load('../tilt-support/Tiltfile', 'deploy_repo')
55

66
repo = {
77
'image': 'quay.io/operator-framework/catalogd',
8-
'yaml': 'config/default',
8+
'yaml': 'config/overlays/cert-manager',
99
'binaries': {
1010
'manager': 'catalogd-controller-manager',
1111
},

api/core/v1alpha1/catalog_types_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import (
2020
)
2121

2222
func TestPollIntervalCELValidationRules(t *testing.T) {
23-
validators := fieldValidatorsFromFile(t, "../../../config/crd/bases/catalogd.operatorframework.io_catalogs.yaml")
23+
validators := fieldValidatorsFromFile(t, "../../../config/base/crd/bases/catalogd.operatorframework.io_catalogs.yaml")
2424
pth := "openAPIV3Schema.properties.spec"
2525
validator, found := validators["v1alpha1"][pth]
2626
assert.True(t, found)

cmd/manager/main.go

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ package main
1919
import (
2020
"flag"
2121
"fmt"
22-
"net/http"
2322
"net/url"
2423
"os"
2524
"path/filepath"
@@ -39,8 +38,8 @@ import (
3938

4039
"github.com/operator-framework/catalogd/api/core/v1alpha1"
4140
"github.com/operator-framework/catalogd/internal/garbagecollection"
41+
"github.com/operator-framework/catalogd/internal/serverutil"
4242
"github.com/operator-framework/catalogd/internal/source"
43-
"github.com/operator-framework/catalogd/internal/third_party/server"
4443
"github.com/operator-framework/catalogd/internal/version"
4544
corecontrollers "github.com/operator-framework/catalogd/pkg/controllers/core"
4645
"github.com/operator-framework/catalogd/pkg/features"
@@ -71,9 +70,11 @@ func main() {
7170
catalogdVersion bool
7271
systemNamespace string
7372
catalogServerAddr string
74-
httpExternalAddr string
73+
externalAddr string
7574
cacheDir string
7675
gcInterval time.Duration
76+
certFile string
77+
keyFile string
7778
)
7879
flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
7980
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
@@ -83,10 +84,12 @@ func main() {
8384
"Enabling this will ensure there is only one active controller manager.")
8485
flag.StringVar(&systemNamespace, "system-namespace", "", "The namespace catalogd uses for internal state, configuration, and workloads")
8586
flag.StringVar(&catalogServerAddr, "catalogs-server-addr", ":8083", "The address where the unpacked catalogs' content will be accessible")
86-
flag.StringVar(&httpExternalAddr, "http-external-address", "http://catalogd-catalogserver.catalogd-system.svc", "The external address at which the http server is reachable.")
87+
flag.StringVar(&externalAddr, "external-address", "catalogd-catalogserver.catalogd-system.svc", "The external address at which the http(s) server is reachable.")
8788
flag.StringVar(&cacheDir, "cache-dir", "/var/cache/", "The directory in the filesystem that catalogd will use for file based caching")
8889
flag.BoolVar(&catalogdVersion, "version", false, "print the catalogd version and exit")
8990
flag.DurationVar(&gcInterval, "gc-interval", 12*time.Hour, "interval in which garbage collection should be run against the catalog content cache")
91+
flag.StringVar(&certFile, "tls-cert", "", "The certificate file used for serving catalog contents over HTTPS. Requires tls-key.")
92+
flag.StringVar(&keyFile, "tls-key", "", "The key file used for serving catalog contents over HTTPS. Requires tls-cert.")
9093
opts := zap.Options{
9194
Development: true,
9295
}
@@ -103,6 +106,18 @@ func main() {
103106
}
104107

105108
ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))
109+
110+
if (certFile != "" && keyFile == "") || (certFile == "" && keyFile != "") {
111+
setupLog.Error(nil, "unable to configure TLS certificates: tls-cert and tls-key flags must be used together")
112+
os.Exit(1)
113+
}
114+
115+
protocol := "http://"
116+
if certFile != "" && keyFile != "" {
117+
protocol = "https://"
118+
}
119+
externalAddr = protocol + externalAddr
120+
106121
cfg := ctrl.GetConfigOrDie()
107122
mgr, err := ctrl.NewManager(cfg, ctrl.Options{
108123
Scheme: scheme,
@@ -143,29 +158,25 @@ func main() {
143158
os.Exit(1)
144159
}
145160

146-
baseStorageURL, err := url.Parse(fmt.Sprintf("%s/catalogs/", httpExternalAddr))
161+
baseStorageURL, err := url.Parse(fmt.Sprintf("%s/catalogs/", externalAddr))
147162
if err != nil {
148163
setupLog.Error(err, "unable to create base storage URL")
149164
os.Exit(1)
150165
}
151166

152167
localStorage = storage.LocalDir{RootDir: storeDir, BaseURL: baseStorageURL}
153-
shutdownTimeout := 30 * time.Second
154-
catalogServer := server.Server{
155-
Kind: "catalogs",
156-
Server: &http.Server{
157-
Addr: catalogServerAddr,
158-
Handler: catalogdmetrics.AddMetricsToHandler(localStorage.StorageServerHandler()),
159-
ReadTimeout: 5 * time.Second,
160-
// TODO: Revert this to 10 seconds if/when the API
161-
// evolves to have significantly smaller responses
162-
WriteTimeout: 5 * time.Minute,
163-
},
164-
ShutdownTimeout: &shutdownTimeout,
168+
169+
catalogServerConfig := serverutil.CatalogServerConfig{
170+
ExternalAddr: externalAddr,
171+
CatalogAddr: catalogServerAddr,
172+
CertFile: certFile,
173+
KeyFile: keyFile,
174+
LocalStorage: localStorage,
165175
}
166176

167-
if err := mgr.Add(&catalogServer); err != nil {
168-
setupLog.Error(err, "unable to start catalog server")
177+
err = serverutil.AddCatalogServerToManager(mgr, catalogServerConfig)
178+
if err != nil {
179+
setupLog.Error(err, "unable to configure catalog server")
169180
os.Exit(1)
170181
}
171182

@@ -202,7 +213,7 @@ func main() {
202213
Interval: gcInterval,
203214
}
204215
if err := mgr.Add(gc); err != nil {
205-
setupLog.Error(err, "problem adding garbage collector to manager")
216+
setupLog.Error(err, "unable to add garbage collector to manager")
206217
os.Exit(1)
207218
}
208219

File renamed without changes.

config/default/kustomization.yaml renamed to config/base/default/kustomization.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,3 @@ resources:
1515
- ../crd
1616
- ../rbac
1717
- ../manager
18-

config/manager/manager.yaml renamed to config/base/manager/manager.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ spec:
7676
args:
7777
- --leader-elect
7878
- --metrics-bind-address=127.0.0.1:8080
79-
- --http-external-address=http://catalogd-catalogserver.catalogd-system.svc
79+
- --external-address=catalogd-catalogserver.catalogd-system.svc
8080
image: controller:latest
8181
name: manager
8282
volumeMounts:
File renamed without changes.

config/base/rbac/role.yaml

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
---
2+
apiVersion: rbac.authorization.k8s.io/v1
3+
kind: ClusterRole
4+
metadata:
5+
name: manager-role
6+
rules:
7+
- apiGroups:
8+
- catalogd.operatorframework.io
9+
resources:
10+
- catalogs
11+
verbs:
12+
- create
13+
- delete
14+
- get
15+
- list
16+
- patch
17+
- update
18+
- watch
19+
- apiGroups:
20+
- catalogd.operatorframework.io
21+
resources:
22+
- catalogs/finalizers
23+
verbs:
24+
- update
25+
- apiGroups:
26+
- catalogd.operatorframework.io
27+
resources:
28+
- catalogs/status
29+
verbs:
30+
- get
31+
- patch
32+
- update
33+
- apiGroups:
34+
- ""
35+
resources:
36+
- pods
37+
verbs:
38+
- create
39+
- delete
40+
- get
41+
- list
42+
- patch
43+
- update
44+
- watch
45+
- apiGroups:
46+
- ""
47+
resources:
48+
- pods/log
49+
verbs:
50+
- get
51+
- list
52+
- watch
53+
---
54+
apiVersion: rbac.authorization.k8s.io/v1
55+
kind: Role
56+
metadata:
57+
name: manager-role
58+
namespace: system
59+
rules:
60+
- apiGroups:
61+
- ""
62+
resources:
63+
- secrets
64+
verbs:
65+
- get
File renamed without changes.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Adds namespace to all resources.
2+
namespace: catalogd-system
3+
4+
# Value of this field is prepended to the
5+
# names of all resources, e.g. a deployment named
6+
# "wordpress" becomes "alices-wordpress".
7+
# Note that it should also match with the prefix (text before '-') of the namespace
8+
# field above.
9+
namePrefix: catalogd-
10+
11+
# the following config is for teaching kustomize how to do var substitution
12+
apiVersion: kustomize.config.k8s.io/v1beta1
13+
kind: Kustomization
14+
resources:
15+
- ../../base/crd
16+
- ../../base/rbac
17+
- ../../base/manager
18+
- resources
19+
20+
patches:
21+
- target:
22+
kind: Service
23+
name: catalogserver
24+
path: patches/catalogserver_service_port.yaml
25+
- target:
26+
kind: Deployment
27+
name: controller-manager
28+
path: patches/manager_deployment_certs.yaml
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
- op: replace
2+
path: /spec/ports/0/port
3+
value: 443
4+
- op: replace
5+
path: /spec/ports/0/name
6+
value: https
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
- op: add
2+
path: /spec/template/spec/volumes/-
3+
value: {"name":"catalogserver-certs", "secret":{"secretName":"catalogd-catalogserver-cert"}}
4+
- op: add
5+
path: /spec/template/spec/containers/1/volumeMounts/-
6+
value: {"name":"catalogserver-certs", "mountPath":"/var/certs"}
7+
- op: add
8+
path: /spec/template/spec/containers/1/args/-
9+
value: "--tls-cert=/var/certs/tls.crt"
10+
- op: add
11+
path: /spec/template/spec/containers/1/args/-
12+
value: "--tls-key=/var/certs/tls.key"
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
apiVersion: cert-manager.io/v1
3+
kind: Certificate
4+
metadata:
5+
name: catalogserver-cert
6+
namespace: system
7+
spec:
8+
secretName: catalogd-catalogserver-cert
9+
dnsNames:
10+
- localhost
11+
- catalogd-catalogserver.catalogd-system.svc
12+
issuerRef:
13+
kind: Issuer
14+
name: catalogd-catalogserver-ca-issuer

0 commit comments

Comments
 (0)