github_test.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /*
  2. Copyright © The ESO Authors
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. https://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package github
  14. import (
  15. "context"
  16. "fmt"
  17. "net/http"
  18. "net/http/httptest"
  19. "os"
  20. "reflect"
  21. "testing"
  22. "github.com/stretchr/testify/assert"
  23. "github.com/stretchr/testify/require"
  24. v1 "k8s.io/api/core/v1"
  25. apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
  26. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  27. "sigs.k8s.io/controller-runtime/pkg/client"
  28. clientfake "sigs.k8s.io/controller-runtime/pkg/client/fake"
  29. )
  30. const (
  31. tstCrtName = "github_test.pem"
  32. )
  33. func testHTTPSrv(t *testing.T, r []byte, s int) *httptest.Server {
  34. return httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
  35. assert.Equal(t, "POST", req.Method, "Expected POST request")
  36. assert.NotEmpty(t, req.Body)
  37. assert.NotEmpty(t, req.Header.Get("Authorization"))
  38. assert.Equal(t, "application/vnd.github.v3+json", req.Header.Get("Accept"))
  39. // Send response to be tested
  40. rw.WriteHeader(s)
  41. rw.Write(r)
  42. }))
  43. }
  44. func TestGenerate(t *testing.T) {
  45. type args struct {
  46. ctx context.Context
  47. jsonSpec *apiextensions.JSON
  48. kube client.Client
  49. namespace string
  50. }
  51. pem, err := os.ReadFile(tstCrtName)
  52. assert.NoError(t, err, "Should not error when reading privateKey")
  53. validResponce := []byte(`{
  54. "token": "ghs_16C7e42F292c6912E7710c838347Ae178B4a",
  55. "expires_at": "2016-07-11T22:14:10Z",
  56. "permissions": {
  57. "contents": "read"
  58. },
  59. "repositories": [
  60. {
  61. "id": 10000
  62. }
  63. ],
  64. "repository_selection": "selected"
  65. }`)
  66. invalidResponce := []byte(`{
  67. "documentation_url": "https://docs.github.com/rest/reference/apps#create-an-installation-access-token-for-an-app",
  68. "message": "There is at least one repository that does not exist or is not accessible to the parent installation.",
  69. "status": 422
  70. }`)
  71. server := testHTTPSrv(t, validResponce, http.StatusCreated)
  72. badServer := testHTTPSrv(t, invalidResponce, 422)
  73. tests := []struct {
  74. name string
  75. g *Generator
  76. args args
  77. want map[string][]byte
  78. assertErr func(t *testing.T, err error)
  79. server *httptest.Server
  80. }{
  81. {
  82. name: "nil spec",
  83. args: args{
  84. jsonSpec: nil,
  85. },
  86. assertErr: func(t *testing.T, err error) {
  87. require.Error(t, err)
  88. },
  89. server: server,
  90. },
  91. {
  92. name: "full spec",
  93. args: args{
  94. ctx: context.TODO(),
  95. namespace: "foo",
  96. kube: clientfake.NewClientBuilder().WithObjects(&v1.Secret{
  97. ObjectMeta: metav1.ObjectMeta{
  98. Name: "testName",
  99. Namespace: "foo",
  100. },
  101. Data: map[string][]byte{
  102. "privateKey": pem,
  103. },
  104. }).Build(),
  105. jsonSpec: &apiextensions.JSON{
  106. Raw: []byte(fmt.Sprintf(`apiVersion: generators.external-secrets.io/v1alpha1
  107. kind: GithubToken
  108. spec:
  109. appID: "0000000"
  110. installID: "00000000"
  111. URL: %q
  112. repositories:
  113. - "Hello-World"
  114. permissions:
  115. contents: "read"
  116. auth:
  117. privateKey:
  118. secretRef:
  119. name: "testName"
  120. namespace: "foo"
  121. key: "privateKey"`, server.URL)),
  122. },
  123. },
  124. want: map[string][]byte{
  125. "token": []byte("ghs_16C7e42F292c6912E7710c838347Ae178B4a"),
  126. },
  127. assertErr: func(t *testing.T, err error) {
  128. require.NoError(t, err)
  129. },
  130. server: server,
  131. },
  132. {
  133. name: "fail on bad request",
  134. args: args{
  135. ctx: context.TODO(),
  136. namespace: "foo",
  137. kube: clientfake.NewClientBuilder().WithObjects(&v1.Secret{
  138. ObjectMeta: metav1.ObjectMeta{
  139. Name: "testName",
  140. Namespace: "foo",
  141. },
  142. Data: map[string][]byte{
  143. "privateKey": pem,
  144. },
  145. }).Build(),
  146. jsonSpec: &apiextensions.JSON{
  147. Raw: []byte(fmt.Sprintf(`apiVersion: generators.external-secrets.io/v1alpha1
  148. kind: GithubToken
  149. spec:
  150. appID: "0000000"
  151. installID: "00000000"
  152. URL: %q
  153. repositories:
  154. - "octocat/Hello-World"
  155. permissions:
  156. contents: "read"
  157. auth:
  158. privateKey:
  159. secretRef:
  160. name: "testName"
  161. namespace: "foo"
  162. key: "privateKey"`, badServer.URL)),
  163. },
  164. },
  165. assertErr: func(t *testing.T, err error) {
  166. assert.ErrorContains(t, err, "error generating token")
  167. },
  168. server: badServer,
  169. },
  170. }
  171. for _, tt := range tests {
  172. t.Run(tt.name, func(t *testing.T) {
  173. g := &Generator{httpClient: tt.server.Client()}
  174. got, _, err := g.generate(
  175. tt.args.ctx,
  176. tt.args.jsonSpec,
  177. tt.args.kube,
  178. tt.args.namespace,
  179. )
  180. tt.assertErr(t, err)
  181. if !reflect.DeepEqual(got, tt.want) {
  182. t.Errorf("Generator.Generate() = %s, want %s", got, tt.want)
  183. }
  184. })
  185. }
  186. }