mirror of
https://github.com/open-policy-agent/opa.git
synced 2026-08-25 17:55:15 -06:00
d3f34a3387
Have done this some time in the past, but there was a few new issues this would highlight now that we're on Go 1.24. Mostly: - Use `b.Loop()` in benchmarks - Use `strings.SplitSeq` where possible - Remove `omitempty` tag for types that can't be empty Signed-off-by: Anders Eknert <anders@eknert.com>
136 lines
3.8 KiB
Go
136 lines
3.8 KiB
Go
// Copyright 2018 The OPA Authors. All rights reserved.
|
|
// Use of this source code is governed by an Apache2
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package bundle
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"reflect"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/open-policy-agent/opa/v1/ast"
|
|
"github.com/open-policy-agent/opa/v1/download"
|
|
"github.com/open-policy-agent/opa/v1/metrics"
|
|
"github.com/open-policy-agent/opa/v1/server/types"
|
|
)
|
|
|
|
const (
|
|
errCode = "bundle_error"
|
|
)
|
|
|
|
// Status represents the status of processing a bundle.
|
|
type Status struct {
|
|
Name string `json:"name"`
|
|
ActiveRevision string `json:"active_revision,omitempty"`
|
|
LastSuccessfulActivation time.Time `json:"last_successful_activation"`
|
|
Type string `json:"type,omitempty"`
|
|
Size int `json:"size,omitempty"`
|
|
LastSuccessfulDownload time.Time `json:"last_successful_download"`
|
|
LastSuccessfulRequest time.Time `json:"last_successful_request"`
|
|
LastRequest time.Time `json:"last_request"`
|
|
Code string `json:"code,omitempty"`
|
|
Message string `json:"message,omitempty"`
|
|
Errors []error `json:"errors,omitempty"`
|
|
Metrics metrics.Metrics `json:"metrics,omitempty"`
|
|
HTTPCode json.Number `json:"http_code,omitempty"`
|
|
}
|
|
|
|
// SetActivateSuccess updates the status object to reflect a successful
|
|
// activation.
|
|
func (s *Status) SetActivateSuccess(revision string) {
|
|
s.LastSuccessfulActivation = time.Now().UTC()
|
|
s.ActiveRevision = revision
|
|
}
|
|
|
|
// SetDownloadSuccess updates the status object to reflect a successful
|
|
// download.
|
|
func (s *Status) SetDownloadSuccess() {
|
|
s.LastSuccessfulDownload = time.Now().UTC()
|
|
}
|
|
|
|
// SetRequest updates the status object to reflect a download attempt.
|
|
func (s *Status) SetRequest() {
|
|
s.LastRequest = time.Now().UTC()
|
|
}
|
|
|
|
func (s *Status) SetBundleSize(size int) {
|
|
s.Size = size
|
|
}
|
|
|
|
// SetError updates the status object to reflect a failure to download or
|
|
// activate. If err is nil, the error status is cleared.
|
|
func (s *Status) SetError(err error) {
|
|
var (
|
|
astErrors ast.Errors
|
|
httpError download.HTTPError
|
|
)
|
|
switch {
|
|
case err == nil:
|
|
s.Code = ""
|
|
s.HTTPCode = ""
|
|
s.Message = ""
|
|
s.Errors = nil
|
|
|
|
case errors.As(err, &astErrors):
|
|
s.Code = errCode
|
|
s.HTTPCode = ""
|
|
s.Message = types.MsgCompileModuleError
|
|
s.Errors = make([]error, len(astErrors))
|
|
for i := range astErrors {
|
|
s.Errors[i] = astErrors[i]
|
|
}
|
|
|
|
case errors.As(err, &httpError):
|
|
s.Code = errCode
|
|
s.HTTPCode = json.Number(strconv.Itoa(httpError.StatusCode))
|
|
s.Message = err.Error()
|
|
s.Errors = nil
|
|
|
|
default:
|
|
s.Code = errCode
|
|
s.HTTPCode = ""
|
|
s.Message = err.Error()
|
|
s.Errors = nil
|
|
}
|
|
}
|
|
|
|
func (s *Status) Equal(other *Status) bool {
|
|
if s == nil || other == nil {
|
|
return s == nil && other == nil
|
|
}
|
|
|
|
equal := s.Name == other.Name &&
|
|
s.Type == other.Type &&
|
|
s.Size == other.Size &&
|
|
s.Code == other.Code &&
|
|
s.Message == other.Message &&
|
|
s.HTTPCode == other.HTTPCode &&
|
|
s.ActiveRevision == other.ActiveRevision &&
|
|
s.LastSuccessfulActivation.Equal(other.LastSuccessfulActivation) &&
|
|
s.LastSuccessfulDownload.Equal(other.LastSuccessfulDownload) &&
|
|
s.LastSuccessfulRequest.Equal(other.LastSuccessfulRequest) &&
|
|
s.LastRequest.Equal(other.LastRequest)
|
|
|
|
if !equal {
|
|
return false
|
|
}
|
|
|
|
if len(s.Errors) != len(other.Errors) {
|
|
return false
|
|
}
|
|
for i := range s.Errors {
|
|
if s.Errors[i].Error() != other.Errors[i].Error() {
|
|
return false
|
|
}
|
|
}
|
|
|
|
if s.Metrics != nil && other.Metrics != nil && s.Metrics.All() != nil && other.Metrics.All() != nil {
|
|
return reflect.DeepEqual(s.Metrics.All(), other.Metrics.All())
|
|
}
|
|
|
|
return s.Metrics == nil && other.Metrics == nil
|
|
}
|