Skip to content
This repository has been archived by the owner on Apr 17, 2024. It is now read-only.

Commit

Permalink
feat: add list of certs to add to the http.client used
Browse files Browse the repository at this point in the history
Signed-off-by: Alexander Trost <galexrt@googlemail.com>
  • Loading branch information
galexrt committed Jan 26, 2024
1 parent 7c9466d commit 7fee9ca
Show file tree
Hide file tree
Showing 16 changed files with 125 additions and 36 deletions.
10 changes: 10 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
- [ ] Rework caching logic to be non-blocking. -> Either a "cluster is detected and stats is available" or there is no stats of the cluster.
- [ ] Clearly communicate to the user if the data is "live" or not. Adding auto refresh.
- [ ] Look into "basic IF condition"-AI for the data-control-center -> Recommendation system
- [ ] "Reliability"-score on steroids -> Always give a why.
- [ ] Ideas: "It is recommended to ..."
- [ ] Set a custom OSD scrubbing schedule.
- [ ] Set K8S resources requests/limits for the Ceph components.
- [ ] At least replicated.size 3 or higher for production.
- [ ] Other important config aspects to check for?
- [ ] Fix SSL CA custom cert issue
2 changes: 1 addition & 1 deletion charts/data-control-center/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.3.3
version: 0.3.4

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
Expand Down
2 changes: 1 addition & 1 deletion charts/data-control-center/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ The following table lists the configurable parameters of the rook-operator chart
| `additionalVolumeMounts` | Extra volume mounts to add to the data-control-center deployment | `[]` |
| `additionalVolumes` | Extra volumes to add to the data-control-center deployment | `[]` |
| `affinity` | Pod Affinity options https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#affinity-v1-core | `{}` |
| `config` | data-control-center config, documentation here: https://github.com/koor-tech/data-control-center/blob/main/docs/configuration.md#reference | `{"ancienttCmd":"ancientt","ceph":{"api":{"insecureSSL":true,"password":null,"url":"https://rook-ceph-mgr-dashboard:8443/api","username":"data-control-center"}},"http":{"listen":":8282","sessions":{"cookieSecret":"your_generated_cookie_secret","domain":"localhost"}},"jwt":{"secret":"your_generated_jwt_secret"},"logLevel":"INFO","mode":"release","namespace":"","oauth2":{"providers":[]},"readOnly":false,"updateCheck":{"enabled":true,"interval":"24h"},"users":[]}` |
| `config` | data-control-center config, documentation here: https://github.com/koor-tech/data-control-center/blob/main/docs/configuration.md#reference | `{"ancienttCmd":"ancientt","ceph":{"api":{"insecureSkipVerify":true,"password":null,"url":"https://rook-ceph-mgr-dashboard:8443/api","username":"data-control-center"}},"certs":{"caCerts":[],"insecureSkipVerify":false},"http":{"listen":":8282","sessions":{"cookieSecret":"your_generated_cookie_secret","domain":"localhost"}},"jwt":{"secret":"your_generated_jwt_secret"},"logLevel":"INFO","mode":"release","namespace":"","oauth2":{"providers":[]},"readOnly":false,"updateCheck":{"enabled":true,"interval":"24h"},"users":[]}` |
| `config.ceph.api.password` | Password is auto generated if not set and retrieved using helm's lookup function | `nil` |
| `config.namespace` | The rook ceph namespace, if different from the release namespace. Defaults to the release namespace. | `""` |
| `fullnameOverride` | Overrides the chart's computed fullname | `""` |
Expand Down
5 changes: 4 additions & 1 deletion charts/data-control-center/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ config:
username: 'data-control-center'
# -- Password is auto generated if not set and retrieved using helm's lookup function
password: null
insecureSSL: true
insecureSkipVerify: true
oauth2:
providers: []
#- name: 'keycloak'
Expand All @@ -167,6 +167,9 @@ config:
enabled: true
interval: 24h
ancienttCmd: "ancientt"
certs:
caCerts: []
insecureSkipVerify: false

# -- Extra volumes to add to the data-control-center deployment
additionalVolumes: []
Expand Down
5 changes: 4 additions & 1 deletion config.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ ceph:
url: 'http://localhost:8383/api'
username: 'admin'
password: 'admin'
insecureSSL: false
insecureSkipVerify: false
oauth2:
providers:
- name: 'keycloak'
Expand All @@ -45,3 +45,6 @@ updateCheck:
enabled: true
interval: 24h
ancienttCmd: 'ancientt'
certs:
caCerts: []
insecureSkipVerify: false
2 changes: 1 addition & 1 deletion docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Changes to the config file are not auto detected, they require a (manual) restar
* `url`: Ceph dashboard API URL, if run inside the data-control-center in same cluster your Rook/Koor Ceph cluster is running use `https://rook-ceph-mgr-dashboard:8443/api` (assumes that SSL is enabled on the dashboard, if not change `https` to `http`). The Ceph dashboard is part of the Ceph MGR component exposed on the configured port.
* `username`: Username of Ceph dashboard user to use.
* `password`: Password of Ceph dashboard user to use.
* `insecureSSL`: If the certificate of the Ceph dashboard API should be verified or not.
* `insecureSkipVerify`: If the certificate of the Ceph dashboard API should be verified or not.

### `oauth2` Section

Expand Down
11 changes: 7 additions & 4 deletions docs/custom-ca.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,12 @@ This guide assumes that you already have your custom CA certificate available in
mountPath: /certs
readOnly: true
```
2. Add the env variable `SSL_CERT_FILE` with the path to the certificate to your `values.yaml` like this.
1. Find or add the following to your `values.yaml`:
2. Add the CA cert to the list of (custom) certificates for the data-control-center to load in your `values.yaml` like this.
1. Find the `config:` section and in the `certs:` sub section add the certs path in the container/Pod like this:
```yaml
additionalEnv:
SSL_CERT_FILE: "/certs/ca.pem"
config:
# [...]
certs:
caCerts:
- /certs/ca.pem
```
2 changes: 1 addition & 1 deletion pkg/ceph/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type Client struct {

func NewClient(apiConfig config.API) *Client {
customTransport := http.DefaultTransport.(*http.Transport).Clone()
if apiConfig.InsecureSSL {
if apiConfig.InsecureSkipVerify {
customTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
}

Expand Down
15 changes: 11 additions & 4 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ type Config struct {
UpdateCheck UpdateCheck `yaml:"updateCheck"`

AncienttCmd string `default:"ancientt" yaml:"ancienttCmd"`

Certs Certs `yaml:"certs"`
}

type HTTP struct {
Expand Down Expand Up @@ -130,13 +132,18 @@ type Ceph struct {
}

type API struct {
Url string `yaml:"url"`
Username string `yaml:"username"`
Password string `yaml:"password"`
InsecureSSL bool `yaml:"insecureSSL"`
Url string `yaml:"url"`
Username string `yaml:"username"`
Password string `yaml:"password"`
InsecureSkipVerify bool `yaml:"insecureSkipVerify"`
}

type UpdateCheck struct {
Enabled bool `default:"true" yaml:"enabled"`
Interval time.Duration `default:"24h" yaml:"interval"`
}

type Certs struct {
InsecureSkipVerify bool `yaml:"insecureSkipVerify"`
CACerts []string `yaml:"caCerts"`
}
50 changes: 50 additions & 0 deletions pkg/httpclient/httpclient.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package httpclient

import (
"crypto/tls"
"crypto/x509"
"fmt"
"log"
"net/http"
"os"

"github.com/koor-tech/data-control-center/pkg/config"
"go.uber.org/fx"
"go.uber.org/zap"
)

var Module = fx.Module("http_client",
fx.Provide(New),
)

func New(logger *zap.Logger, cfg *config.Config) (*http.Client, error) {
// Get the SystemCertPool, continue with an empty pool on error
rootCAs, _ := x509.SystemCertPool()
if rootCAs == nil {
rootCAs = x509.NewCertPool()
}

for _, certFile := range cfg.Certs.CACerts {
// Read cert file
certs, err := os.ReadFile(certFile)
if err != nil {
return nil, fmt.Errorf("failed to append %q to RootCAs: %w", certFile, err)
}

// Append cert to the system pool
if ok := rootCAs.AppendCertsFromPEM(certs); !ok {
log.Println("No certs appended, using system certs only")
}
}

// Trust the augmented cert pool in our client
config := &tls.Config{
InsecureSkipVerify: cfg.Certs.InsecureSkipVerify,
RootCAs: rootCAs,
}

tr := &http.Transport{TLSClientConfig: config}
client := &http.Client{Transport: tr}

return client, nil
}
11 changes: 7 additions & 4 deletions pkg/server/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
cephcache "github.com/koor-tech/data-control-center/pkg/ceph/cache"
"github.com/koor-tech/data-control-center/pkg/config"
"github.com/koor-tech/data-control-center/pkg/grpc/auth"
"github.com/koor-tech/data-control-center/pkg/httpclient"
"github.com/koor-tech/data-control-center/pkg/k8s"
k8scache "github.com/koor-tech/data-control-center/pkg/k8s/cache"
"github.com/koor-tech/data-control-center/pkg/server/httpapi"
Expand Down Expand Up @@ -53,9 +54,10 @@ type ServerParams struct {

LC fx.Lifecycle

Logger *zap.Logger
Config *config.Config
TokenMgr *auth.TokenMgr
Logger *zap.Logger
Config *config.Config
TokenMgr *auth.TokenMgr
HttpClient *http.Client

Routes *httpapi.Routes
OAuth2Providers map[string]providers.IProvider
Expand Down Expand Up @@ -132,7 +134,7 @@ func setupHTTPServer(p ServerParams) *gin.Engine {
p.Routes.Register(e)

if len(p.OAuth2Providers) > 0 {
oauth := oauth2.New(p.Logger.Named("oauth"), p.TokenMgr, p.OAuth2Providers)
oauth := oauth2.New(p.Logger.Named("oauth"), p.TokenMgr, p.HttpClient, p.OAuth2Providers)
oauth.Register(e)
}

Expand Down Expand Up @@ -198,6 +200,7 @@ func StartHTTPServer() {
update.Module,
ancientt.Module,
oauth2.ConfigModule,
httpclient.Module,

// Connect Services - Need to be added here
fx.Provide(
Expand Down
13 changes: 9 additions & 4 deletions pkg/server/oauth2/oauth2.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package oauth2

import (
"context"
"fmt"
"net/http"
"net/url"
Expand All @@ -12,19 +13,22 @@ import (
"github.com/koor-tech/data-control-center/pkg/server/oauth2/providers"
"github.com/koor-tech/data-control-center/pkg/utils"
"go.uber.org/zap"
"golang.org/x/oauth2"
)

type OAuth2 struct {
logger *zap.Logger
tm *auth.TokenMgr
logger *zap.Logger
tm *auth.TokenMgr
httpClient *http.Client

oauthConfigs map[string]providers.IProvider
}

func New(logger *zap.Logger, tm *auth.TokenMgr, oAuth2Providers map[string]providers.IProvider) *OAuth2 {
func New(logger *zap.Logger, tm *auth.TokenMgr, httpClient *http.Client, oAuth2Providers map[string]providers.IProvider) *OAuth2 {
o := &OAuth2{
logger: logger,
tm: tm,
httpClient: httpClient,
oauthConfigs: oAuth2Providers,
}

Expand Down Expand Up @@ -167,7 +171,8 @@ func (o *OAuth2) Callback(c *gin.Context) {
}

code := c.Request.FormValue("code")
userInfo, err := provider.GetUserInfo(code)
ctx := context.WithValue(c, oauth2.HTTPClient, o.httpClient)
userInfo, err := provider.GetUserInfo(ctx, code)
if err != nil {
o.logger.Error("failed to get userinfo from provider", zap.Error(err))
o.handleRedirect(c, err, connectOnly, false, "provider_failed")
Expand Down
6 changes: 3 additions & 3 deletions pkg/server/oauth2/providers/generic.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ type Generic struct {
BaseProvider
}

func (p *Generic) GetUserInfo(code string) (*UserInfo, error) {
token, err := p.oauthConfig.Exchange(context.Background(), code)
func (p *Generic) GetUserInfo(ctx context.Context, code string) (*UserInfo, error) {
token, err := p.oauthConfig.Exchange(ctx, code)
if err != nil {
return nil, fmt.Errorf("code exchange failed: %s", err.Error())
}

res, err := p.oauthConfig.Client(context.Background(), token).Get(p.UserInfoURL)
res, err := p.oauthConfig.Client(ctx, token).Get(p.UserInfoURL)
if err != nil {
return nil, fmt.Errorf("failed to get user info: %+q", err)
}
Expand Down
4 changes: 3 additions & 1 deletion pkg/server/oauth2/providers/providers.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package providers

import (
"context"

jsoniter "github.com/json-iterator/go"
"github.com/koor-tech/data-control-center/pkg/config"
"golang.org/x/oauth2"
Expand All @@ -16,7 +18,7 @@ type IProvider interface {
GetName() string

GetRedirect(state string) string
GetUserInfo(string) (*UserInfo, error)
GetUserInfo(ctx context.Context, code string) (*UserInfo, error)
GetLogoutURL(token string) string
}

Expand Down
18 changes: 11 additions & 7 deletions pkg/update/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package update

import (
"context"
"net/http"
"strings"
"time"

Expand All @@ -19,8 +20,9 @@ var Module = fx.Module("update_checker",
)

type Checker struct {
ctx context.Context
logger *zap.Logger
ctx context.Context
logger *zap.Logger
httpClient *http.Client

routes *httpapi.Routes

Expand All @@ -32,8 +34,9 @@ type Params struct {

LC fx.Lifecycle

Logger *zap.Logger
Cfg *config.Config
Logger *zap.Logger
Cfg *config.Config
HttpClient *http.Client

Routes *httpapi.Routes
}
Expand All @@ -42,8 +45,9 @@ func New(p Params) *Checker {
ctx, cancel := context.WithCancel(context.Background())

c := &Checker{
ctx: ctx,
logger: p.Logger.Named("update_checker"),
ctx: ctx,
logger: p.Logger.Named("update_checker"),
httpClient: p.HttpClient,

routes: p.Routes,

Expand Down Expand Up @@ -85,7 +89,7 @@ func (c *Checker) check(ctx context.Context) error {
ctx, cancel := context.WithTimeout(ctx, 15*time.Second)
defer cancel()

latest, err := GetLatestRelease(ctx)
latest, err := c.GetLatestRelease(ctx)
if err != nil {
return err
}
Expand Down
5 changes: 2 additions & 3 deletions pkg/update/releasecheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type release struct {
Draft bool `json:"draft"`
}

func GetLatestRelease(ctx context.Context) (string, error) {
func (c *Checker) GetLatestRelease(ctx context.Context) (string, error) {
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.github.com/repos/koor-tech/data-control-center/releases", nil)
if err != nil {
return "", err
Expand All @@ -28,8 +28,7 @@ func GetLatestRelease(ctx context.Context) (string, error) {
req.Header.Set("Accept", "application/vnd.github+json")
req.Header.Set("X-GitHub-Api-Version", "2022-11-28")

client := http.DefaultClient
res, err := client.Do(req)
res, err := c.httpClient.Do(req)
if err != nil {
log.Fatalf("%v", err)
}
Expand Down

0 comments on commit 7fee9ca

Please sign in to comment.