Add testserver package (#2281)
This commit is contained in:
		
							parent
							
								
									8e52a6d2cf
								
							
						
					
					
						commit
						dd8ec1a055
					
				|  | @ -0,0 +1,115 @@ | ||||||
|  | package testserver | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"net/http" | ||||||
|  | 	"net/http/httptest" | ||||||
|  | 	"strings" | ||||||
|  | 	"time" | ||||||
|  | 
 | ||||||
|  | 	"github.com/golang-jwt/jwt/v4" | ||||||
|  | 	"github.com/onsi/ginkgo/v2" | ||||||
|  | 	"github.com/stretchr/testify/require" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // New returns a new httptest.Server that handles the
 | ||||||
|  | // authentication requests neeeded to create a new client. Any requests not
 | ||||||
|  | // made to the /actions/runners/registration-token or
 | ||||||
|  | // /actions/runner-registration endpoints will be handled by the provided
 | ||||||
|  | // handler. The returned server is started and will be automatically closed
 | ||||||
|  | // when the test ends.
 | ||||||
|  | //
 | ||||||
|  | // TODO: this uses ginkgo interface _only_ to support our current controller tests
 | ||||||
|  | func New(t ginkgo.GinkgoTInterface, handler http.Handler, options ...actionsServerOption) *actionsServer { | ||||||
|  | 	s := NewUnstarted(t, handler, options...) | ||||||
|  | 	s.Start() | ||||||
|  | 	return s | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // TODO: this uses ginkgo interface _only_ to support our current controller tests
 | ||||||
|  | func NewUnstarted(t ginkgo.GinkgoTInterface, handler http.Handler, options ...actionsServerOption) *actionsServer { | ||||||
|  | 	s := httptest.NewUnstartedServer(handler) | ||||||
|  | 	server := &actionsServer{ | ||||||
|  | 		Server: s, | ||||||
|  | 	} | ||||||
|  | 	t.Cleanup(func() { | ||||||
|  | 		server.Close() | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	for _, option := range options { | ||||||
|  | 		option(server) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||||
|  | 		// handle getRunnerRegistrationToken
 | ||||||
|  | 		if strings.HasSuffix(r.URL.Path, "/runners/registration-token") { | ||||||
|  | 			w.WriteHeader(http.StatusCreated) | ||||||
|  | 			w.Write([]byte(`{"token":"token"}`)) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// handle getActionsServiceAdminConnection
 | ||||||
|  | 		if strings.HasSuffix(r.URL.Path, "/actions/runner-registration") { | ||||||
|  | 			if server.token == "" { | ||||||
|  | 				server.token = DefaultActionsToken(t) | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			w.Write([]byte(`{"url":"` + s.URL + `/tenant/123/","token":"` + server.token + `"}`)) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		handler.ServeHTTP(w, r) | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	server.Config.Handler = h | ||||||
|  | 
 | ||||||
|  | 	return server | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type actionsServerOption func(*actionsServer) | ||||||
|  | 
 | ||||||
|  | func WithActionsToken(token string) actionsServerOption { | ||||||
|  | 	return func(s *actionsServer) { | ||||||
|  | 		s.token = token | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type actionsServer struct { | ||||||
|  | 	*httptest.Server | ||||||
|  | 
 | ||||||
|  | 	token string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (s *actionsServer) ConfigURLForOrg(org string) string { | ||||||
|  | 	return s.URL + "/" + org | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func DefaultActionsToken(t ginkgo.GinkgoTInterface) string { | ||||||
|  | 	claims := &jwt.RegisteredClaims{ | ||||||
|  | 		IssuedAt:  jwt.NewNumericDate(time.Now().Add(-10 * time.Minute)), | ||||||
|  | 		ExpiresAt: jwt.NewNumericDate(time.Now().Add(10 * time.Minute)), | ||||||
|  | 		Issuer:    "123", | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims) | ||||||
|  | 	privateKey, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(samplePrivateKey)) | ||||||
|  | 	require.NoError(t, err) | ||||||
|  | 	tokenString, err := token.SignedString(privateKey) | ||||||
|  | 	require.NoError(t, err) | ||||||
|  | 	return tokenString | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const samplePrivateKey = `-----BEGIN RSA PRIVATE KEY----- | ||||||
|  | MIICWgIBAAKBgHXfRT9cv9UY9fAAD4+1RshpfSSZe277urfEmPfX3/Og9zJYRk//
 | ||||||
|  | CZrJVD1CaBZDiIyQsNEzjta7r4UsqWdFOggiNN2E7ZTFQjMSaFkVgrzHqWuiaCBf | ||||||
|  | /BjbKPn4SMDmTzHvIe7Nel76hBdCaVgu6mYCW5jmuSH5qz/yR1U1J/WJAgMBAAEC | ||||||
|  | gYARWGWsSU3BYgbu5lNj5l0gKMXNmPhdAJYdbMTF0/KUu18k/XB7XSBgsre+vALt | ||||||
|  | I8r4RGKApoGif8P4aPYUyE8dqA1bh0X3Fj1TCz28qoUL5//dA+pigCRS20H7HM3C
 | ||||||
|  | ojoqF7+F+4F2sXmzFNd1NgY5RxFPYosTT7OnUiFuu2IisQJBALnMLe09LBnjuHXR | ||||||
|  | xxR65DDNxWPQLBjW3dL+ubLcwr7922l6ZIQsVjdeE0ItEUVRjjJ9/B/Jq9VJ/Lw4 | ||||||
|  | g9LCkkMCQQCiaM2f7nYmGivPo9hlAbq5lcGJ5CCYFfeeYzTxMqum7Mbqe4kk5lgb | ||||||
|  | X6gWd0Izg2nGdAEe/97DClO6VpKcPbpDAkBTR/JOJN1fvXMxXJaf13XxakrQMr+R | ||||||
|  | Yr6LlSInykyAz8lJvlLP7A+5QbHgN9NF/wh+GXqpxPwA3ukqdSqhjhWBAkBn6mDv | ||||||
|  | HPgR5xrzL6XM8y9TgaOlJAdK6HtYp6d/UOmN0+Butf6JUq07TphRT5tXNJVgemch | ||||||
|  | O5x/9UKfbrc+KyzbAkAo97TfFC+mZhU1N5fFelaRu4ikPxlp642KRUSkOh8GEkNf | ||||||
|  | jQ97eJWiWtDcsMUhcZgoB5ydHcFlrBIn6oBcpge5 | ||||||
|  | -----END RSA PRIVATE KEY-----` | ||||||
		Loading…
	
		Reference in New Issue