zero/healthchecks: add checks for ability to save bootstrap parameter and bundle status reporting (#5064)

This commit is contained in:
Denis Mishin 2024-04-11 10:47:52 -04:00 committed by GitHub
parent 25aceea626
commit dc7820ea3e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 33 additions and 69 deletions

View file

@ -127,43 +127,3 @@ func (api *API) GetClusterResourceBundles(ctx context.Context) (*cluster_api.Get
api.cluster.GetClusterResourceBundlesWithResponse(ctx), api.cluster.GetClusterResourceBundlesWithResponse(ctx),
) )
} }
// ReportBundleAppliedSuccess reports a successful bundle application
func (api *API) ReportBundleAppliedSuccess(ctx context.Context, bundleID string, metadata map[string]string) error {
status := cluster_api.BundleStatus{
Success: &cluster_api.BundleStatusSuccess{
Metadata: metadata,
},
}
_, err := apierror.CheckResponse[cluster_api.EmptyResponse](
api.cluster.ReportClusterResourceBundleStatusWithResponse(ctx, bundleID, status),
)
if err != nil {
return fmt.Errorf("error reporting bundle status: %w", err)
}
return err
}
// ReportBundleAppliedFailure reports a failed bundle application
func (api *API) ReportBundleAppliedFailure(
ctx context.Context,
bundleID string,
source cluster_api.BundleStatusFailureSource,
err error,
) error {
status := cluster_api.BundleStatus{
Failure: &cluster_api.BundleStatusFailure{
Message: err.Error(),
Source: source,
},
}
_, err = apierror.CheckResponse[cluster_api.EmptyResponse](
api.cluster.ReportClusterResourceBundleStatusWithResponse(ctx, bundleID, status),
)
if err != nil {
return fmt.Errorf("error reporting bundle status: %w", err)
}
return err
}

View file

@ -15,6 +15,7 @@ import (
"os" "os"
"github.com/pomerium/pomerium/pkg/cryptutil" "github.com/pomerium/pomerium/pkg/cryptutil"
"github.com/pomerium/pomerium/pkg/health"
cluster_api "github.com/pomerium/pomerium/pkg/zero/cluster" cluster_api "github.com/pomerium/pomerium/pkg/zero/cluster"
) )
@ -40,6 +41,16 @@ func LoadBootstrapConfigFromFile(fp string, cipher cipher.AEAD) (*cluster_api.Bo
// SaveBootstrapConfigToFile saves the bootstrap configuration to a file. // SaveBootstrapConfigToFile saves the bootstrap configuration to a file.
func SaveBootstrapConfigToFile(src *cluster_api.BootstrapConfig, fp string, cipher cipher.AEAD) error { func SaveBootstrapConfigToFile(src *cluster_api.BootstrapConfig, fp string, cipher cipher.AEAD) error {
err := saveBootstrapConfigToFile(src, fp, cipher)
if err != nil {
health.ReportError(health.ZeroBootstrapConfigSave, err)
} else {
health.ReportOK(health.ZeroBootstrapConfigSave)
}
return err
}
func saveBootstrapConfigToFile(src *cluster_api.BootstrapConfig, fp string, cipher cipher.AEAD) error {
plaintext, err := json.Marshal(src) plaintext, err := json.Marshal(src)
if err != nil { if err != nil {
return fmt.Errorf("marshal file config: %w", err) return fmt.Errorf("marshal file config: %w", err)

View file

@ -1,44 +1,28 @@
package reconciler package reconciler
import ( import (
"context" "fmt"
"github.com/pomerium/pomerium/internal/log" "github.com/pomerium/pomerium/pkg/health"
cluster_api "github.com/pomerium/pomerium/pkg/zero/cluster"
) )
const ( // sourceAttr is to indicate the source of this health check is not host specific
// BundleStatusFailureDatabrokerError indicates a failure due to a databroker error var sourceAttr = health.StrAttr("source", "pomerium-managed-core")
BundleStatusFailureDatabrokerError = cluster_api.DatabrokerError
// BundleStatusFailureDownloadError indicates a failure due to a download error
BundleStatusFailureDownloadError = cluster_api.DownloadError
// BundleStatusFailureInvalidBundle indicates a failure due to an invalid bundle
BundleStatusFailureInvalidBundle = cluster_api.InvalidBundle
// BundleStatusFailureIO indicates a failure due to an IO error
BundleStatusFailureIO = cluster_api.IoError
// BundleStatusFailureUnknownError indicates a failure due to an unknown error
BundleStatusFailureUnknownError = cluster_api.UnknownError
)
func (c *service) ReportBundleAppliedSuccess( func (c *service) ReportBundleAppliedSuccess(
ctx context.Context,
bundleID string, bundleID string,
metadata map[string]string, metadata map[string]string,
) { ) {
err := c.config.api.ReportBundleAppliedSuccess(ctx, bundleID, metadata) attr := []health.Attr{sourceAttr}
if err != nil { for k, v := range metadata {
log.Ctx(ctx).Err(err).Msg("reconciler: error reporting bundle status") attr = append(attr, health.StrAttr(fmt.Sprintf("download-metadata-%s", k), v))
} }
health.ReportOK(health.ZeroResourceBundle(bundleID), attr...)
} }
func (c *service) ReportBundleAppliedFailure( func (c *service) ReportBundleAppliedFailure(
ctx context.Context,
bundleID string, bundleID string,
source cluster_api.BundleStatusFailureSource,
err error, err error,
) { ) {
err = c.config.api.ReportBundleAppliedFailure(ctx, bundleID, source, err) health.ReportError(health.ZeroResourceBundle(bundleID), err, sourceAttr)
if err != nil {
log.Ctx(ctx).Err(err).Msg("reconciler: error reporting bundle status")
}
} }

View file

@ -136,7 +136,7 @@ func (c *service) syncBundle(ctx context.Context, key string) error {
result, err := c.config.api.DownloadClusterResourceBundle(ctx, fd, key, conditional) result, err := c.config.api.DownloadClusterResourceBundle(ctx, fd, key, conditional)
if err != nil { if err != nil {
c.ReportBundleAppliedFailure(ctx, key, BundleStatusFailureDownloadError, err) c.ReportBundleAppliedFailure(key, fmt.Errorf("download bundle: %w", err))
return fmt.Errorf("download bundle: %w", err) return fmt.Errorf("download bundle: %w", err)
} }
@ -157,7 +157,7 @@ func (c *service) syncBundle(ctx context.Context, key string) error {
bundleRecordTypes, err := c.syncBundleToDatabroker(ctx, key, fd, cached.GetRecordTypes()) bundleRecordTypes, err := c.syncBundleToDatabroker(ctx, key, fd, cached.GetRecordTypes())
if err != nil { if err != nil {
c.ReportBundleAppliedFailure(ctx, key, BundleStatusFailureDatabrokerError, err) c.ReportBundleAppliedFailure(key, fmt.Errorf("sync bundle to databroker: %w", err))
return fmt.Errorf("apply bundle to databroker: %w", err) return fmt.Errorf("apply bundle to databroker: %w", err)
} }
current := BundleCacheEntry{ current := BundleCacheEntry{
@ -176,11 +176,11 @@ func (c *service) syncBundle(ctx context.Context, key string) error {
err = c.SetBundleCacheEntry(ctx, key, current) err = c.SetBundleCacheEntry(ctx, key, current)
if err != nil { if err != nil {
err = fmt.Errorf("set bundle cache entry: %w", err) err = fmt.Errorf("set bundle cache entry: %w", err)
c.ReportBundleAppliedFailure(ctx, key, BundleStatusFailureDatabrokerError, err) c.ReportBundleAppliedFailure(key, fmt.Errorf("set bundle cache entry: %w", err))
return err return err
} }
c.ReportBundleAppliedSuccess(ctx, key, result.Metadata) c.ReportBundleAppliedSuccess(key, result.Metadata)
return nil return nil
} }

View file

@ -1,5 +1,7 @@
package health package health
import "fmt"
type Check string type Check string
const ( const (
@ -11,4 +13,11 @@ const (
XDSRouteConfiguration = Check("xds.route-configuration") XDSRouteConfiguration = Check("xds.route-configuration")
// XDSOther is a catch-all for other XDS resources // XDSOther is a catch-all for other XDS resources
XDSOther = Check("xds.other") XDSOther = Check("xds.other")
// ZeroBootstrapConfigSave checks whether the Zero bootstrap config was saved
ZeroBootstrapConfigSave = Check("zero.bootstrap-config.save")
) )
// ZeroResourceBundle checks whether the Zero resource bundle was applied
func ZeroResourceBundle(bundleID string) Check {
return Check(fmt.Sprintf("zero.resource-bundle.%s", bundleID))
}