Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Idea: configuration assertions #4537

Open
simon04 opened this issue Jan 19, 2022 · 3 comments
Open

Idea: configuration assertions #4537

simon04 opened this issue Jan 19, 2022 · 3 comments
Labels
discussion 💬 The right solution needs to be found feature ⚙️ New feature or request
Milestone

Comments

@simon04
Copy link
Contributor

simon04 commented Jan 19, 2022

Very often the desired functionality of a webserver configuration is clear. When a user accesses the URL 1, she should get the file X from /var/foo. The URL 2 is proxies to the backend URL 3 and headers Y and Z are added.

Correctly configuring the webserver is more challenging. As a non-expert in caddy, one has to try multiple configurations and debug the proxy backend requests.

Can we add a configuration directive assert request_matcher response_matcher (using matchers)? Those assertions would be checked after parsing/loading the configuration. Some vague examples:

example.com {
  root /var/foo
  reverse_proxy /api/* localhost:9005 {
    header_up Foo "Bar"
  }
  assert https://example.com/cat.jpg file:/var/foo/cat.jpg
  assert https://example.com/does-not-exist { status_code 404 }
  assert https://example.com/api/ping { reverse_proxy http://localhost:9005/ping; header Foo "Bar" }
}

What you you think?
Thanks!

@mholt mholt added discussion 💬 The right solution needs to be found feature ⚙️ New feature or request labels Jan 19, 2022
@francislavoie
Copy link
Member

Interesting idea.

In theory this would probably run during the Validate() phase (see the lifecycle here: https://caddyserver.com/docs/architecture#module-lifecycle). But the trouble is that some of those assertions are only possible once the app is actually Start()ed because the HTTP app only binds to ports when starting, not when provisioning/validating.

So for example the caddy validate command could not run these assertions, they would need to happen right at the end of the HTTP app's Start() and maybe return an error if any of them fail.

Another thing is that asserting an https:// request would probably almost always fail on first run, because Caddy fetches certificates from ACME issuers asynchronously, so it would likely not have the certificate yet to be able to make an HTTPS connection to itself.

Also I think for this to be robust, we would need to be able to craft any kind of request, because request matching isn't simply by URL, it also matters what HTTP method is used, headers, sometimes body, etc. So the syntax might need to be something like this:

assert {
	request {
		method <method>
		uri <uri>
		header <field> <value>
		body <body>
	}
	response {
		status <status>
		header <field> <value>
	}
}

To me, this seems like it would be pretty complex overall, not sure we want the maintenance burden. This could be implemented as a plugin, but admittedly it would be less useful if it's not included in the standard distribution of Caddy, since users would have to go out of their way to add it to a custom build.

@mholt
Copy link
Member

mholt commented Jan 20, 2022

Nice idea, I had a similar idea while writing Caddy 2 a couple years ago but decided to shelve it until the project was more mature and I had more time (like that'll happen)... OR until a customer needs it and pays for it. 😁

I think a more wholistic solution is to have tests that Caddy runs during config reloads. Any time the config is loaded, it runs tests defined ... somewhere/somehow ... and if the tests fail with the new config, it rolls back to the previous config.

I don't think defining the tests in the config file is going to be flexible enough. I envision a separate assertion file and API endpoints for this.

@mholt
Copy link
Member

mholt commented Apr 20, 2022

Second guessing the notion that a separate API or assertions file is needed. Maybe it should all go within one big config document. Hmmmm. Will need to evaluate pros and cons.

@mholt mholt added this to the v2.6.0 milestone Apr 20, 2022
@mholt mholt modified the milestones: v2.6.0, 2.x Sep 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion 💬 The right solution needs to be found feature ⚙️ New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants