-
Notifications
You must be signed in to change notification settings - Fork 36
Support external resources via HTTP as includes #53
Comments
Thanks for filing this! We chatted briefly about this on Slack and I like the idea, but here are my current "worries":
I don't want to add features that increase complexity and user friction (afterall this isn't supposed to be Helm ...), so it's important to me to solve these questions before proceeding with any implementation (writing this is trivial, the design is hard!). |
Great concerns, here are my thoughts at the moment:
|
Here are some preliminary UI considerations, consider this me thinking loud: # Remote resources UI mockup
---
context: some-cluster
include:
# My API service is a local resource set:
- name: some-api-service
values:
version: '1.2-7ab326c'
# but its database is a remote resource set:
- name: postgres
# The location field will always opaquely exist for normal resource sets,
# too. This means that it is by default derived from the 'name' field but
# can be overridden and set to a different local or remote path.
# Remote paths support HTTP(S) for now.
location: https://raw.githubusercontent.com/tazjin/stuff/postgres.yaml
# I'd prefer if remote resource sets did not change unexpectedly, so the
# optional 'hash' field can be used to provide the sha256 hash of the file
# specified above.
# If this field is not set a warning will be emitted during the run that
# informs the user about the hash of the file that was retrieved and
# suggests pinning the hash.
# If the hashes don't match, kontemplate errors on runs.
hash: '969a969d4e57f352a4a1b4e8e5788033fbecf84c7d2c9c5652b0462e369d5372'
# Values for the remote resource set are set as normal
values:
version: 9.6
storageSize: 100Gi
# That's basic functionality but the big remaining question is how to deal
# with defaults. @jordanjennings suggested simply attempting to fetch the
# default.[json|yaml] from the same location as the resource itself, but
# there is no guarantee that the resource location is a URL containing a
# filename.
# One other idea is to make 'location' an array (potentially with promotion
# of single values for syntactic convenience):
location:
- https://raw.githubusercontent.com/tazjin/stuff/postgres.yaml
- https://raw.githubusercontent.com/tazjin/stuff/default.json
# But what happens to hashes then? This can too easily end up with a complex
# type in this array.
# Another feature that falls out of this potentially is using absolute local
# paths:
location: /etc/kontemplate/resource-sets/postgres I want to avoid making "package formats" with metadata-manifests if at all possible, but I also don't want remote resources to have diminished capabilities. Probably going to need 2-3 days to form a decision on this ... |
Some of these things can be solved with convention, by saying remote resource sets must have a User friction can be reduced by having helpful error messages: 1: Remote resource set is incompleteIf the $ grep -A1 postgres my-cluster.yaml
- name: postgres
location: https://www.google.com
$ kontemplate apply my-cluster.yaml
Loading resources for some-api-service
Loading resources for postgres
ERROR: The resource set 'postgres' has been included from a remote location at
'https://www.google.com', however the expected file 'https://www.google.com/main.yaml`
could not be found.
Remote resource sets are expected to contain a `main.yaml` file and optionally a
`default.json`. Something something YAML & JSON support. 2: Remote resource set has no hashHashes are optional, but preferred. If they are not present a warning will be Hashes are calculated like such:
And checked after fetching the remote files. If no hash is present this happens (text could be better...): $ grep -A1 postgres my-cluster.yaml
- name: postgres
location: https://raw.githubusercontent.com/tazjin/resource-sets/postgres
$ kontemplate apply my-cluster.yaml
Loading resources for some-api-service
Loading resources for postgres
WARNING: Resource set 'postgres' is remote, but no hash is currently set. The
owner of the remote location could potentially change the resource files without
your knowledge.
To pin the current version of the resource set add 'hash: 969a969d4e57f352a4a1b4e8e5788033fbecf84c7d2c9c5652b0462e369d5372' below the 'location' configuration for 'postgres'.
You may suppress this warning by adding 'hash: ignore' instead. Step 3: Hash mismatchIf the user is a good user and has put nice hashes in there, but the remote $ grep -A1 postgres my-cluster.yaml
- name: postgres
location: https://raw.githubusercontent.com/tazjin/resource-sets/postgres
hash: 969a969d4e57f352a4a1b4e8e5788033fbecf84c7d2c9c5652b0462e369d5372
$ kontemplate apply my-cluster.yaml
Loading resources for some-api-service
Loading resources for postgres
ERROR: Expected hash for remote resource set 'postgres' did not match.
Got unexpected hash '33495e96e55c2fe59e1ba6d75a3cfa5ca36719ac1e38155d245908e0b720ae75'.
Please check whether the updated resource is the one you want and update
'my-cluster.yaml' accordingly. "Emergent" features
|
I was typing a long reply and you basically mentioned everything I was typing already in your latest update :) Yes, HTTP basic auth would be something people would definitely request. And yes, most git hosts (GitHub, Bitbucket, and Gitlab at least) support linking to a specific commit which would be guaranteed to be stable, since the commit ID is already a hash of the contents. I would very much prefer NOT to see an enforced naming convention for remote resources. If the convention just uses a single file anyway, I think it would be much nicer to just allow the user to specify the location of both the resource and optionally the defaults.
Perhaps by convention if the URL does not end with .yaml, .yml, or .json then you could check for a main.yaml/json and default.yaml/json relative to the location? |
Great minds etc.! ;-)
Do you think it's feasible to enforce that the remote locations have to end in sensible filenames? In that case going for the I spoke briefly to @heavenlyhash and he brought up that kontemplate "suddenly" doing network I/O should require explicit opt-in, a la having a
|
The concern about networking calls is certainly valid, but I would agree that specifying remote locations is essentially an opt-in. And yes, enforcing that files end with sensible extensions like |
I don't think this will make it into 1.1.0 which I'm planning to get out soon for the fix of #51 |
This would be an awesome feature, making codebases much more modular (similar to Terraform & git source modules). |
I'm closing this issue as I now think that using tools like Nix is a much better way of achieving this sort of modularity. Please note that the source of kontemplate is moving to git.tazj.in and issue tracking / patches will be available on depot@tazj.in. |
It would be really nice to have the option to include external resources via HTTP so that I could have templates stored somewhere different than the kontemplate file.
Use case 1
I create a microservice deployment template that I want multiple projects to be able to use. Each project then has one or more kontemplate files that refer to the common deployment template.
Each project only has kontemplate files like:
Use case 2
Using kontemplate for cluster standup I have a collection of addons that I want configured per cluster. Some addon definitions will be locally managed, some will be shared (and may not even need customization for installation).
dev-cluster.yml:
prod-cluster.yml:
Yes for the second use case I could just directly run kubectl apply -f with the URL, but keeping it all in one place would be very convenient and make me happy :)
The text was updated successfully, but these errors were encountered: