github.com/crowdsecurity/crowdsec@v1.6.1/test/bats/07_setup.bats (about)

     1  #!/usr/bin/env bats
     2  # vim: ft=bats:list:ts=8:sts=4:sw=4:et:ai:si:
     3  
     4  set -u
     5  
     6  setup_file() {
     7      load "../lib/setup_file.sh"
     8      ./instance-data load
     9      HUB_DIR=$(config_get '.config_paths.hub_dir')
    10      # remove trailing slash if any (like in default config.yaml from package)
    11      HUB_DIR=${HUB_DIR%/}
    12      export HUB_DIR
    13      DETECT_YAML="${HUB_DIR}/detect.yaml"
    14      export DETECT_YAML
    15      # shellcheck disable=SC2154
    16      TESTDATA="${BATS_TEST_DIRNAME}/testdata/07_setup"
    17      export TESTDATA
    18  
    19      export CROWDSEC_FEATURE_CSCLI_SETUP="true"
    20  }
    21  
    22  teardown_file() {
    23      load "../lib/teardown_file.sh"
    24  }
    25  
    26  setup() {
    27      load "../lib/setup.sh"
    28      load "../lib/bats-file/load.bash"
    29      load "../lib/bats-mock/load.bash"
    30      ./instance-data load
    31  }
    32  
    33  teardown() {
    34      ./instance-crowdsec stop
    35  }
    36  
    37  #----------
    38  
    39  #shellcheck disable=SC2154
    40  @test "cscli setup" {
    41      rune -0 cscli help
    42      assert_line --regexp '^ +setup +Tools to configure crowdsec$'
    43  
    44      rune -0 cscli setup --help
    45      assert_line 'Usage:'
    46      assert_line '  cscli setup [command]'
    47      assert_line 'Manage hub configuration and service detection'
    48      assert_line --partial "detect                  detect running services, generate a setup file"
    49      assert_line --partial "datasources             generate datasource (acquisition) configuration from a setup file"
    50      assert_line --partial "install-hub             install items from a setup file"
    51      assert_line --partial "validate                validate a setup file"
    52  
    53      # cobra should return error for non-existing sub-subcommands, but doesn't
    54      rune -0 cscli setup blahblah
    55      assert_line 'Usage:'
    56  }
    57  
    58  @test "cscli setup detect --help; --detect-config" {
    59      rune -0 cscli setup detect --help
    60      assert_line --regexp "detect running services, generate a setup file"
    61      assert_line 'Usage:'
    62      assert_line '  cscli setup detect [flags]'
    63      assert_line --partial "--detect-config string      path to service detection configuration (default \"${HUB_DIR}/detect.yaml\")"
    64      assert_line --partial "--force-process strings     force detection of a running process (can be repeated)"
    65      assert_line --partial "--force-unit strings        force detection of a systemd unit (can be repeated)"
    66      assert_line --partial "--list-supported-services   do not detect; only print supported services"
    67      assert_line --partial "--force-os-family string    override OS.Family: one of linux, freebsd, windows or darwin"
    68      assert_line --partial "--force-os-id string        override OS.ID=[debian | ubuntu | , redhat...]"
    69      assert_line --partial "--force-os-version string   override OS.RawVersion (of OS or Linux distribution)"
    70      assert_line --partial "--skip-service strings      ignore a service, don't recommend hub/datasources (can be repeated)"
    71  
    72      rune -1 cscli setup detect --detect-config /path/does/not/exist
    73      assert_stderr --partial "open /path/does/not/exist: no such file or directory"
    74  
    75      # - is stdin
    76      rune -1 cscli setup detect --detect-config - <<< "{}"
    77      assert_stderr --partial "detecting services: missing version tag (must be 1.0)"
    78  
    79      # rm -f "${HUB_DIR}/detect.yaml"
    80  }
    81  
    82  @test "cscli setup detect (linux), --skip-service" {
    83      [[ ${OSTYPE} =~ linux.* ]] || skip
    84      tempfile=$(TMPDIR="$BATS_TEST_TMPDIR" mktemp)
    85      cat <<-EOT >"${tempfile}"
    86  	version: 1.0
    87  	detect:
    88  	  linux:
    89  	    when:
    90  	      - OS.Family == "linux"
    91  	    install:
    92  	      collections:
    93  	        - crowdsecurity/linux
    94  	  thewiz:
    95  	    when:
    96  	      - OS.Family != "linux"
    97  	  foobarbaz:
    98  	EOT
    99  
   100      rune -0 cscli setup detect --detect-config "$tempfile"
   101      assert_json '{setup:[{detected_service:"foobarbaz"},{detected_service:"linux",install:{collections:["crowdsecurity/linux"]}}]}'
   102  
   103      rune -0 cscli setup detect --detect-config "$tempfile" --skip-service linux
   104      assert_json '{setup:[{detected_service:"foobarbaz"}]}'
   105  }
   106  
   107  @test "cscli setup detect --force-os-*" {
   108      rune -0 cscli setup detect --force-os-family linux --detect-config "${TESTDATA}/detect.yaml"
   109      rune -0 jq -cS '.setup[] | select(.detected_service=="linux")' <(output)
   110      assert_json '{detected_service:"linux",install:{collections:["crowdsecurity/linux"]},datasource:{source:"file",labels:{type:"syslog"},filenames:["/var/log/syslog","/var/log/kern.log","/var/log/messages"]}}'
   111  
   112      rune -0 cscli setup detect --force-os-family freebsd --detect-config "${TESTDATA}/detect.yaml"
   113      rune -0 jq -cS '.setup[] | select(.detected_service=="freebsd")' <(output)
   114      assert_json '{detected_service:"freebsd",install:{collections:["crowdsecurity/freebsd"]}}'
   115  
   116      rune -0 cscli setup detect --force-os-family windows --detect-config "${TESTDATA}/detect.yaml"
   117      rune -0 jq -cS '.setup[] | select(.detected_service=="windows")' <(output)
   118      assert_json '{detected_service:"windows",install:{collections:["crowdsecurity/windows"]}}'
   119  
   120      rune -0 cscli setup detect --force-os-family darwin --detect-config "${TESTDATA}/detect.yaml"
   121  
   122      # XXX do we want do disallow unknown family?
   123      # assert_stderr --partial "detecting services: OS 'darwin' not supported"
   124  
   125      # XXX TODO force-os-id, force-os-version
   126  }
   127  
   128  @test "cscli setup detect --list-supported-services" {
   129      tempfile=$(TMPDIR="$BATS_TEST_TMPDIR" mktemp)
   130      cat <<-EOT >"${tempfile}"
   131  	version: 1.0
   132  	detect:
   133  	  thewiz:
   134  	  foobarbaz:
   135  	  apache2:
   136  	EOT
   137  
   138      rune -0 cscli setup detect --list-supported-services --detect-config "$tempfile"
   139      # the service list is sorted
   140      assert_output - <<-EOT
   141  	apache2
   142  	foobarbaz
   143  	thewiz
   144  	EOT
   145  
   146      cat <<-EOT >"${tempfile}"
   147  	thisisajoke
   148  	EOT
   149  
   150      rune -1 cscli setup detect --list-supported-services --detect-config "$tempfile"
   151      assert_stderr --partial "yaml: unmarshal errors:"
   152  
   153      rm -f "$tempfile"
   154  }
   155  
   156  @test "cscli setup detect (systemctl)" {
   157      cat <<-EOT >"${DETECT_YAML}"
   158  	version: 1.0
   159  	detect:
   160  	  apache2:
   161  	    when:
   162  	      - UnitFound("mock-apache2.service")
   163  	    datasource:
   164  	      source: file
   165  	      filename: dummy.log
   166  	      labels:
   167  	        type: apache2
   168  	EOT
   169  
   170      # transparently mock systemctl. It's easier if you can tell the application
   171      # under test which executable to call (in which case just call $mock) but
   172      # here we do the symlink and $PATH dance as an example
   173      mocked_command="systemctl"
   174  
   175      # mock setup
   176      mock="$(mock_create)"
   177      mock_path="${mock%/*}"
   178      mock_file="${mock##*/}"
   179      ln -sf "${mock_path}/${mock_file}" "${mock_path}/${mocked_command}"
   180  
   181      #shellcheck disable=SC2030
   182      PATH="${mock_path}:${PATH}"
   183  
   184      mock_set_output "$mock" \
   185  'UNIT FILE                               STATE   VENDOR PRESET
   186  snap-bare-5.mount                       enabled enabled
   187  snap-core-13308.mount                   enabled enabled
   188  snap-firefox-1635.mount                 enabled enabled
   189  snap-fx-158.mount                       enabled enabled
   190  snap-gimp-393.mount                     enabled enabled
   191  snap-gtk\x2dcommon\x2dthemes-1535.mount enabled enabled
   192  snap-kubectl-2537.mount                 enabled enabled
   193  snap-rustup-1027.mount                  enabled enabled
   194  cups.path                               enabled enabled
   195  console-setup.service                   enabled enabled
   196  dmesg.service                           enabled enabled
   197  getty@.service                          enabled enabled
   198  grub-initrd-fallback.service            enabled enabled
   199  irqbalance.service                      enabled enabled
   200  keyboard-setup.service                  enabled enabled
   201  mock-apache2.service                    enabled enabled
   202  networkd-dispatcher.service             enabled enabled
   203  ua-timer.timer                          enabled enabled
   204  update-notifier-download.timer          enabled enabled
   205  update-notifier-motd.timer              enabled enabled
   206  
   207  20 unit files listed.'
   208      mock_set_status "$mock" 1 2
   209  
   210      rune -0 cscli setup detect
   211      rune -0 jq -c '.setup' <(output)
   212  
   213      # If a call to UnitFoundwas part of the expression and it returned true,
   214      # there is a default journalctl_filter derived from the unit's name.
   215      assert_json '[{datasource:{source:"file",filename:"dummy.log",labels:{type:"apache2"}},detected_service:"apache2"}]'
   216  
   217      # the command was called exactly once
   218      [[ $(mock_get_call_num "$mock") -eq 1 ]]
   219  
   220      # the command was called with the expected parameters
   221      [[ $(mock_get_call_args "$mock" 1) == "list-unit-files --state=enabled,generated,static" ]]
   222  
   223      rune -1 systemctl
   224  
   225      # mock teardown
   226      unlink "${mock_path}/${mocked_command}"
   227      PATH="${PATH/${mock_path}:/}"
   228  }
   229  
   230  # XXX this is the same boilerplate as the previous test, can be simplified
   231  @test "cscli setup detect (snub systemd)" {
   232      cat <<-EOT >"${DETECT_YAML}"
   233  	version: 1.0
   234  	detect:
   235  	  apache2:
   236  	    when:
   237  	      - UnitFound("mock-apache2.service")
   238  	    datasource:
   239  	      source: file
   240  	      filename: dummy.log
   241  	      labels:
   242  	        type: apache2
   243  	EOT
   244  
   245      # transparently mock systemctl. It's easier if you can tell the application
   246      # under test which executable to call (in which case just call $mock) but
   247      # here we do the symlink and $PATH dance as an example
   248      mocked_command="systemctl"
   249  
   250      # mock setup
   251      mock="$(mock_create)"
   252      mock_path="${mock%/*}"
   253      mock_file="${mock##*/}"
   254      ln -sf "${mock_path}/${mock_file}" "${mock_path}/${mocked_command}"
   255  
   256      #shellcheck disable=SC2031
   257      PATH="${mock_path}:${PATH}"
   258  
   259      # we don't really care about the output, it's not used anyway
   260      mock_set_output "$mock" ""
   261      mock_set_status "$mock" 1 2
   262  
   263      rune -0 cscli setup detect --snub-systemd
   264  
   265      # setup must not be 'null', but an empty list
   266      assert_json '{setup:[]}'
   267  
   268      # the command was never called
   269      [[ $(mock_get_call_num "$mock") -eq 0 ]]
   270  
   271      rune -0 systemctl
   272  
   273      # mock teardown
   274      unlink "${mock_path}/${mocked_command}"
   275      PATH="${PATH/${mock_path}:/}"
   276  }
   277  
   278  @test "cscli setup detect --force-unit" {
   279      cat <<-EOT >"${DETECT_YAML}"
   280  	version: 1.0
   281  	detect:
   282  	  apache2:
   283  	    when:
   284  	      - UnitFound("force-apache2")
   285  	    datasource:
   286  	      source: file
   287  	      filename: dummy.log
   288  	      labels:
   289  	        type: apache2
   290  	  apache3:
   291  	    when:
   292  	      - UnitFound("force-apache3")
   293  	    datasource:
   294  	      source: file
   295  	      filename: dummy.log
   296  	      labels:
   297  	        type: apache3
   298  	EOT
   299  
   300      rune -0 cscli setup detect --force-unit force-apache2
   301      rune -0 jq -cS '.setup' <(output)
   302      assert_json '[{datasource:{source:"file",filename:"dummy.log",labels:{"type":"apache2"}},detected_service:"apache2"}]'
   303  
   304      rune -0 cscli setup detect --force-unit force-apache2,force-apache3
   305      rune -0 jq -cS '.setup' <(output)
   306      assert_json '[{datasource:{source:"file",filename:"dummy.log",labels:{type:"apache2"}},detected_service:"apache2"},{datasource:{source:"file",filename:"dummy.log",labels:{"type":"apache3"}},detected_service:"apache3"}]'
   307  
   308      # force-unit can be specified multiple times, the order does not matter
   309      rune -0 cscli setup detect --force-unit force-apache3 --force-unit force-apache2
   310      rune -0 jq -cS '.setup' <(output)
   311      assert_json '[{datasource:{source:"file",filename:"dummy.log",labels:{type:"apache2"}},detected_service:"apache2"},{datasource:{source:"file",filename:"dummy.log",labels:{type:"apache3"}},detected_service:"apache3"}]'
   312  
   313      rune -1 cscli setup detect --force-unit mock-doesnotexist
   314      assert_stderr --partial "detecting services: unit(s) forced but not supported: [mock-doesnotexist]"
   315  }
   316  
   317  @test "cscli setup detect (process)" {
   318      # This is harder to mock, because gopsutil requires proc/ to be a mount
   319      # point. So we pick a process that exists for sure.
   320      expected_process=cscli
   321  
   322      cat <<-EOT >"${DETECT_YAML}"
   323  	version: 1.0
   324  	detect:
   325  	  apache2:
   326  	    when:
   327  	      - ProcessRunning("${expected_process}")
   328  	  apache3:
   329  	    when:
   330  	      - ProcessRunning("this-does-not-exist")
   331  	EOT
   332  
   333      rune -0 cscli setup detect
   334      rune -0 jq -cS '.setup' <(output)
   335      assert_json '[{detected_service:"apache2"}]'
   336  }
   337  
   338  @test "cscli setup detect --force-process" {
   339      cat <<-EOT >"${DETECT_YAML}"
   340  	version: 1.0
   341  	detect:
   342  	  apache2:
   343  	    when:
   344  	      - ProcessRunning("force-apache2")
   345  	  apache3:
   346  	    when:
   347  	      - ProcessRunning("this-does-not-exist")
   348  	EOT
   349  
   350      rune -0 cscli setup detect --force-process force-apache2
   351      rune -0 jq -cS '.setup' <(output)
   352      assert_json '[{detected_service:"apache2"}]'
   353  }
   354  
   355  @test "cscli setup detect (acquisition only, no hub items)" {
   356      cat <<-EOT >"${DETECT_YAML}"
   357  	version: 1.0
   358  	detect:
   359  	  apache2:
   360  	    when:
   361  	      - UnitFound("force-apache2")
   362  	    datasource:
   363  	      source: file
   364  	      filename: dummy.log
   365  	      labels:
   366  	        type: apache2
   367  	EOT
   368  
   369      rune -0 cscli setup detect --force-unit force-apache2
   370      rune -0 jq -cS '.setup' <(output)
   371      assert_json '[{datasource:{source:"file",filename:"dummy.log",labels:{type:"apache2"}},detected_service:"apache2"}]'
   372  
   373      rune -0 cscli setup detect --force-unit force-apache2 --yaml
   374      assert_output - <<-EOT
   375  	setup:
   376  	  - detected_service: apache2
   377  	    datasource:
   378  	      filename: dummy.log
   379  	      labels:
   380  	        type: apache2
   381  	      source: file
   382  	EOT
   383  }
   384  
   385  @test "cscli setup detect (full acquisition section)" {
   386      skip "not supported yet"
   387      cat <<-EOT >"${DETECT_YAML}"
   388  	version: 1.0
   389  	detect:
   390  	  foobar:
   391              datasource:
   392                filenames:
   393                  - /path/to/log/*.log
   394                exclude_regexps:
   395                  - ^/path/to/log/excludeme\.log$
   396                force_inotify: true
   397                mode: tail
   398                labels:
   399                  type: foolog
   400  	EOT
   401  
   402      rune -0 cscli setup detect --yaml
   403      assert_output - <<-EOT
   404  	setup:
   405  	  - detected_service: foobar
   406  	    datasource:
   407                filenames:
   408                  - /path/to/log/*.log
   409                exclude_regexps:
   410                  - ^/path/to/log/excludeme.log$
   411                force_inotify: true
   412                mode: tail
   413                labels:
   414                  type: foolog
   415  	EOT
   416  }
   417  
   418  @test "cscli setup detect + acquis + install (no acquisition, no hub items)" {
   419      # no-op edge case, to make sure we don't crash
   420      cat <<-EOT >"${DETECT_YAML}"
   421  	version: 1.0
   422  	detect:
   423  	  always:
   424  	EOT
   425  
   426      rune -0 cscli setup detect
   427      assert_json '{setup:[{detected_service:"always"}]}'
   428      setup=$output
   429      rune -0 cscli setup datasources /dev/stdin <<<"$setup"
   430      rune -0 cscli setup install-hub /dev/stdin <<<"$setup"
   431  }
   432  
   433  @test "cscli setup detect (with collections)" {
   434      cat <<-EOT >"${DETECT_YAML}"
   435  	version: 1.0
   436  	detect:
   437  	  foobar:
   438  	    when:
   439  	      - ProcessRunning("force-foobar")
   440  	    install:
   441  	      collections:
   442  	        - crowdsecurity/foobar
   443  	  qox:
   444  	    when:
   445  	      - ProcessRunning("test-qox")
   446  	    install:
   447  	      collections:
   448  	        - crowdsecurity/foobar
   449  	  apache2:
   450  	    when:
   451  	      - ProcessRunning("force-apache2")
   452  	    install:
   453  	      collections:
   454  	        - crowdsecurity/apache2
   455  	EOT
   456  
   457      rune -0 cscli setup detect --force-process force-apache2,force-foobar
   458      rune -0 jq -Sc '.setup | sort' <(output)
   459      assert_json '[{install:{collections:["crowdsecurity/apache2"]},detected_service:"apache2"},{install:{collections:["crowdsecurity/foobar"]},detected_service:"foobar"}]'
   460  }
   461  
   462  @test "cscli setup detect (with acquisition)" {
   463      cat <<-EOT >"${DETECT_YAML}"
   464  	version: 1.0
   465  	detect:
   466  	  foobar:
   467  	    when:
   468  	      - ProcessRunning("force-foobar")
   469  	    datasource:
   470  	      source: file
   471  	      labels:
   472  	        type: foobar
   473  	      filenames:
   474  	        - /var/log/apache2/*.log
   475  	        - /var/log/*http*/*.log
   476  	EOT
   477  
   478      rune -0 cscli setup detect --force-process force-foobar
   479      rune -0 yq -op '.setup | sort_keys(..)' <(output)
   480      assert_output - <<-EOT
   481  	0.datasource.filenames.0 = /var/log/apache2/*.log
   482  	0.datasource.filenames.1 = /var/log/*http*/*.log
   483  	0.datasource.labels.type = foobar
   484  	0.datasource.source = file
   485  	0.detected_service = foobar
   486  	EOT
   487  
   488      rune -1 cscli setup detect --force-process mock-doesnotexist
   489      assert_stderr --partial "detecting services: process(es) forced but not supported: [mock-doesnotexist]"
   490  }
   491  
   492  @test "cscli setup detect (datasource validation)" {
   493      cat <<-EOT >"${DETECT_YAML}"
   494  	version: 1.0
   495  	detect:
   496  	  foobar:
   497  	    datasource:
   498                labels:
   499                  type: something
   500  	EOT
   501  
   502      rune -1 cscli setup detect
   503      assert_stderr --partial "detecting services: invalid datasource for foobar: source is empty"
   504  
   505      # more datasource-specific tests are in detect_test.go
   506  }
   507  
   508  @test "cscli setup install-hub (dry run)" {
   509      # it's not installed
   510      rune -0 cscli collections inspect crowdsecurity/apache2 -o json
   511      rune -0 jq -e '.installed == false' <(output)
   512  
   513      # we install it
   514      rune -0 cscli setup install-hub /dev/stdin --dry-run <<< '{"setup":[{"install":{"collections":["crowdsecurity/apache2"]}}]}'
   515      assert_output 'dry-run: would install collection crowdsecurity/apache2'
   516  
   517      # still not installed
   518      rune -0 cscli collections inspect crowdsecurity/apache2 -o json
   519      rune -0 jq -e '.installed == false' <(output)
   520  
   521      # same with dependencies
   522      rune -0 cscli collections remove --all
   523      rune -0 cscli setup install-hub /dev/stdin --dry-run <<< '{"setup":[{"install":{"collections":["crowdsecurity/linux"]}}]}'
   524      assert_output 'dry-run: would install collection crowdsecurity/linux'
   525  }
   526  
   527  @test "cscli setup install-hub (dry run: install multiple collections)" {
   528      # it's not installed
   529      rune -0 cscli collections inspect crowdsecurity/apache2 -o json
   530      rune -0 jq -e '.installed == false' <(output)
   531  
   532      # we install it
   533      rune -0 cscli setup install-hub /dev/stdin --dry-run <<< '{"setup":[{"install":{"collections":["crowdsecurity/apache2"]}}]}'
   534      assert_output 'dry-run: would install collection crowdsecurity/apache2'
   535  
   536      # still not installed
   537      rune -0 cscli collections inspect crowdsecurity/apache2 -o json
   538      rune -0 jq -e '.installed == false' <(output)
   539  }
   540  
   541  @test "cscli setup install-hub (dry run: install multiple collections, parsers, scenarios, postoverflows)" {
   542      rune -0 cscli setup install-hub /dev/stdin --dry-run <<< '{"setup":[{"install":{"collections":["crowdsecurity/aws-console","crowdsecurity/caddy"],"parsers":["crowdsecurity/asterisk-logs"],"scenarios":["crowdsecurity/smb-fs"],"postoverflows":["crowdsecurity/cdn-whitelist","crowdsecurity/rdns"]}}]}'
   543      assert_line 'dry-run: would install collection crowdsecurity/aws-console'
   544      assert_line 'dry-run: would install collection crowdsecurity/caddy'
   545      assert_line 'dry-run: would install parser crowdsecurity/asterisk-logs'
   546      assert_line 'dry-run: would install scenario crowdsecurity/smb-fs'
   547      assert_line 'dry-run: would install postoverflow crowdsecurity/cdn-whitelist'
   548      assert_line 'dry-run: would install postoverflow crowdsecurity/rdns'
   549  
   550      rune -1 cscli setup install-hub /dev/stdin --dry-run <<< '{"setup":[{"install":{"collections":["crowdsecurity/foo"]}}]}'
   551      assert_stderr --partial 'collection crowdsecurity/foo not found'
   552  
   553  }
   554  
   555  @test "cscli setup datasources" {
   556      rune -0 cscli setup datasources --help
   557      assert_line --partial "--to-dir string   write the configuration to a directory, in multiple files"
   558  
   559      # single item
   560  
   561      rune -0 cscli setup datasources /dev/stdin <<-EOT
   562  	setup:
   563  	  - datasource:
   564  	      source: file
   565  	      labels:
   566  	        type: syslog
   567  	      filenames:
   568  	        - /var/log/apache2/*.log
   569  	        - /var/log/*http*/*.log
   570  	        - /var/log/httpd/*.log
   571  	EOT
   572  
   573      # remove diclaimer
   574      rune -0 yq '. head_comment=""' <(output)
   575      assert_output - <<-EOT
   576  	filenames:
   577  	  - /var/log/apache2/*.log
   578  	  - /var/log/*http*/*.log
   579  	  - /var/log/httpd/*.log
   580  	labels:
   581  	  type: syslog
   582  	source: file
   583  	EOT
   584  
   585      # multiple items
   586  
   587      rune -0 cscli setup datasources /dev/stdin <<-EOT
   588  	setup:
   589  	  - datasource:
   590  	      labels:
   591  	        type: syslog
   592  	      filenames:
   593  	        - /var/log/apache2/*.log
   594  	        - /var/log/*http*/*.log
   595  	        - /var/log/httpd/*.log
   596  	  - datasource:
   597  	      labels:
   598  	        type: foobar
   599  	      filenames:
   600  	        - /var/log/foobar/*.log
   601  	  - datasource:
   602  	      labels:
   603  	        type: barbaz
   604  	      filenames:
   605  	        - /path/to/barbaz.log
   606  	EOT
   607  
   608      rune -0 yq '. head_comment=""' <(output)
   609      assert_output - <<-EOT
   610  	filenames:
   611  	  - /var/log/apache2/*.log
   612  	  - /var/log/*http*/*.log
   613  	  - /var/log/httpd/*.log
   614  	labels:
   615  	  type: syslog
   616  	---
   617  	filenames:
   618  	  - /var/log/foobar/*.log
   619  	labels:
   620  	  type: foobar
   621  	---
   622  	filenames:
   623  	  - /path/to/barbaz.log
   624  	labels:
   625  	  type: barbaz
   626  	EOT
   627  
   628      # multiple items, to a directory
   629  
   630      # avoid the BATS_TEST_TMPDIR variable, it can have a double //
   631      acquisdir=$(TMPDIR="$BATS_FILE_TMPDIR" mktemp -u)
   632      mkdir "$acquisdir"
   633  
   634      rune -0 cscli setup datasources /dev/stdin --to-dir "$acquisdir" <<-EOT
   635  	setup:
   636  	  - detected_service: apache2
   637  	    datasource:
   638  	      labels:
   639  	        type: syslog
   640  	      filenames:
   641  	        - /var/log/apache2/*.log
   642  	        - /var/log/*http*/*.log
   643  	        - /var/log/httpd/*.log
   644  	  - detected_service: foobar
   645  	    datasource:
   646  	      labels:
   647  	        type: foobar
   648  	      filenames:
   649  	        - /var/log/foobar/*.log
   650  	  - detected_service: barbaz
   651  	    datasource:
   652  	      labels:
   653  	        type: barbaz
   654  	      filenames:
   655  	        - /path/to/barbaz.log
   656  	EOT
   657  
   658      # XXX what if detected_service is missing?
   659  
   660      rune -0 cat "${acquisdir}/setup.apache2.yaml"
   661      rune -0 yq '. head_comment=""' <(output)
   662      assert_output - <<-EOT
   663  	filenames:
   664  	  - /var/log/apache2/*.log
   665  	  - /var/log/*http*/*.log
   666  	  - /var/log/httpd/*.log
   667  	labels:
   668  	  type: syslog
   669  	EOT
   670  
   671      rune -0 cat "${acquisdir}/setup.foobar.yaml"
   672      rune -0 yq '. head_comment=""' <(output)
   673      assert_output - <<-EOT
   674  	filenames:
   675  	  - /var/log/foobar/*.log
   676  	labels:
   677  	  type: foobar
   678  	EOT
   679  
   680      rune -0 cat "${acquisdir}/setup.barbaz.yaml"
   681      rune -0 yq '. head_comment=""' <(output)
   682      assert_output - <<-EOT
   683  	filenames:
   684  	  - /path/to/barbaz.log
   685  	labels:
   686  	  type: barbaz
   687  	EOT
   688  
   689      rm -rf -- "${acquisdir:?}"
   690      mkdir "$acquisdir"
   691  
   692      # having both filenames and journalctl does not generate two files: the datasource is copied as-is, even if incorrect
   693  
   694      rune -0 cscli setup datasources /dev/stdin --to-dir "$acquisdir" <<-EOT
   695  	setup:
   696  	  - detected_service: apache2
   697  	    install:
   698  	      collections:
   699  	        - crowdsecurity/apache2
   700  	    datasource:
   701  	      labels:
   702  	        type: apache2
   703  	      filenames:
   704  	        - /var/log/apache2/*.log
   705  	        - /var/log/*http*/*.log
   706  	        - /var/log/httpd/*.log
   707  	      journalctl_filter:
   708  	        - _SYSTEMD_UNIT=apache2.service
   709  	EOT
   710  
   711      rune -0 cat "${acquisdir}/setup.apache2.yaml"
   712      rune -0 yq '. head_comment=""' <(output)
   713      assert_output - <<-EOT
   714  	filenames:
   715  	  - /var/log/apache2/*.log
   716  	  - /var/log/*http*/*.log
   717  	  - /var/log/httpd/*.log
   718  	journalctl_filter:
   719  	  - _SYSTEMD_UNIT=apache2.service
   720  	labels:
   721  	  type: apache2
   722  	EOT
   723  
   724      # the directory must exist
   725      rune -1 cscli setup datasources /dev/stdin --to-dir /path/does/not/exist <<< '{}'
   726      assert_stderr --partial "directory /path/does/not/exist does not exist"
   727  
   728      # of course it must be a directory
   729  
   730      touch "${acquisdir}/notadir"
   731  
   732      rune -1 cscli setup datasources /dev/stdin --to-dir "${acquisdir}/notadir" <<-EOT
   733  	setup:
   734  	  - detected_service: apache2
   735  	    datasource:
   736  	      filenames:
   737  	        - /var/log/apache2/*.log
   738  	EOT
   739      assert_stderr --partial "open ${acquisdir}/notadir/setup.apache2.yaml: not a directory"
   740  
   741      rm -rf -- "${acquisdir:?}"
   742  }
   743  
   744  @test "cscli setup datasources (disclaimer)" {
   745      disclaimer="This file was automatically generated"
   746  
   747      rune -0 cscli setup datasources /dev/stdin <<<"setup:"
   748      rune -0 yq 'head_comment' <(output)
   749      assert_output --partial "$disclaimer"
   750  
   751      rune -0 cscli setup datasources /dev/stdin <<-EOT
   752  	setup:
   753            - detected_service: something
   754              datasource:
   755                labels:
   756                  type: syslog
   757                filenames:
   758                  - /var/log/something.log
   759  	EOT
   760      rune -0 yq 'head_comment' <(output)
   761      assert_output --partial "$disclaimer"
   762  }
   763  
   764  @test "cscli setup (custom journalctl filter)" {
   765      tempfile=$(TMPDIR="$BATS_TEST_TMPDIR" mktemp)
   766      cat <<-EOT >"${tempfile}"
   767  	version: 1.0
   768  	detect:
   769  	  thewiz:
   770  	    when:
   771  	      - UnitFound("thewiz.service")
   772  	    datasource:
   773  	      source: journalctl
   774  	      labels:
   775  	        type: thewiz
   776  	      journalctl_filter:
   777  	        - "SYSLOG_IDENTIFIER=TheWiz"
   778  	EOT
   779  
   780      rune -0 cscli setup detect --detect-config "$tempfile" --force-unit thewiz.service
   781      rune -0 jq -cS '.' <(output)
   782      assert_json '{setup:[{datasource:{source:"journalctl",journalctl_filter:["SYSLOG_IDENTIFIER=TheWiz"],labels:{type:"thewiz"}},detected_service:"thewiz"}]}'
   783      rune -0 cscli setup datasources <(output)
   784      rune -0 yq '. head_comment=""' <(output)
   785      assert_output - <<-EOT
   786  	journalctl_filter:
   787  	  - SYSLOG_IDENTIFIER=TheWiz
   788  	labels:
   789  	  type: thewiz
   790  	source: journalctl
   791  	EOT
   792  
   793      rm -f "$tempfile"
   794  }
   795  
   796  @test "cscli setup validate" {
   797      # an empty file is not enough
   798      rune -1 cscli setup validate /dev/null
   799      assert_output "EOF"
   800      assert_stderr --partial "invalid setup file"
   801  
   802      # this is ok; install nothing
   803      rune -0 cscli setup validate /dev/stdin <<-EOT
   804  	setup:
   805  	EOT
   806      refute_output
   807  
   808      rune -1 cscli setup validate /dev/stdin <<-EOT
   809  	se tup:
   810  	EOT
   811      assert_output - <<-EOT
   812  	[1:1] unknown field "se tup"
   813  	>  1 | se tup:
   814  	       ^
   815  	EOT
   816      assert_stderr --partial "invalid setup file"
   817  
   818      rune -1 cscli setup validate /dev/stdin <<-EOT
   819  	setup:
   820  	alsdk al; sdf
   821  	EOT
   822      assert_output "while unmarshaling setup file: yaml: line 2: could not find expected ':'"
   823      assert_stderr --partial "invalid setup file"
   824  }
   825