Skip to content

Commit

Permalink
feat: add BuildSetStatusResponse to plugin helper (#47)
Browse files Browse the repository at this point in the history
Signed-off-by: Armando Ruocco <[email protected]>
Signed-off-by: Leonardo Cecchi <[email protected]>
Co-authored-by: Leonardo Cecchi <[email protected]>
  • Loading branch information
armru and leonardoce authored Aug 7, 2024
1 parent 9621082 commit a3bd4ce
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 2 deletions.
4 changes: 2 additions & 2 deletions pkg/pluginhelper/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,14 +182,14 @@ func (*Data) DecodeBackup(backupDefinition []byte) (*apiv1.Backup, error) {
return &backup, nil
}

// GetKind gets the Kubernetes object kind from its JSON representation
// GetKind gets the Kubernetes object kind from its JSON representation.
func GetKind(definition []byte) (string, error) {
var genericObject struct {
Kind string `json:"kind"`
}

if err := json.Unmarshal(definition, &genericObject); err != nil {
return "", err
return "", fmt.Errorf("while unmarshalling resource definition: %w", err)
}

return genericObject.Kind, nil
Expand Down
70 changes: 70 additions & 0 deletions pkg/pluginhelper/status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package pluginhelper

import (
"encoding/json"
"errors"
"fmt"

"github.com/cloudnative-pg/cnpg-i/pkg/operator"
)

// ErrNilObject is used when a nill object is passed to the builder.
var ErrNilObject = errors.New("nil object passed, use NoOpResponse")

// NotAnObjectError is used when the passed value cannot be represented
// as a JSON object.
type NotAnObjectError struct {
representation []byte
}

func (err NotAnObjectError) Error() string {
return fmt.Sprintf(
"the passed variable cannot be serialized as a JSON object: %s",
err.representation,
)
}

// SetStatusResponseBuilder a SetStatus response builder.
type SetStatusResponseBuilder struct{}

// NewSetStatusResponseBuilder is an helper that creates the SetStatus endpoint responses.
func NewSetStatusResponseBuilder() *SetStatusResponseBuilder {
return &SetStatusResponseBuilder{}
}

// NoOpResponse this response will ensure that no changes will be done to the plugin status.
func (s SetStatusResponseBuilder) NoOpResponse() *operator.SetClusterStatusResponse {
return &operator.SetClusterStatusResponse{JsonStatus: nil}
}

// SetEmptyStatusResponse will set the plugin status to an empty object '{}'.
func (s SetStatusResponseBuilder) SetEmptyStatusResponse() *operator.SetClusterStatusResponse {
b, err := json.Marshal(map[string]string{})
if err != nil {
panic("JSON mashaller failed for empty map")
}

return &operator.SetClusterStatusResponse{JsonStatus: b}
}

// JSONStatusResponse requires a struct or map that can be translated to a JSON object,
// will set the status to the passed object.
func (s SetStatusResponseBuilder) JSONStatusResponse(obj any) (*operator.SetClusterStatusResponse, error) {
if obj == nil {
return nil, ErrNilObject
}

jsonObject, err := json.Marshal(obj)
if err != nil {
return nil, fmt.Errorf("while marshalling resource definition: %w", err)
}

var js map[string]interface{}
if err := json.Unmarshal(jsonObject, &js); err != nil {
return nil, NotAnObjectError{representation: jsonObject}
}

return &operator.SetClusterStatusResponse{
JsonStatus: jsonObject,
}, nil
}
35 changes: 35 additions & 0 deletions pkg/pluginhelper/status_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package pluginhelper

import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

var _ = Describe("BuildSetStatusResponse", func() {
type test struct {
Name string `json:"string"`
}

It("should properly form a response with an object, allowing the plugins to set the status", func() {
jsonBody := test{Name: "test"}
b, err := NewSetStatusResponseBuilder().JSONStatusResponse(&jsonBody)
Expect(err).NotTo(HaveOccurred())
Expect(b.GetJsonStatus()).ToNot(BeEmpty())
})

It("should properly form a response for a 'nil' value, allowing the plugins to do a 'noop'", func() {
b := NewSetStatusResponseBuilder().NoOpResponse()
Expect(b.GetJsonStatus()).To(BeNil())
})

It("should serialize an empty JSONStatus, allowing the plugins to reset its status", func() {
b := NewSetStatusResponseBuilder().SetEmptyStatusResponse()
Expect(b.GetJsonStatus()).ToNot(BeEmpty())
})

It("should return an error if it is an invalid JSON object", func() {
wrongType := 4
_, err := NewSetStatusResponseBuilder().JSONStatusResponse(&wrongType)
Expect(err).To(HaveOccurred())
})
})

0 comments on commit a3bd4ce

Please sign in to comment.