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

Model templates #92

Closed
wants to merge 1 commit into from
Closed

Model templates #92

wants to merge 1 commit into from

Conversation

plorenz
Copy link
Member

@plorenz plorenz commented Dec 1, 2020

No description provided.

}

var getFilesCmd = &cobra.Command{
Use: "get-files hostSpec localPath remoteFiles",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get-files <hostSpec> <localPath> <remoteFiles> ... very minor nitpick.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, can we add a get command, which contains the files command... rather than a hyphenated get-files?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed both

@@ -88,6 +88,12 @@ func bootstrapModel() (*Model, error) {
}
}

for _, factory := range m.ModelFactories {
if err := factory.Build(m); err != nil {
return nil, fmt.Errorf("error executing factory [%s] (%w)", reflect.TypeOf(factory), err)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

been trying to standardize on errors.Wrap for this sort of thing.

return nil, errors.Wrapf(err, "error executing factory [%s]", reflect.TypeOf(factory))

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to know, I hadn't learned about errors.Wrap(f) yet. I've started converting things over, but there's a lot there, so I'll convert more opportunistically as I come across them.

Regions Regions

Regions Regions
ModelFactories []Factory // Factories that change the model structure, eg: add/remove hosts
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would this be different than a Factory? Why add another Factory concept?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's to separate Factories which mutate model structure vs ones that don't. The structure manipulation has to be done before we bind the label and environment, otherwise things like IP addresses don't end up in the right spot, b/c their intended targets aren't there yet. Other Factories get done after the label/binding are applied, and it didn't feel right to move them all in front of label/env binding.

Let me know if that makes sense, if you've got ideas on how that could be solved differently.

Copy link
Collaborator

@michaelquigley michaelquigley Dec 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think by their nature factories need to be inserted into the model in the correct order. What you're doing with "model" factories is no different.. they just happen first. Not sure that it's a useful distinction. It's more powerful to just have "factories" and put them in the correct order.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you arguing there should be just one set of factories and that they should all be invoked before the label and environment is bound? I suspect that will break other factories which rely on variables to be set.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why can't all of the factories run after the label and environment are bound? The label and environment binding just feed static data to the factories and the model?

Copy link
Collaborator

@michaelquigley michaelquigley Dec 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe label/environment binding gets moved into a Factory and then the ordering can be controlled however we want per-model? (If we really do have factories that we want to run before label/environment binding)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving label/env binding into a factory would work. The templating stuff really does need to run before binding, otherwise the binding doesn't have anything to apply values to.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably loop this into our conversation tomorrow.

return result
}

func (region *Region) Templatize(templater *Templater) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think my biggest issue with "templatization" is the name. If all we're doing is calling CloneXXX methods from a Factory... why not just call it that? Then, doesn't the model just contain a single, or the smallest version of a footprint, and we're just cloning that to extend the model to a larger configuration?

I just don't think the model is a "template" in that example. It's a fully-fledged model.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can change the name, but there is more to it than just cloning. Taking the edge bit for an example, here's the client host/component definition:

				"client{{ .Index }}": {
					Scope: model.Scope{Tags: model.Tags{"^client", "^sdk-app"}},
					Components: model.Components{
						"client{{ .Host.Index }}": {
							BinaryName:     "ziti-fabric-test",
							PublicIdentity: "client{{ .Host.Index }}",
							ConfigSrc:      "loop/edge-perf.loop3.yml",
							ConfigName:     "edge-perf-{{ .Host.Index }}.loop3.yml",
						},
					},
				},

So we're not just copying it, we're using it as a base, and injecting environment into the id, public identity and config name. Even if we only had one client, it wouldn't look like the code above, it would be the version after templating has been applied.

Does that justify the templating nomenclature, or does it still feel like it should be called something else?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to spend more time thinking about this. I don't think bringing the golang template engine into the mix makes this more streamlined... I feel like it makes it more convoluted. Using the model to express things that are "templates" feels like a corruption of the model.

Base automatically changed from master to main January 25, 2021 22:19
@plorenz plorenz force-pushed the model-templates branch 2 times, most recently from 936f054 to 021d1f7 Compare May 10, 2021 20:15
@plorenz
Copy link
Member Author

plorenz commented Oct 20, 2021

Replaced by refactored model scaling PR #113

@plorenz plorenz closed this Oct 20, 2021
@plorenz plorenz deleted the model-templates branch April 19, 2022 18:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants