plugin.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. package authorization
  2. import (
  3. "sync"
  4. "github.com/docker/docker/pkg/plugingetter"
  5. "github.com/docker/docker/pkg/plugins"
  6. )
  7. // Plugin allows third party plugins to authorize requests and responses
  8. // in the context of docker API
  9. type Plugin interface {
  10. // Name returns the registered plugin name
  11. Name() string
  12. // AuthZRequest authorizes the request from the client to the daemon
  13. AuthZRequest(*Request) (*Response, error)
  14. // AuthZResponse authorizes the response from the daemon to the client
  15. AuthZResponse(*Request) (*Response, error)
  16. }
  17. // newPlugins constructs and initializes the authorization plugins based on plugin names
  18. func newPlugins(names []string) []Plugin {
  19. plugins := []Plugin{}
  20. pluginsMap := make(map[string]struct{})
  21. for _, name := range names {
  22. if _, ok := pluginsMap[name]; ok {
  23. continue
  24. }
  25. pluginsMap[name] = struct{}{}
  26. plugins = append(plugins, newAuthorizationPlugin(name))
  27. }
  28. return plugins
  29. }
  30. var getter plugingetter.PluginGetter
  31. // SetPluginGetter sets the plugingetter
  32. func SetPluginGetter(pg plugingetter.PluginGetter) {
  33. getter = pg
  34. }
  35. // GetPluginGetter gets the plugingetter
  36. func GetPluginGetter() plugingetter.PluginGetter {
  37. return getter
  38. }
  39. // authorizationPlugin is an internal adapter to docker plugin system
  40. type authorizationPlugin struct {
  41. plugin *plugins.Client
  42. name string
  43. once sync.Once
  44. }
  45. func newAuthorizationPlugin(name string) Plugin {
  46. return &authorizationPlugin{name: name}
  47. }
  48. func (a *authorizationPlugin) Name() string {
  49. return a.name
  50. }
  51. // Set the remote for an authz pluginv2
  52. func (a *authorizationPlugin) SetName(remote string) {
  53. a.name = remote
  54. }
  55. func (a *authorizationPlugin) AuthZRequest(authReq *Request) (*Response, error) {
  56. if err := a.initPlugin(); err != nil {
  57. return nil, err
  58. }
  59. authRes := &Response{}
  60. if err := a.plugin.Call(AuthZApiRequest, authReq, authRes); err != nil {
  61. return nil, err
  62. }
  63. return authRes, nil
  64. }
  65. func (a *authorizationPlugin) AuthZResponse(authReq *Request) (*Response, error) {
  66. if err := a.initPlugin(); err != nil {
  67. return nil, err
  68. }
  69. authRes := &Response{}
  70. if err := a.plugin.Call(AuthZApiResponse, authReq, authRes); err != nil {
  71. return nil, err
  72. }
  73. return authRes, nil
  74. }
  75. // initPlugin initializes the authorization plugin if needed
  76. func (a *authorizationPlugin) initPlugin() error {
  77. // Lazy loading of plugins
  78. var err error
  79. a.once.Do(func() {
  80. if a.plugin == nil {
  81. var plugin plugingetter.CompatPlugin
  82. var e error
  83. if pg := GetPluginGetter(); pg != nil {
  84. plugin, e = pg.Get(a.name, AuthZApiImplements, plugingetter.Lookup)
  85. a.SetName(plugin.Name())
  86. } else {
  87. plugin, e = plugins.Get(a.name, AuthZApiImplements)
  88. }
  89. if e != nil {
  90. err = e
  91. return
  92. }
  93. a.plugin = plugin.Client()
  94. }
  95. })
  96. return err
  97. }