api_test.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. package csconfig
  2. import (
  3. "fmt"
  4. "os"
  5. "path/filepath"
  6. "strings"
  7. "testing"
  8. "github.com/crowdsecurity/crowdsec/pkg/types"
  9. log "github.com/sirupsen/logrus"
  10. "github.com/stretchr/testify/assert"
  11. "gopkg.in/yaml.v2"
  12. "github.com/crowdsecurity/crowdsec/pkg/cstest"
  13. )
  14. func TestLoadLocalApiClientCfg(t *testing.T) {
  15. tests := []struct {
  16. name string
  17. input *LocalApiClientCfg
  18. expected *ApiCredentialsCfg
  19. expectedErr string
  20. }{
  21. {
  22. name: "basic valid configuration",
  23. input: &LocalApiClientCfg{
  24. CredentialsFilePath: "./tests/lapi-secrets.yaml",
  25. },
  26. expected: &ApiCredentialsCfg{
  27. URL: "http://localhost:8080/",
  28. Login: "test",
  29. Password: "testpassword",
  30. },
  31. },
  32. {
  33. name: "invalid configuration",
  34. input: &LocalApiClientCfg{
  35. CredentialsFilePath: "./tests/bad_lapi-secrets.yaml",
  36. },
  37. expected: &ApiCredentialsCfg{},
  38. expectedErr: "field unknown_key not found in type csconfig.ApiCredentialsCfg",
  39. },
  40. {
  41. name: "invalid configuration filepath",
  42. input: &LocalApiClientCfg{
  43. CredentialsFilePath: "./tests/nonexist_lapi-secrets.yaml",
  44. },
  45. expected: nil,
  46. expectedErr: "open ./tests/nonexist_lapi-secrets.yaml: " + cstest.FileNotFoundMessage,
  47. },
  48. {
  49. name: "valid configuration with insecure skip verify",
  50. input: &LocalApiClientCfg{
  51. CredentialsFilePath: "./tests/lapi-secrets.yaml",
  52. InsecureSkipVerify: types.BoolPtr(false),
  53. },
  54. expected: &ApiCredentialsCfg{
  55. URL: "http://localhost:8080/",
  56. Login: "test",
  57. Password: "testpassword",
  58. },
  59. },
  60. }
  61. for _, tc := range tests {
  62. tc := tc
  63. t.Run(tc.name, func(t *testing.T) {
  64. err := tc.input.Load()
  65. cstest.RequireErrorContains(t, err, tc.expectedErr)
  66. if tc.expectedErr != "" {
  67. return
  68. }
  69. assert.Equal(t, tc.expected, tc.input.Credentials)
  70. })
  71. }
  72. }
  73. func TestLoadOnlineApiClientCfg(t *testing.T) {
  74. tests := []struct {
  75. name string
  76. input *OnlineApiClientCfg
  77. expected *ApiCredentialsCfg
  78. expectedErr string
  79. }{
  80. {
  81. name: "basic valid configuration",
  82. input: &OnlineApiClientCfg{
  83. CredentialsFilePath: "./tests/online-api-secrets.yaml",
  84. },
  85. expected: &ApiCredentialsCfg{
  86. URL: "http://crowdsec.api",
  87. Login: "test",
  88. Password: "testpassword",
  89. },
  90. },
  91. {
  92. name: "invalid configuration",
  93. input: &OnlineApiClientCfg{
  94. CredentialsFilePath: "./tests/bad_lapi-secrets.yaml",
  95. },
  96. expected: &ApiCredentialsCfg{},
  97. expectedErr: "failed unmarshaling api server credentials",
  98. },
  99. {
  100. name: "missing field configuration",
  101. input: &OnlineApiClientCfg{
  102. CredentialsFilePath: "./tests/bad_online-api-secrets.yaml",
  103. },
  104. expected: nil,
  105. },
  106. {
  107. name: "invalid configuration filepath",
  108. input: &OnlineApiClientCfg{
  109. CredentialsFilePath: "./tests/nonexist_online-api-secrets.yaml",
  110. },
  111. expected: &ApiCredentialsCfg{},
  112. expectedErr: "failed to read api server credentials",
  113. },
  114. }
  115. for _, tc := range tests {
  116. tc := tc
  117. t.Run(tc.name, func(t *testing.T) {
  118. err := tc.input.Load()
  119. cstest.RequireErrorContains(t, err, tc.expectedErr)
  120. if tc.expectedErr != "" {
  121. return
  122. }
  123. assert.Equal(t, tc.expected, tc.input.Credentials)
  124. })
  125. }
  126. }
  127. func TestLoadAPIServer(t *testing.T) {
  128. tmpLAPI := &LocalApiServerCfg{
  129. ProfilesPath: "./tests/profiles.yaml",
  130. }
  131. if err := tmpLAPI.LoadProfiles(); err != nil {
  132. t.Fatalf("loading tmp profiles: %+v", err)
  133. }
  134. LogDirFullPath, err := filepath.Abs("./tests")
  135. if err != nil {
  136. t.Fatal(err)
  137. }
  138. logLevel := log.InfoLevel
  139. config := &Config{}
  140. fcontent, err := os.ReadFile("./tests/config.yaml")
  141. if err != nil {
  142. t.Fatal(err)
  143. }
  144. configData := os.ExpandEnv(string(fcontent))
  145. err = yaml.UnmarshalStrict([]byte(configData), &config)
  146. if err != nil {
  147. t.Fatal(err)
  148. }
  149. tests := []struct {
  150. name string
  151. input *Config
  152. expected *LocalApiServerCfg
  153. expectedErr string
  154. }{
  155. {
  156. name: "basic valid configuration",
  157. input: &Config{
  158. Self: []byte(configData),
  159. API: &APICfg{
  160. Server: &LocalApiServerCfg{
  161. ListenURI: "http://crowdsec.api",
  162. OnlineClient: &OnlineApiClientCfg{
  163. CredentialsFilePath: "./tests/online-api-secrets.yaml",
  164. },
  165. ProfilesPath: "./tests/profiles.yaml",
  166. PapiLogLevel: &logLevel,
  167. },
  168. },
  169. DbConfig: &DatabaseCfg{
  170. Type: "sqlite",
  171. DbPath: "./tests/test.db",
  172. },
  173. Common: &CommonCfg{
  174. LogDir: "./tests/",
  175. LogMedia: "stdout",
  176. },
  177. DisableAPI: false,
  178. },
  179. expected: &LocalApiServerCfg{
  180. Enable: types.BoolPtr(true),
  181. ListenURI: "http://crowdsec.api",
  182. TLS: nil,
  183. DbConfig: &DatabaseCfg{
  184. DbPath: "./tests/test.db",
  185. Type: "sqlite",
  186. MaxOpenConns: types.IntPtr(DEFAULT_MAX_OPEN_CONNS),
  187. },
  188. ConsoleConfigPath: DefaultConfigPath("console.yaml"),
  189. ConsoleConfig: &ConsoleConfig{
  190. ShareManualDecisions: types.BoolPtr(false),
  191. ShareTaintedScenarios: types.BoolPtr(true),
  192. ShareCustomScenarios: types.BoolPtr(true),
  193. ShareContext: types.BoolPtr(false),
  194. ConsoleManagement: types.BoolPtr(false),
  195. },
  196. LogDir: LogDirFullPath,
  197. LogMedia: "stdout",
  198. OnlineClient: &OnlineApiClientCfg{
  199. CredentialsFilePath: "./tests/online-api-secrets.yaml",
  200. Credentials: &ApiCredentialsCfg{
  201. URL: "http://crowdsec.api",
  202. Login: "test",
  203. Password: "testpassword",
  204. },
  205. },
  206. Profiles: tmpLAPI.Profiles,
  207. ProfilesPath: "./tests/profiles.yaml",
  208. UseForwardedForHeaders: false,
  209. PapiLogLevel: &logLevel,
  210. },
  211. },
  212. {
  213. name: "basic invalid configuration",
  214. input: &Config{
  215. Self: []byte(configData),
  216. API: &APICfg{
  217. Server: &LocalApiServerCfg{},
  218. },
  219. Common: &CommonCfg{
  220. LogDir: "./tests/",
  221. LogMedia: "stdout",
  222. },
  223. DisableAPI: false,
  224. },
  225. expected: &LocalApiServerCfg{
  226. PapiLogLevel: &logLevel,
  227. },
  228. expectedErr: "no database configuration provided",
  229. },
  230. }
  231. for idx, test := range tests {
  232. err := test.input.LoadAPIServer()
  233. if err == nil && test.expectedErr != "" {
  234. fmt.Printf("TEST '%s': NOK\n", test.name)
  235. t.Fatalf("Test number %d/%d expected error, didn't get it", idx+1, len(tests))
  236. } else if test.expectedErr != "" {
  237. fmt.Printf("ERR: %+v\n", err)
  238. if !strings.HasPrefix(fmt.Sprintf("%s", err), test.expectedErr) {
  239. fmt.Printf("TEST '%s': NOK\n", test.name)
  240. t.Fatalf("%d/%d expected '%s' got '%s'", idx, len(tests),
  241. test.expectedErr,
  242. fmt.Sprintf("%s", err))
  243. }
  244. assert.Equal(t, test.expected, test.input.API.Server)
  245. }
  246. }
  247. }