Add additional logging for OPA connections (#7982)

This commit is contained in:
Harshavardhana 2019-07-27 20:03:25 -07:00 committed by Nitish Tiwari
parent e871e27562
commit 94c88890b8
3 changed files with 45 additions and 13 deletions

View file

@ -30,7 +30,7 @@ import (
"github.com/minio/minio/pkg/auth" "github.com/minio/minio/pkg/auth"
"github.com/minio/minio/pkg/event" "github.com/minio/minio/pkg/event"
"github.com/minio/minio/pkg/event/target" "github.com/minio/minio/pkg/event/target"
"github.com/minio/minio/pkg/iam/policy" iampolicy "github.com/minio/minio/pkg/iam/policy"
"github.com/minio/minio/pkg/iam/validator" "github.com/minio/minio/pkg/iam/validator"
xnet "github.com/minio/minio/pkg/net" xnet "github.com/minio/minio/pkg/net"
) )
@ -284,13 +284,24 @@ func (s *serverConfig) loadFromEnvs() {
if u, err := xnet.ParseURL(jwksURL); err == nil { if u, err := xnet.ParseURL(jwksURL); err == nil {
s.OpenID.JWKS.URL = u s.OpenID.JWKS.URL = u
logger.FatalIf(s.OpenID.JWKS.PopulatePublicKey(), "Unable to populate public key from JWKS URL") logger.FatalIf(s.OpenID.JWKS.PopulatePublicKey(), "Unable to populate public key from JWKS URL")
} else {
logger.FatalIf(err, "Unable to parse MINIO_IAM_JWKS_URL %s", jwksURL)
} }
} }
if opaURL, ok := os.LookupEnv("MINIO_IAM_OPA_URL"); ok { if opaURL, ok := os.LookupEnv("MINIO_IAM_OPA_URL"); ok {
if u, err := xnet.ParseURL(opaURL); err == nil { if u, err := xnet.ParseURL(opaURL); err == nil {
s.Policy.OPA.URL = u opaArgs := iampolicy.OpaArgs{
s.Policy.OPA.AuthToken = os.Getenv("MINIO_IAM_OPA_AUTHTOKEN") URL: u,
AuthToken: os.Getenv("MINIO_IAM_OPA_AUTHTOKEN"),
Transport: NewCustomHTTPTransport(),
CloseRespFn: xhttp.DrainBody,
}
s.Policy.OPA.URL = opaArgs.URL
s.Policy.OPA.AuthToken = opaArgs.AuthToken
logger.FatalIf(opaArgs.Validate(), "Unable to reach MINIO_IAM_OPA_URL %s", opaURL)
} else {
logger.FatalIf(err, "Unable to parse MINIO_IAM_OPA_URL %s", opaURL)
} }
} }
} }

View file

@ -1236,7 +1236,11 @@ func (sys *IAMSys) IsAllowedSTS(args iampolicy.Args) bool {
func (sys *IAMSys) IsAllowed(args iampolicy.Args) bool { func (sys *IAMSys) IsAllowed(args iampolicy.Args) bool {
// If opa is configured, use OPA always. // If opa is configured, use OPA always.
if globalPolicyOPA != nil { if globalPolicyOPA != nil {
return globalPolicyOPA.IsAllowed(args) ok, err := globalPolicyOPA.IsAllowed(args)
if err != nil {
logger.LogIf(context.Background(), err)
}
return ok
} }
// With claims set, we should do STS related checks and validation. // With claims set, we should do STS related checks and validation.

View file

@ -37,6 +37,23 @@ type OpaArgs struct {
// Validate - validate opa configuration params. // Validate - validate opa configuration params.
func (a *OpaArgs) Validate() error { func (a *OpaArgs) Validate() error {
req, err := http.NewRequest("POST", a.URL.String(), bytes.NewReader([]byte("")))
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
if a.AuthToken != "" {
req.Header.Set("Authorization", a.AuthToken)
}
client := &http.Client{Transport: a.Transport}
resp, err := client.Do(req)
if err != nil {
return err
}
defer a.CloseRespFn(resp.Body)
return nil return nil
} }
@ -92,9 +109,9 @@ func NewOpa(args OpaArgs) *Opa {
} }
// IsAllowed - checks given policy args is allowed to continue the REST API. // IsAllowed - checks given policy args is allowed to continue the REST API.
func (o *Opa) IsAllowed(args Args) bool { func (o *Opa) IsAllowed(args Args) (bool, error) {
if o == nil { if o == nil {
return false return false, nil
} }
// OPA input // OPA input
@ -103,12 +120,12 @@ func (o *Opa) IsAllowed(args Args) bool {
inputBytes, err := json.Marshal(body) inputBytes, err := json.Marshal(body)
if err != nil { if err != nil {
return false return false, err
} }
req, err := http.NewRequest("POST", o.args.URL.String(), bytes.NewReader(inputBytes)) req, err := http.NewRequest("POST", o.args.URL.String(), bytes.NewReader(inputBytes))
if err != nil { if err != nil {
return false return false, err
} }
req.Header.Set("Content-Type", "application/json") req.Header.Set("Content-Type", "application/json")
@ -118,14 +135,14 @@ func (o *Opa) IsAllowed(args Args) bool {
resp, err := o.client.Do(req) resp, err := o.client.Do(req)
if err != nil { if err != nil {
return false return false, err
} }
defer o.args.CloseRespFn(resp.Body) defer o.args.CloseRespFn(resp.Body)
// Read the body to be saved later. // Read the body to be saved later.
opaRespBytes, err := ioutil.ReadAll(resp.Body) opaRespBytes, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
return false return false, err
} }
// Handle large OPA responses when OPA URL is of // Handle large OPA responses when OPA URL is of
@ -149,9 +166,9 @@ func (o *Opa) IsAllowed(args Args) bool {
respBody.Seek(0, 0) respBody.Seek(0, 0)
var resultAllow opaResultAllow var resultAllow opaResultAllow
if err = json.NewDecoder(respBody).Decode(&resultAllow); err != nil { if err = json.NewDecoder(respBody).Decode(&resultAllow); err != nil {
return false return false, err
} }
return resultAllow.Result.Allow return resultAllow.Result.Allow, nil
} }
return result.Result return result.Result, nil
} }