Skip to content

Commit

Permalink
Satisfy linters
Browse files Browse the repository at this point in the history
  • Loading branch information
monstermunchkin committed Jan 17, 2025
1 parent e718c51 commit 7989f1d
Show file tree
Hide file tree
Showing 221 changed files with 3,474 additions and 1,419 deletions.
4 changes: 2 additions & 2 deletions backend/couchdb/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ func (l *AuthTransport) RoundTrip(req *http.Request) (*http.Response, error) {
return l.transport.RoundTrip(req)
}

func (rt *AuthTransport) Transport() http.RoundTripper {
return rt.transport
func (l *AuthTransport) Transport() http.RoundTripper {
return l.transport
}

func (l *AuthTransport) SetTransport(rt http.RoundTripper) {
Expand Down
12 changes: 8 additions & 4 deletions backend/couchdb/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ func clientAndDB(ctx context.Context, dbName string, cfg *Config) (*kivik.Client
if db.Err() != nil {
return nil, nil, db.Err()
}

return client, db, err
}

Expand All @@ -74,6 +75,7 @@ func Client(cfg *Config) (*kivik.Client, error) {
if err != nil {
return nil, err
}

rts := []transport.ChainableRoundTripper{
&AuthTransport{
Username: cfg.User,
Expand All @@ -84,10 +86,11 @@ func Client(cfg *Config) (*kivik.Client, error) {
if !cfg.DisableRequestLogging {
rts = append(rts, &transport.LoggingRoundTripper{})
}

chain := transport.Chain(rts...)
tr := couchdb.SetTransport(chain)
err = client.Authenticate(ctx, tr)
if err != nil {

if err := client.Authenticate(ctx, tr); err != nil {
return nil, err
}

Expand All @@ -96,9 +99,10 @@ func Client(cfg *Config) (*kivik.Client, error) {

func ParseConfig() (*Config, error) {
var cfg Config
err := env.Parse(&cfg)
if err != nil {

if err := env.Parse(&cfg); err != nil {
return nil, err
}

return &cfg, nil
}
41 changes: 28 additions & 13 deletions backend/couchdb/health_check.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import (
"time"

kivik "github.com/go-kivik/kivik/v3"

"github.com/pace/bricks/maintenance/health/servicehealthcheck"
"github.com/pace/bricks/maintenance/log"
)

// HealthCheck checks the state of the object storage client. It must not be changed
Expand All @@ -28,7 +30,7 @@ var (

// HealthCheck checks if the object storage client is healthy. If the last result is outdated,
// object storage is checked for upload and download,
// otherwise returns the old result
// otherwise returns the old result.
func (h *HealthCheck) HealthCheck(ctx context.Context) servicehealthcheck.HealthCheckResult {
if time.Since(h.state.LastChecked()) <= h.Config.HealthCheckResultTTL {
// the last health check is not outdated, an can be reused.
Expand All @@ -38,14 +40,16 @@ func (h *HealthCheck) HealthCheck(ctx context.Context) servicehealthcheck.Health
checkTime := time.Now()

var doc Doc

var err error

var row *kivik.Row

check:
// check if context was canceled
select {
case <-ctx.Done():
h.state.SetErrorState(fmt.Errorf("failed: %v", ctx.Err()))
h.state.SetErrorState(fmt.Errorf("failed: %w", ctx.Err()))
return h.state.GetState()
default:
}
Expand All @@ -55,16 +59,22 @@ check:
if kivik.StatusCode(row.Err) == http.StatusNotFound {
goto put
}
h.state.SetErrorState(fmt.Errorf("failed to get: %#v", row.Err))

h.state.SetErrorState(fmt.Errorf("failed to get: %w", row.Err))

return h.state.GetState()
}
defer row.Body.Close()

defer func() {
if err := row.Body.Close(); err != nil {
log.Ctx(ctx).Debug().Err(err).Msg("Failed closing body")
}
}()

// check if document exists
if row.Rev != "" {
err = row.ScanDoc(&doc)
if err != nil {
h.state.SetErrorState(fmt.Errorf("failed to get: %v", row.Err))
if err := row.ScanDoc(&doc); err != nil {
h.state.SetErrorState(fmt.Errorf("failed to get: %w", row.Err))
return h.state.GetState()
}

Expand All @@ -77,23 +87,27 @@ check:
put:
// update document
doc.ID = h.Config.HealthCheckKey

doc.Time = time.Now().Format(healthCheckTimeFormat)

_, err = h.DB.Put(ctx, h.Config.HealthCheckKey, doc)
if err != nil {
// not yet created, try to create
if h.Config.DatabaseAutoCreate && kivik.StatusCode(err) == http.StatusNotFound {
err := h.Client.CreateDB(ctx, h.Name)
if err != nil {
h.state.SetErrorState(fmt.Errorf("failed to put object: %v", err))
if err := h.Client.CreateDB(ctx, h.Name); err != nil {
h.state.SetErrorState(fmt.Errorf("failed to put object: %w", err))
return h.state.GetState()
}

goto put
}

if kivik.StatusCode(err) == http.StatusConflict {
goto check
}
h.state.SetErrorState(fmt.Errorf("failed to put object: %v", err))

h.state.SetErrorState(fmt.Errorf("failed to put object: %w", err))

return h.state.GetState()
}

Expand All @@ -103,6 +117,7 @@ put:
healthy:
// If uploading and downloading worked set the Health Check to healthy
h.state.SetHealthy()

return h.state.GetState()
}

Expand All @@ -116,15 +131,15 @@ type Doc struct {
// time span concurrent request to the objstore may break the assumption
// that the value is the same, but in this case it would be acceptable.
// Assumption all instances are created equal and one providing evidence
// of a good write would be sufficient. See #244
// of a good write would be sufficient. See #244.
func wasConcurrentHealthCheck(checkTime time.Time, observedValue string) bool {
t, err := time.Parse(healthCheckTimeFormat, observedValue)
if err == nil {
allowedStart := checkTime.Add(-healthCheckConcurrentSpan)
allowedEnd := checkTime.Add(healthCheckConcurrentSpan)

// timestamp we got from the document is in allowed range
// concider it healthy
// consider it healthy
return t.After(allowedStart) && t.Before(allowedEnd)
}

Expand Down
44 changes: 29 additions & 15 deletions backend/k8sapi/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,76 +15,84 @@ import (
"strings"

"github.com/caarlos0/env/v10"

"github.com/pace/bricks/http/transport"
"github.com/pace/bricks/maintenance/log"
)

// Client minimal client for the kubernetes API
// Client minimal client for the kubernetes API.
type Client struct {
Podname string
Namespace string
CACert []byte
Token string
cfg Config
HttpClient *http.Client
HTTPClient *http.Client
}

// NewClient create new api client
// NewClient create new api client.
func NewClient() (*Client, error) {
cl := Client{
HttpClient: &http.Client{},
HTTPClient: &http.Client{},
}

// lookup hostname (for pod update)
hostname, err := os.Hostname()
if err != nil {
return nil, err
}

cl.Podname = hostname

// parse environment including secrets mounted by kubernetes
err = env.Parse(&cl.cfg)
if err != nil {
if err := env.Parse(&cl.cfg); err != nil {
return nil, err
}

caData, err := os.ReadFile(cl.cfg.CACertFile)
if err != nil {
return nil, fmt.Errorf("failed to read %q: %v", cl.cfg.CACertFile, err)
return nil, fmt.Errorf("failed to read %q: %w", cl.cfg.CACertFile, err)
}

cl.CACert = []byte(strings.TrimSpace(string(caData)))

namespaceData, err := os.ReadFile(cl.cfg.NamespaceFile)
if err != nil {
return nil, fmt.Errorf("failed to read %q: %v", cl.cfg.NamespaceFile, err)
return nil, fmt.Errorf("failed to read %q: %w", cl.cfg.NamespaceFile, err)
}

cl.Namespace = strings.TrimSpace(string(namespaceData))

tokenData, err := os.ReadFile(cl.cfg.TokenFile)
if err != nil {
return nil, fmt.Errorf("failed to read %q: %v", cl.cfg.CACertFile, err)
return nil, fmt.Errorf("failed to read %q: %w", cl.cfg.CACertFile, err)
}

cl.Token = strings.TrimSpace(string(tokenData))

// add kubernetes api server cert
chain := transport.NewDefaultTransportChain()
pool := x509.NewCertPool()

ok := pool.AppendCertsFromPEM(cl.CACert)
if !ok {
return nil, fmt.Errorf("failed to load kubernetes ca cert")
}

chain.Final(&http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: pool,
RootCAs: pool,
MinVersion: tls.VersionTLS12,
},
})
cl.HttpClient.Transport = chain

cl.HTTPClient.Transport = chain

return &cl, nil
}

// SimpleRequest send a simple http request to kubernetes with the passed
// method, url and requestObj, decoding the result into responseObj
// method, url and requestObj, decoding the result into responseObj.
func (c *Client) SimpleRequest(ctx context.Context, method, url string, requestObj, responseObj interface{}) error {
data, err := json.Marshal(requestObj)
if err != nil {
Expand All @@ -99,16 +107,22 @@ func (c *Client) SimpleRequest(ctx context.Context, method, url string, requestO
req.Header.Set("Content-Type", "application/json-patch+json")
req.Header.Set("Authorization", "Bearer "+c.Token)

resp, err := c.HttpClient.Do(req)
resp, err := c.HTTPClient.Do(req)
if err != nil {
log.Ctx(ctx).Debug().Err(err).Msg("failed to do api request")
return err
}
defer resp.Body.Close()

defer func() {
if err := resp.Body.Close(); err != nil {
log.Ctx(ctx).Debug().Err(err).Msg("failed to close response body")
}
}()

if resp.StatusCode > 299 {
body, _ := io.ReadAll(resp.Body) // nolint: errcheck
body, _ := io.ReadAll(resp.Body)
log.Ctx(ctx).Debug().Msgf("failed to do api request, due to: %s", string(body))

return fmt.Errorf("k8s request failed with %s", resp.Status)
}

Expand Down
2 changes: 1 addition & 1 deletion backend/k8sapi/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
package k8sapi

// Config gathers the required kubernetes system configuration to use the
// kubernetes API
// kubernetes API.
type Config struct {
Host string `env:"KUBERNETES_SERVICE_HOST" envDefault:"localhost"`
Port int `env:"KUBERNETES_PORT_443_TCP_PORT" envDefault:"433"`
Expand Down
5 changes: 3 additions & 2 deletions backend/k8sapi/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import (
)

// SetCurrentPodLabel set the label for the current pod in the current
// namespace (requires patch on pods resource)
// namespace (requires patch on pods resource).
func (c *Client) SetCurrentPodLabel(ctx context.Context, label, value string) error {
return c.SetPodLabel(ctx, c.Namespace, c.Podname, label, value)
}

// SetPodLabel sets the label and value for the pod of the given namespace
// (requires patch on pods resource in the given namespace)
// (requires patch on pods resource in the given namespace).
func (c *Client) SetPodLabel(ctx context.Context, namespace, podname, label, value string) error {
pr := []struct {
Op string `json:"op"`
Expand All @@ -30,6 +30,7 @@ func (c *Client) SetPodLabel(ctx context.Context, namespace, podname, label, val
}
url := fmt.Sprintf("https://%s:%d/api/v1/namespaces/%s/pods/%s",
c.cfg.Host, c.cfg.Port, namespace, podname)

var resp interface{}

return c.SimpleRequest(ctx, http.MethodPatch, url, &pr, &resp)
Expand Down
Loading

0 comments on commit 7989f1d

Please sign in to comment.