goss-org / goss

Quick and Easy server testing/validation
https://goss.rocks
Apache License 2.0
5.55k stars 473 forks source link

Comparing/Validating contents in file #557

Closed shan100github closed 4 years ago

shan100github commented 4 years ago

I came across below yaml configuration

matching:
  has_substr:
    content: some string
    matches:
      match-regexp: some str
  has_2:
    content:
      - 2
    matches:
      contain-element: 2
  has_foo_bar_and_baz:
    content:
      foo: bar
      baz: bing
    matches:
      and:
        - have-key-with-value:
            foo: bar
        - have-key: baz

Whether we can use something like this compare contents in apache/nginx kind of conf file.? It would be helpful to see some examples around if possible.

aelsabbahy commented 4 years ago

Can you provide an example of an input file, what a file test would look like and expected results?

shan100github commented 4 years ago

I am trying to figure out how I can convert my existing serverspec to goss.

template-j2

<VirtualHost {{ vhost }}:80>
ServerAlias     {{ alias_host }}
ErrorLog        /usr/local/apache/vhosts/{{ vhost }}/logs/error_log
CustomLog       /usr/local/apache/vhosts/{{ vhost }}/logs/access_log common
CustomLog       /usr/local/apache/vhosts/{{ vhost }}/logs/referer_log referer
RewriteCond %{REQUEST_METHOD} !^({{ rewritecon_methods | join('|')}}) 
</VirtualHost>
<Directory "/usr/local/apache/vhosts/{{ vhost }}/htdocs">
<LimitExcept {{ dir_methods | join(' ') }}>
        Require all denied
    </LimitExcept>
</Directory>

input vars

vhost: "local.dev.domain.cs"
alias_host: "local.dev.cs"
rewritecon_methods: ["POST","GET","PUT","DELETE"]
dir_methods: ["PUT","PATCH","DELETE"]

Here i need to compare these vars replaced in the actual file contents are good enough.

currently, I could figure in goss way to do is

file:
  /usr/local/apache/conf/httpd.conf:
  contents:
    - '/^<VirtualHost local.dev.domain.cs:80>$/'
    - '/^ServerAlias     local.dev.cs$/'
    - '/^ErrorLog        /usr/local/apache/vhosts/local.dev.domain.cs/logs/error_log$/'
    - '/^CustomLog       /usr/local/apache/vhosts/local.dev.domain.cs/logs/access_log common$/'
    - '/^CustomLog       /usr/local/apache/vhosts/local.dev.domain.cs/logs/referer_log referer$/'
    - '/^RewriteCond %{REQUEST_METHOD} !^(POST|GET|PUT|DELETE)$/'
    - '/^<LimitExcept PUT PATCH DELETE>$/'

like this I need to write/generate all lines for matching with the contents between file.

please let me know if any alternatives ways in goss to compare contents with the actual conf file in the environment

Below are my guess/thoughts

shan100github commented 4 years ago

Tried below goss.yaml as an alternative but the results are not good.

goss.yaml

command:
  diff:
    exit-status: 0
    exec: "diff file1 file2"
    timeout: 10000

on success

$>goss v -f tap
1..1
ok 1 - Command: diff: exit-status: matches expectation: [0]

on failure

$>goss v -f tap
1..1
not ok 1 - Command: diff: exit-status: doesn't match, expect: [0] found: [1]

on exec of diff

$>diff file1 file2
3d2
< help
shan100github commented 4 years ago

Hi @aelsabbahy,

Sorry for the noise, looking forward to getting some guidance/thoughts.

pedroMMM commented 4 years ago

@shan100github don't be sorry for the noise, we are sorry that the question went unanswered for so long...

I recreated your scenario by having 2 files /tmp/f1 and /tmp/f2 with the same content:

<VirtualHost local.dev.domain.cs:80>
ServerAlias     local.dev.cs
ErrorLog        /usr/local/apache/vhosts/local.dev.domain.cs/logs/error_log
CustomLog       /usr/local/apache/vhosts/local.dev.domain.cs/logs/access_log common
CustomLog       /usr/local/apache/vhosts/local.dev.domain.cs/logs/referer_log referer
RewriteCond %{REQUEST_METHOD} !^(POST|GET|PUT|DELETE)
</VirtualHost>
<Directory "/usr/local/apache/vhosts/local.dev.domain.cs/htdocs">
<LimitExcept PUT PATCH DELETE>
        Require all denied
    </LimitExcept>
</Directory>

Then a /tmp/goss.yaml file with:

file:
  /tmp/f1:
    exists: true
    filetype: file
    contains:
    - '<VirtualHost local.dev.domain.cs:80>'
    - 'ServerAlias     local.dev.cs'
    - 'ErrorLog        /usr/local/apache/vhosts/local.dev.domain.cs/logs/error_log'
    - 'CustomLog       /usr/local/apache/vhosts/local.dev.domain.cs/logs/access_log common'
    - 'CustomLog       /usr/local/apache/vhosts/local.dev.domain.cs/logs/referer_log referer'
    - 'RewriteCond %{REQUEST_METHOD} !^(POST|GET|PUT|DELETE)'
    - '<LimitExcept PUT PATCH DELETE>'

command:
  diff /tmp/f1 /tmp/f2:
    exit-status: 0

My output:

vagrant@ubuntu-bionic:/tmp$ goss v
....

Total Duration: 0.002s
Count: 4, Failed: 0, Skipped: 0

For a bit more context you can find in the manual the list of available tests.

For the 1st test, I used the file test, this test uses pattern matching

Please let me know if you have any questions.

shan100github commented 4 years ago

hi @pedroMMM , For test purpose & easy understanding, I made this small file. Actual file contents vary and maybe sometimes around 100 lines or 50 lines etc. It doesn't look easy to provide the pattern matching contents for each line for my scenario.

So currently using something like

command:
  diff:
    exit-status: 0
    exec: "diff /tmp/file1 /tmp/file2"

during success scenario it's fine, but during failures, not many details are displayed :(

on failure

$>goss v -f tap
1..1
not ok 1 - Command: diff: exit-status: doesn't match, expect: [0] found: [1]

on exec of diff linux command execution

$>diff /tmp/file1 /tmp/file2
2c2
< am in file1
---
> am in file2

it would be good if Linux command output is displayed part of goss command execution in the future or any better alternatives.

Anyway, am happy that the time being I am using goss command testing.

pedroMMM commented 4 years ago

@shan100github on my use cases I use the Goss file tests to match important configurations that were either introduced or removed if that helps you. Based on what I have understood it doesn't really apply to your use case but I thought I should share anyway.

it would be good if Linux command output is displayed part of goss command execution in the future or any better alternatives.

That is a good idea if you may create a feature request because I should help other users in the future.

shan100github commented 4 years ago

No problem. Already using goss file - pattern matching too. Sure let me raise a future request for

it would be good if Linux command output is displayed part of goss command execution in the future or any better alternatives.

thank you @pedroMMM

shan100github commented 4 years ago

created feature request https://github.com/aelsabbahy/goss/issues/559.