mirror of https://github.com/minio/minio.git
				
				
				
			Add HTTP2 config option for policy plugin (#16225)
This commit is contained in:
		
							parent
							
								
									709eb283d9
								
							
						
					
					
						commit
						9e6cc847f8
					
				|  | @ -374,8 +374,7 @@ func validateSubSysConfig(s config.Config, subSys string, objAPI ObjectLayer) er | |||
| 		subSys = config.PolicyPluginSubSys | ||||
| 		fallthrough | ||||
| 	case config.PolicyPluginSubSys: | ||||
| 		if ppargs, err := polplugin.LookupConfig(s[config.PolicyPluginSubSys][config.Default], | ||||
| 			NewHTTPTransport(), xhttp.DrainBody); err != nil { | ||||
| 		if ppargs, err := polplugin.LookupConfig(s, GetDefaultConnSettings(), xhttp.DrainBody); err != nil { | ||||
| 			return err | ||||
| 		} else if ppargs.URL == nil { | ||||
| 			// Check if legacy opa is configured.
 | ||||
|  |  | |||
|  | @ -233,8 +233,7 @@ func (sys *IAMSys) Init(ctx context.Context, objAPI ObjectLayer, etcdClient *etc | |||
| 
 | ||||
| 	setGlobalAuthNPlugin(idplugin.New(authNPluginCfg)) | ||||
| 
 | ||||
| 	authZPluginCfg, err := polplugin.LookupConfig(s[config.PolicyPluginSubSys][config.Default], | ||||
| 		NewHTTPTransport(), xhttp.DrainBody) | ||||
| 	authZPluginCfg, err := polplugin.LookupConfig(s, GetDefaultConnSettings(), xhttp.DrainBody) | ||||
| 	if err != nil { | ||||
| 		logger.LogIf(ctx, fmt.Errorf("Unable to initialize AuthZPlugin: %w", err)) | ||||
| 	} | ||||
|  |  | |||
|  | @ -568,6 +568,15 @@ func ToS3ETag(etag string) string { | |||
| 	return etag | ||||
| } | ||||
| 
 | ||||
| // GetDefaultConnSettings returns default HTTP connection settings.
 | ||||
| func GetDefaultConnSettings() xhttp.ConnSettings { | ||||
| 	return xhttp.ConnSettings{ | ||||
| 		DNSCache:    globalDNSCache, | ||||
| 		DialTimeout: rest.DefaultTimeout, | ||||
| 		RootCAs:     globalRootCAs, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // NewInternodeHTTPTransport returns a transport for internode MinIO
 | ||||
| // connections.
 | ||||
| func NewInternodeHTTPTransport() func() http.RoundTripper { | ||||
|  |  | |||
|  | @ -46,16 +46,19 @@ Only the last operation would fail with a permissions error. | |||
| Access Management Plugin can be configured with environment variables: | ||||
| 
 | ||||
| ```sh | ||||
| $ mc admin config set dminio1 policy_plugin --env | ||||
| $ mc admin config set myminio policy_plugin --env | ||||
| KEY: | ||||
| policy_plugin  enable Access Management Plugin for policy enforcement | ||||
| 
 | ||||
| ARGS: | ||||
| MINIO_POLICY_PLUGIN_URL*        (url)       plugin hook endpoint (HTTP(S)) e.g. "http://localhost:8181/v1/data/httpapi/authz/allow" | ||||
| MINIO_POLICY_PLUGIN_AUTH_TOKEN  (string)    authorization token for plugin hook endpoint | ||||
| MINIO_POLICY_PLUGIN_COMMENT     (sentence)  optionally add a comment to this setting | ||||
| MINIO_POLICY_PLUGIN_URL*          (url)       plugin hook endpoint (HTTP(S)) e.g. "http://localhost:8181/v1/data/httpapi/authz/allow" | ||||
| MINIO_POLICY_PLUGIN_AUTH_TOKEN    (string)    authorization header for plugin hook endpoint | ||||
| MINIO_POLICY_PLUGIN_ENABLE_HTTP2  (bool)      Enable experimental HTTP2 support to connect to plugin service (default: 'off') | ||||
| MINIO_POLICY_PLUGIN_COMMENT       (sentence)  optionally add a comment to this setting | ||||
| ``` | ||||
| 
 | ||||
| By default this plugin uses HTTP 1.x. To enable HTTP2 use the `MINIO_POLICY_PLUGIN_ENABLE_HTTP2` environment variable. | ||||
| 
 | ||||
| ## Request and Response | ||||
| 
 | ||||
| MinIO will make a `POST` request with a JSON body to the given plugin URL. If the auth token parameter is set, it will be sent as an authorization header. | ||||
|  |  | |||
|  | @ -22,6 +22,7 @@ package main | |||
| 
 | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"flag" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"log" | ||||
|  | @ -29,6 +30,16 @@ import ( | |||
| 	"strings" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	keyFile  string | ||||
| 	certFile string | ||||
| ) | ||||
| 
 | ||||
| func init() { | ||||
| 	flag.StringVar(&keyFile, "key-file", "", "Path to TLS cert key file") | ||||
| 	flag.StringVar(&certFile, "cert-file", "", "Path to TLS cert file") | ||||
| } | ||||
| 
 | ||||
| func writeErrorResponse(w http.ResponseWriter, err error) { | ||||
| 	w.WriteHeader(http.StatusBadRequest) | ||||
| 	json.NewEncoder(w).Encode(map[string]string{ | ||||
|  | @ -77,8 +88,22 @@ func mainHandler(w http.ResponseWriter, r *http.Request) { | |||
| } | ||||
| 
 | ||||
| func main() { | ||||
| 	flag.Parse() | ||||
| 	serveFunc := func() error { | ||||
| 		return http.ListenAndServe(":8080", nil) | ||||
| 	} | ||||
| 
 | ||||
| 	if certFile != "" || keyFile != "" { | ||||
| 		if certFile == "" || keyFile == "" { | ||||
| 			log.Fatal("Please provide both a key file and a cert file to enable TLS.") | ||||
| 		} | ||||
| 		serveFunc = func() error { | ||||
| 			return http.ListenAndServeTLS(":8080", certFile, keyFile, nil) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	http.HandleFunc("/", mainHandler) | ||||
| 
 | ||||
| 	log.Print("Listening on :8080") | ||||
| 	log.Fatal(http.ListenAndServe(":8080", nil)) | ||||
| 	log.Fatal(serveFunc()) | ||||
| } | ||||
|  |  | |||
|  | @ -1076,7 +1076,7 @@ func getEnvVarName(subSys, target, param string) string { | |||
| 		Default, target) | ||||
| } | ||||
| 
 | ||||
| var resolvableSubsystems = set.CreateStringSet(IdentityOpenIDSubSys, IdentityLDAPSubSys) | ||||
| var resolvableSubsystems = set.CreateStringSet(IdentityOpenIDSubSys, IdentityLDAPSubSys, PolicyPluginSubSys) | ||||
| 
 | ||||
| // ValueSource represents the source of a config parameter value.
 | ||||
| type ValueSource uint8 | ||||
|  |  | |||
|  | @ -22,20 +22,23 @@ import ( | |||
| 	"encoding/json" | ||||
| 	"io" | ||||
| 	"net/http" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/minio/minio/internal/config" | ||||
| 	"github.com/minio/pkg/env" | ||||
| 	xhttp "github.com/minio/minio/internal/http" | ||||
| 	iampolicy "github.com/minio/pkg/iam/policy" | ||||
| 	xnet "github.com/minio/pkg/net" | ||||
| ) | ||||
| 
 | ||||
| // Authorization Plugin config and env variables
 | ||||
| const ( | ||||
| 	URL       = "url" | ||||
| 	AuthToken = "auth_token" | ||||
| 	URL         = "url" | ||||
| 	AuthToken   = "auth_token" | ||||
| 	EnableHTTP2 = "enable_http2" | ||||
| 
 | ||||
| 	EnvPolicyPluginURL       = "MINIO_POLICY_PLUGIN_URL" | ||||
| 	EnvPolicyPluginAuthToken = "MINIO_POLICY_PLUGIN_AUTH_TOKEN" | ||||
| 	EnvPolicyPluginURL         = "MINIO_POLICY_PLUGIN_URL" | ||||
| 	EnvPolicyPluginAuthToken   = "MINIO_POLICY_PLUGIN_AUTH_TOKEN" | ||||
| 	EnvPolicyPluginEnableHTTP2 = "MINIO_POLICY_PLUGIN_ENABLE_HTTP2" | ||||
| ) | ||||
| 
 | ||||
| // DefaultKVS - default config for Authz plugin config
 | ||||
|  | @ -49,10 +52,14 @@ var ( | |||
| 			Key:   AuthToken, | ||||
| 			Value: "", | ||||
| 		}, | ||||
| 		config.KV{ | ||||
| 			Key:   EnableHTTP2, | ||||
| 			Value: "off", | ||||
| 		}, | ||||
| 	} | ||||
| ) | ||||
| 
 | ||||
| // Args opa general purpose policy engine configuration.
 | ||||
| // Args for general purpose policy engine configuration.
 | ||||
| type Args struct { | ||||
| 	URL         *xnet.URL             `json:"url"` | ||||
| 	AuthToken   string                `json:"authToken"` | ||||
|  | @ -114,27 +121,43 @@ func Enabled(kvs config.KVS) bool { | |||
| } | ||||
| 
 | ||||
| // LookupConfig lookup AuthZPlugin from config, override with any ENVs.
 | ||||
| func LookupConfig(kv config.KVS, transport *http.Transport, closeRespFn func(io.ReadCloser)) (Args, error) { | ||||
| func LookupConfig(s config.Config, httpSettings xhttp.ConnSettings, closeRespFn func(io.ReadCloser)) (Args, error) { | ||||
| 	args := Args{} | ||||
| 
 | ||||
| 	if err := config.CheckValidKeys(config.PolicyPluginSubSys, kv, DefaultKVS); err != nil { | ||||
| 	if err := s.CheckValidKeys(config.PolicyPluginSubSys, nil); err != nil { | ||||
| 		return args, err | ||||
| 	} | ||||
| 
 | ||||
| 	pluginURL := env.Get(EnvPolicyPluginURL, kv.Get(URL)) | ||||
| 	getCfg := func(cfgParam string) string { | ||||
| 		// As parameters are already validated, we skip checking
 | ||||
| 		// if the config param was found.
 | ||||
| 		val, _ := s.ResolveConfigParam(config.PolicyPluginSubSys, config.Default, cfgParam) | ||||
| 		return val | ||||
| 	} | ||||
| 
 | ||||
| 	pluginURL := getCfg(URL) | ||||
| 	if pluginURL == "" { | ||||
| 		return args, nil | ||||
| 	} | ||||
| 
 | ||||
| 	authToken := env.Get(EnvPolicyPluginAuthToken, kv.Get(AuthToken)) | ||||
| 
 | ||||
| 	u, err := xnet.ParseHTTPURL(pluginURL) | ||||
| 	if err != nil { | ||||
| 		return args, err | ||||
| 	} | ||||
| 
 | ||||
| 	enableHTTP2 := false | ||||
| 	if v := getCfg(EnableHTTP2); v != "" { | ||||
| 		enableHTTP2, err = config.ParseBool(v) | ||||
| 		if err != nil { | ||||
| 			return args, err | ||||
| 		} | ||||
| 	} | ||||
| 	httpSettings.EnableHTTP2 = enableHTTP2 | ||||
| 	transport := httpSettings.NewHTTPTransportWithTimeout(time.Minute) | ||||
| 
 | ||||
| 	args = Args{ | ||||
| 		URL:         u, | ||||
| 		AuthToken:   authToken, | ||||
| 		AuthToken:   getCfg(AuthToken), | ||||
| 		Transport:   transport, | ||||
| 		CloseRespFn: closeRespFn, | ||||
| 	} | ||||
|  |  | |||
|  | @ -34,11 +34,17 @@ var ( | |||
| 		}, | ||||
| 		config.HelpKV{ | ||||
| 			Key:         AuthToken, | ||||
| 			Description: "authorization token for plugin hook endpoint" + defaultHelpPostfix(AuthToken), | ||||
| 			Description: "authorization header for plugin hook endpoint" + defaultHelpPostfix(AuthToken), | ||||
| 			Optional:    true, | ||||
| 			Type:        "string", | ||||
| 			Sensitive:   true, | ||||
| 		}, | ||||
| 		config.HelpKV{ | ||||
| 			Key:         EnableHTTP2, | ||||
| 			Description: "Enable experimental HTTP2 support to connect to plugin service" + defaultHelpPostfix(EnableHTTP2), | ||||
| 			Optional:    true, | ||||
| 			Type:        "bool", | ||||
| 		}, | ||||
| 		config.HelpKV{ | ||||
| 			Key:         config.Comment, | ||||
| 			Description: config.DefaultComment, | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue