internal/api/api.go (65 lines of code) (raw):

package internal_api //nolint:staticcheck import ( "bytes" "context" "encoding/json" "fmt" "io" "net/http" "net/url" "time" "gitlab.com/gitlab-org/gitlab-zoekt-indexer/internal/authentication" ) const ( apiBasePath = "/api/v4/internal/search/zoekt" jwtIssuer = "gitlab-shell" // Needs to be shell so that rails verifies the payload jwtRequestHeader = "Gitlab-Shell-Api-Request" // TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/426557 jwtTTL = time.Minute ) type InternalAPIRequestParams struct { Path string BodyParams any GitlabURL string NodeUUID string Secret []byte } func NewRequest(ctx context.Context, params InternalAPIRequestParams) (*http.Request, error) { if len(params.Secret) == 0 { return nil, fmt.Errorf("secret is empty") } secret, err := generateJWTForRailsAPI(params.Secret) if err != nil { return nil, err } endpoint, err := url.JoinPath(params.GitlabURL, apiBasePath, params.NodeUUID, params.Path) if err != nil { return nil, err } var body io.Reader if params.BodyParams != nil { jsonParams, marshalErr := json.Marshal(params.BodyParams) if marshalErr != nil { return nil, marshalErr } body = bytes.NewReader(jsonParams) } req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint, body) if err != nil { return nil, err } req.Header = http.Header{ "Accept": []string{"application/json"}, jwtRequestHeader: []string{secret}, } if body != nil { req.Header.Set("Content-Type", "application/json") } return req, nil } func generateJWTForRailsAPI(secret []byte) (string, error) { tokenString, authErr := authentication.NewAuth(jwtIssuer, jwtTTL, secret).GenerateJWT() if authErr != nil { return "", authErr } return tokenString, nil }