github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/controller/pkg/remoteenforcer/internal/tokenissuer/tokenissuer.go (about) 1 package tokenissuer 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "os" 8 "reflect" 9 "time" 10 11 "go.aporeto.io/enforcerd/trireme-lib/common" 12 "go.aporeto.io/enforcerd/trireme-lib/controller/constants" 13 "go.aporeto.io/enforcerd/trireme-lib/controller/internal/enforcer/utils/rpcwrapper" 14 "go.uber.org/zap" 15 ) 16 17 // TokenClient interface provides a start function. the client is used to 18 // request tokens. 19 type TokenClient interface { 20 Run(ctx context.Context) error 21 Issue(ctx context.Context, contextID string, stype common.ServiceTokenType, audience string, validity time.Duration) (string, error) 22 } 23 24 const ( 25 tokenIssuerContextID = "UNUSED" 26 retrieveTokenCommand = "ProxyRPCServer.RetrieveToken" 27 ) 28 29 // Client represents the remote API client. 30 type Client struct { 31 rpchdl rpcwrapper.RPCClient 32 secret string 33 socketPath string 34 stop chan bool 35 } 36 37 // NewClient returns a remote API client that can be used for 38 // issuing API calls to the master enforcer. 39 func NewClient() (*Client, error) { 40 c := &Client{ 41 rpchdl: rpcwrapper.NewRPCWrapper(), 42 secret: os.Getenv(constants.EnvStatsSecret), 43 socketPath: os.Getenv(constants.EnvStatsChannel), 44 stop: make(chan bool), 45 } 46 if c.socketPath == "" { 47 return nil, errors.New("no path to socket provided") 48 } 49 if c.secret == "" { 50 return nil, errors.New("no secret provided for channel") 51 } 52 53 return c, nil 54 } 55 56 // RetrieveToken will issue a token request to the main over the RPC channnel. 57 func (c *Client) RetrieveToken(contextID string, stype common.ServiceTokenType, audience string, validity time.Duration) (string, error) { 58 59 request := &rpcwrapper.Request{ 60 Payload: &rpcwrapper.TokenRequestPayload{ 61 ContextID: contextID, 62 Audience: audience, 63 Validity: validity, 64 ServiceTokenType: stype, 65 }, 66 } 67 68 response := &rpcwrapper.Response{} 69 70 if err := c.rpchdl.RemoteCall(tokenIssuerContextID, retrieveTokenCommand, request, response); err != nil { 71 return "", err 72 } 73 74 payload, ok := response.Payload.(rpcwrapper.TokenResponsePayload) 75 if !ok { 76 return "", fmt.Errorf("unrecognized response payload. Received payload is %s", reflect.TypeOf(response.Payload)) 77 } 78 79 return payload.Token, nil 80 } 81 82 // Issue implements the ServiceTokenIssuer interface. 83 func (c *Client) Issue(ctx context.Context, contextID string, stype common.ServiceTokenType, audience string, validity time.Duration) (string, error) { 84 return c.RetrieveToken(contextID, stype, audience, validity) 85 } 86 87 // Run will initialize the client. 88 func (c *Client) Run(ctx context.Context) error { 89 if err := c.rpchdl.NewRPCClient(tokenIssuerContextID, c.socketPath, c.secret); err != nil { 90 zap.L().Error("CounterClient RPC client cannot connect", zap.Error(err)) 91 return err 92 } 93 return nil 94 }