What is "domain" in kubebuilder scaffolding? - kubebuilder

The kubebuilder scaffolding command includes a repo and domain e.g.
kubebuilder init --domain tutorial.kubebuilder.io --repo tutorial.kubebuilder.io/project
I found following text in kubebuilder book about "domain":
domain: Store the domain of the project. This information can be provided by the user when the project is generate with the init sub-command and the domain flag.
And domain: domain for groups (default "my.domain")
I understand domain is usually to set boundaries to avoid naming conflicts e.g. different teams in a company can use different domains/sub-domains and have freedom of choosing names under that domain/sub-domain.
But in the context of a kubebuilder project:
What name conflicts are we avoiding here ? What if teams are different but still they deploy to a shared cluster ? What if domain name itself is duplicate ? When do you figure out there's a conflict ?
What are the functional implications of a domain e.g. on CRDs, on APIs etc. ?
Can you change it later and any gotchas ?
Can you have no domain at all, not even default - my.domain ?
I'm aware that these answers could be much longer for a post if elaborated, any guidance or material in this context would help. Thanks.

The domain is the Kubernetes 'group', which as you describe is used for namespacing and avoiding naming conflicts.
A 'group' along with a 'version' and a 'kind' uniquely identify a type of resource that the Kubernetes API server knows about.
To answer your questions:
The name conflicts you are avoiding are generally if two separate groups have a concept they want to represent with a similar name. Generally, the friendly name of a resource goes in the 'kind' field, e.g. 'Bucket'. If you have two separate concepts of a bucket, then without the existence of the 'group', you might call one kind: AWSBucket and the other kind: GCPBucket. With groups, you can do the following:
apiVersion: aws.amazon.com/v1
kind: Bucket
as separate from
apiVersion: gcp.google.com/v1
kind: Bucket
The previous dot-point hints at this. Functionally, the 'domain'/'group' along with the version form the apiVersion field of any resources you provision against the CRD, and will form the group field of the Custom Resource Definition.
You can change it later. There's the obvious gotcha that some other team might already be using your namespace. You'll also need to update and re-deploy any resources that use this domain as part of a custom resource. Practically, this might as well be a new API from the point of view of Kubernetes. You'll start again with no resources of that kind, and so you'll need to update and re-deploy any resources you've created against the old kind. This may cause issues, though it should be possible to handle these as part of a controller (e.g. migrate any controller state recorded against the old resource to the new resource).
No, it's not possible to not define a domain. I'm not sure what Kubebuilder will do if you don't provide this flag. But practically, group is a required field on the CustomResourceDefinition resource that is used to register the custom resource with Kubernetes. See the API documentation for CustomResourceDefinition
Resources:
Kubernetes docs on API groups and versioning
Kubernetes docs on using API groups
Kubebuilder docs on groups, versions and kinds

Related

How to integrate Dapr with Kong Api Gateway

I want to use Kong as api gateway to allow external applications to interact with the cluster Dapr communicate with my application. I can't find any example.
So, there is no easy way to do this directly. There is a blog post that walks through setting it up with ingress here https://carlos.mendible.com/2020/04/05/kubernetes-nginx-ingress-controller-with-dapr/
The gist of it is that you will set up your ingress controller pods as Dapr services and rewrite/redirect the calls to the dapr sidecar. Be aware of namespaces (the blog glazes over this and installs the ingress in the default namespace which is not common practice) and fully qualify the service name ..
Finally, I recommend you apply a rewrite to the invocation of the downstream service. use a regex to get the segments and append the segment at the end of the service invocation URL: HTTP://localhost:3500/v1.0/invoke/YOURSERVICE.ITSNAMESPACE/method/$2 (where $2 is the segment captured from the original path in the ingress
NOTE: I am having issues getting these types of calls to go through the HTTP pipeline components I have downstream, but if you don't need those, then its a great option

How do I change an attribute for a policy group without having to re-compile all of the policyfiles?

I am trying to shift from environment files in Chef to using Policyfiles. https://docs.chef.io/policy.html. I really like the concept, especially since you can include a policy from policy into another, but I am trying to understand how do a simple attribute change.
For instance, if I want to change a globally-used attribute that may be an error message for a problem that is happening now. ("The system will be down for 10 minutes. Thanks for your patience"). Or perhaps I want to turn off some AB testing with an attribute working as a flag. From what I can tell, the only way I can do this is to change an attribute in the policyfile, and then I need to create a new version of the policy file.
And if the policyfile is an included in many other policyfiles, like in the case of a base policyfile, then I have a lot of work to do for a simple change.
default['production']['maintenance_message'] = 'We will be down for the next 15 minutes!'
default['production']['start_new_feature'] = true
How do I make a simple change to an attribute that affects an entire policy group? Is there a simple way to change an attribute, or do I have to move all my environment properties to a data bag??
OK, I used Chef Support and got an answer: Nope.
This is their response:
"You've called out one of the main reasons we recommend that people use something like Jenkins pipelines to deliver cookbooks to their infrastructure. All that work can be kicked off by a build system recognizing a change in a dependency and initiating new builds for all the downstream consumer jobs.
For what it's worth, I don't really like putting application configurations like that maintenance message example you used in configuration management, I think something like Habitat is a better system for that kind of rapid-change configuration delivery, although you could also go down the route of storing application configuration like that in a system like Hashicorp Vault, Consul, or etcd, and ensuring that whatever apps need to ingest those changes are able to do so without configuration management fighting with the key-value config store.
If that was just an example to illustrate things, ignore the previous comment and refer only to my recommendation to use pipelines to deliver cookbooks, attributes, etc to your infrastructure (and I would generally recommend against data bags these days, but that's mostly a preference thing)."

What are some concrete use-cases for Consul's Key-Value store?

We're considering using Consul's key-value store to enhance our configuration management tool (Ansible, at the moment). We're hoping to use it to solve two related problems:
Preventing scatter: Some items (namely: passwords, certificates etc) are scattered across our configuration files. Updating them requires manual search-and-replace which can be tiresome.
Ease of update: rather then edit-and-commit configuration changes into git, we could use Consul to store those items that change often.
We're looking for a set of recommendations on how to use/integrate Consul (or similar tools) for dynamic configurations. Naturally, there is no one answer, but a set of useful practices here. I'll provide a few approaches in my answer, but I'd like to hear additional ideas.
We've been tinkering with Consul as a key-value store for a while but I think the most interesting use comes with Consul Template and using that to update configuration on the fly.
I think the end state we're probably moving towards is going to be to use Ansible to configure a base image of things we know are slow changing plus configure Consul Template, then AMI this (these first 2 steps probably done via Packer) and then deploy into auto scaling groups in AWS using Terraform (which we already use for provisioning).
Then we will use Consul's key-value store to change properties that Consul Template will then propagate across a cluster of instances. We also intend to have instances register themselves in Consul which will also affect configuration on other instances such as load balancing members on Apache/NGINX configurations or lists of unicast addressable members for clustering.
On a slightly related note, and as mentioned by mahnve, Vault is a pretty nice add on to Consul for storing secrets. We're already using it for pretty static secrets but intend to start using some of the dynamic secret generation which allows you to request short lived API or SSH keys which can be tracked and revoked.
To mitigate #1 I'd suggest looking into Hashicorps Vault, https://www.vaultproject.io/, which is a tool to handle secrets, which can use Consul as a backend.
We've yet to do this, but are thinking about integrating consul into our Ansible plays. Ansible recently added a lookup option from consul:
https://github.com/ansible/ansible/blob/devel/test/integration/roles/test_consul_kv/tasks/main.yml#L70
- debug: msg='key contains {{item}}'
with_consul_kv:
- 'key/to/retrieve'
So we could directly populate our plays with values from Consul.
Another approach we're considering is to utilize consul's templating tool - and template entire configuration files after ansible plants them on our hosts.

How to persist a bundle with resources not still created on my fhir server?

In our CDA2FHIR mapping engine we are generating Fhir bundle from CDA document, but this Bundle has resources without real fhir IDs from our server. For example, one patient and another compartment objects like procedures, medicationPrescription, relatedPerson, ..... We need to persist this REsource network individually, but linked between them.
how should we created the Resources in the Bundle in the server? I think we should persist with certain sorting (first patient, practitioner, and relatedPErsons, and later rest of comparment resources). Is there some approach for this? some endpoint?
Thanks in advance for any suggestion or guidance.
Regards
Within a bundle, it's legitimate to give resources URNs rather than URLs. I.e. urn:uuid:.... or urn:oid:....
This is covered in a single line in section 1.12.3.4.1: "Note that internal references are allowed to be URIs rather than literal URLs."
If you create multiple documents that reference the same Patient, Observation, etc., the uuid or OID used to identify that resource instance SHOULD be the same in each document you produce.

How to provision OSGi services per client

We are developing a web-application (lets call it an image bank) for which we have identified the following needs:
The application caters customers which consist of a set of users.
A new customer can be created dynamically and a customer manages it's users
Customers have different feature sets which can be changed dynamically
Customers can develop their own features and have them deployed.
The application is homogeneous and has a current version, but version lifting of customers can still be handled individually.
The application should be managed as a whole and customers share the resources which should be easy to scale.
Question: Should we build this on a standard OSGi framework or would we be better of using one of the emerging application frameworks (Virgo, Aries or upcoming OSGi standard)?
More background and some initial thoughts:
We're building a web-app which we envision will soon have hundreds of customers (companies) with hundreds of users each (employees), otherwise why bother ;). We want to make it modular hence OSGi. In the future customers themselves might develop and plugin components to their application so we need customer isolation. We also might want different customers to get different feature sets.
What's the "correct" way to provide different service implementations to different clients of an application when different clients share the same bundles?
We could use the app-server approach (we've looked at Virgo) and load each bundle once for each customer into their own "app". However it doesn't feel like embracing OSGi. We're not hosting a multitude of applications, 99% of the services will share the same impl. for all customers. Also we want to manage (configure, monitor etc.) the application as one.
Each service could be registered (properly configured) once for each customer along with some "customer-token" property. It's a bit messy and would have to be handled with an extender pattern or perhaps a ManagedServiceFactory? Also before registering a service for customer A one will need to acquire the A-version of each of it's dependencies.
The "current" customer will be known to each request and can be bound to the thread. It's a bit of a mess having to supply a customer-token each time you search for a service. It makes it hard to use component frameworks like blueprint. To get around the problem we could use service hooks to proxy each registered service type and let the proxy dispatch to the right instance according to current customer (thread).
Beginning our whole OSGi experience by implementing the workaround (hack?) above really feels like an indication we're on the wrong path. So what should we do? Go back to Virgo? Try something similar to what's outlined above? Something completely different?!
ps. Thanks for reading all the way down here! ;)
There are a couple of aspects to a solution:
First of all, you need to find a way to configure the different customers you have. Building a solution on top of ConfigurationAdmin makes sense here, because then you can leverage the existing OSGi standard as much as possible. The reason you might want to build something on top is that ConfigurationAdmin allows you to configure each individual service, but you might want to add a layer on top so you can more conveniently configure your whole application (the assembly of bundles) in one go. Such a configuration can then be translated into the individual configurations of the services.
Adding a property to services that have customer specific implementations makes a lot of sense. You can set them up using a ManagedServiceFactory, and the property makes it easy to lookup the service for the right customer using a filter. You can even define a fallback scenario where you either look for a customer specific service, or a generic one (because not all services will probably be customer specific). Since you need to explicitly add such filters to your dependencies, I'd recommend taking an existing dependency management solution and extending it for your specific use case so dependencies automatically add the right customer specific filters without you having to specify that by hand. I realize I might have to go into more detail here, just let me know...
The next question then is, how to keep track of the customer "context" within your application. Traditionally there are only a few options here, with a thread local context being the most used one. Binding threads to customers does tend to limit you in terms of implementation options though, as in general it probably means you have to prohibit developers from creating threads themselves, and it's hard to off-load certain tasks to pools of worker threads. It gets even worse if you ever decide to use Remote Services as that means you will completely loose the context.
So, for passing on the customer identification from one component to another, I personally prefer a solution where:
As soon as the request comes in (for example in your HTTP servlet) somehow determine the customer ID.
Explicitly pass on that ID down the chain of service dependencies.
Only use solutions like the use of thread locals within the borders of a single bundle, if for example you're using a third party library inside your bundle that needs this to keep track of the customer.
I've been thinking about this same issue (I think) for some time now, and would like your opinions on the following analogy.
Consider a series of web application where you provide access control using a single sign-on (SSO) infrastructure. The user authenticates once using the SSO-server, and - when a request comes in - the target web application asks the SSO server whether the user is (still) authenticated and determines itself if the user is authorized. The authorization information might also be provided by the SSO server as well.
Now think of your application bundles as mini-applications. Although they're not web applications, would it still not make sense to have some sort of SSO bundle using SSO techniques to do authentication and to provide authorization information? Every application bundle would have to be developed or configured to use the SSO bundle to validate the authentication (SSO token), and validate authorization by asking the SSO bundle if the user is allowed to access this application bundle.
The SSO bundle maintains some sort of session repository, and also provides user properties, e.g. information to identify the data repository (of some sort) of this user. This way you also wouldn't pass trough a (meaningful) "customer service token", but rather a cryptic SSO-token that is supplied and managed by the SSO bundle.
Please not that Virgo is an OSGi container based on Equinox, so if you don't want to use some Virgo-specific feature, you don't have to. However, you'll get lots of benefits if you do use Virgo, even for a basic OSGi application. It sounds, though, like you want web support, which comes out of the box with Virgo web server and will save you the trouble of cobbling it together yourself.
Full disclosure: I lead the Virgo project.

Resources