Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gopherpolicy: remove explicit YAML dependency #179

Merged
merged 1 commit into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions gopherpolicy/pkg.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ import (
"fmt"
"net/http"
"os"
"strings"
"time"

policy "github.com/databus23/goslo.policy"
"github.com/gophercloud/gophercloud/v2"
"github.com/gophercloud/gophercloud/v2/openstack"
"github.com/gophercloud/gophercloud/v2/openstack/identity/v3/tokens"
"gopkg.in/yaml.v2"

"github.com/sapcc/go-bits/logg"
)
Expand Down Expand Up @@ -72,13 +72,28 @@ type TokenValidator struct {
}

// LoadPolicyFile creates v.Enforcer from the given policy file.
func (v *TokenValidator) LoadPolicyFile(path string) error {
//
// The second argument must be set to `yaml.Unmarshal` if you want to support
// policy.yaml files. This explicit dependency injection slot allows you to choose
// whether to use gopkg.in/yaml.v2 or gopkg.in/yaml.v3 or anything else.
//
// If `yamlUnmarshal` is given as nil, `json.Unmarshal` from the standard
// library will be used, so only policy.json files will be understood.
func (v *TokenValidator) LoadPolicyFile(path string, yamlUnmarshal func(in []byte, out any) error) error {
unmarshal := yamlUnmarshal
if yamlUnmarshal == nil {
unmarshal = json.Unmarshal
if strings.HasSuffix(path, ".yaml") {
return fmt.Errorf("LoadPolicyFile cannot parse %s because YAML support is not available", path)
}
}

bytes, err := os.ReadFile(path)
if err != nil {
return err // no fmt.Errorf() necessary, errors from package os are already very descriptive
}
var rules map[string]string
err = yaml.Unmarshal(bytes, &rules)
err = unmarshal(bytes, &rules)
if err != nil {
return fmt.Errorf("while parsing structure of %s: %w", path, err)
}
Expand Down
7 changes: 6 additions & 1 deletion liquidapi/liquidapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ type RunOpts struct {
// the Logic instance to supply configuration to it, before Init() is called.
TakesConfiguration bool

// If set, when the runtime loads its oslo.policy from $LIQUID_POLICY_PATH,
// YAML will be supported in addition to JSON. This is an explicit dependency
// injection slot to allow the caller to choose their YAML library.
YAMLUnmarshal func(in []byte, out any) error

// How often the runtime will call BuildServiceInfo() to refresh the
// ServiceInfo of the liquid. The zero value can be used for liquids with
// static ServiceInfo; no polling will be performed then.
Expand Down Expand Up @@ -177,7 +182,7 @@ func Run(ctx context.Context, logic Logic, opts RunOpts) error {
if err != nil {
return err
}
err = tv.LoadPolicyFile(policyPath)
err = tv.LoadPolicyFile(policyPath, opts.YAMLUnmarshal)
if err != nil {
return err
}
Expand Down