Closed pmorie closed 7 years ago
Since #1028 already has some of this functionality, and @nilebox has expressed interest in finishing this feature, I suggest that we repurpose #1028 to implement this API.
We can add future methods of creating parameters
Thinking, if SecretParameters
should be just merged with Parameters
type then.
Also, I would split 2 ways of secret parameters into independent exclusive fields. In other words:
type Parameters struct {
// Reference to a secret in the namespace.
// The parameters will be created as a dictionary from all keys in the secret.
SecretRef *LocalObjectReference
// Reference to a secret key in the namespace.
// The parameters will be set from the JSON contained in this secret key
SecretKeyRef *SecretKeySelector
// Any other methods also go there, for example:
Raw *runtime.RawExtension
ConfigMapRef *LocalObjectReference
ConfigMapKeyRef *ConfigMapKeySelector
}
@pmorie we will need to update the design.md
doc file with the section about parameters.
Do you see this as part of https://github.com/kubernetes-incubator/service-catalog/issues/1028 pull request, or as a separate one?
I would prefer to keep it separate to avoid doc bikeshedding blocking the code merge.
@pmorie @arschles @vaikas-google @kibbles-n-bytes @spadgett Please have a look at the completely new alternative proposal which came out of our discussion with @duglin by trying to address some of his concerns:
The example of the InstanceSpec (see gist)
spec:
serviceClassName: user-provided-service
planName: default
parameters:
- name: username # easy name/value pair case
value: root
- name: password # pull value from a secret's key
valueFrom:
secretKeyRef:
name: mySecret1
key: passwd
- name: size # pull value from a configMap key
valueFrom:
configMapKeyRef:
name: myConfigMap0
key: length
parametersFrom:
- configMapRef:
name: myConfigMap1 # pull in all the CM's key/value's (string/string)
- secretRef:
name: mySecret2 # pull in all the secret key/value's (string/string)
- configMapKeyBlobRef:
name: myConfigMap2
key: credentials # "credentials" is a JSON object so we take it verbatim and we merge with the above
- secretKeyBlobRef:
name: mySecret3
key: creds # "creds" is a JSON object so we take it verbatim and merge with the the above
As you can see, it's consistent with the way envFrom
and env.valueFrom
work in the Pod spec:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: test-container
image: nginxdemos/hello
env:
- name: USERNAME
value: root
- name: PASSWORD
valueFrom:
secretKeyRef:
name: mySecret1
key: passwd
- name: SIZE
valueFrom:
configMapKeyRef:
name: myConfigMap0
key: length
envFrom:
- configMapRef:
name: myConfigMap1
- secretRef:
name: mySecret2
secretKeyBlobRef
and configMapKeyBlobRef
of course, but the rest maps one-to-oneenvFrom
items have prefix attribute, which we might want to leverage as well (for conflict resolution)One of the limitations the proposal above has is poor support for multi-level JSON. Only configMapKeyBlobRef
and secretKeyBlobRef
support them, all the other options are treated as a string.
The easy addition fixing this problem is an extra optional field type
with possible values of string/json (with string
value as a default). For example,
...
- name: textField
value: qwerty # string by default
- name: meta
type: json # the string value will be deserialized and passed as JSON object
valueFrom:
secretKeyRef:
name: mySecret1
key: jsonBlob
...
With this addition we don't need special cases like secretKeyBlobRef
, just type
+secretKeyRef
combination is enough.
In the future we can add support for other valid JSON property types (number, array etc)
@nilebox in that example why would we need to treat it as json instead of just a string that happens to look like json? If our merge strategy is really simple (something like we detect conflicts at the top-most level and error), then we wouldn't really need to care that "meta" is json instead of a string would we?
we wouldn't really need to care that "meta" is json instead of a string would we
@duglin yes we would. It's not about the conflict resolution, it's about being able to pass a value to the broker either as a string, or as a json object, and let the user explicitly make a choice.
for example, if you have a structure like this:
{
"textField": "textValue",
"meta": {
"attributes": {
"a": "b",
"c": "d"
},
"labels": [
"one",
"two"
]
}
}
, you should also be able to send something like this:
{
"textField": "textValue",
"meta": "{\"labels\": [\"one\", \"two\"]}"
}
and it's up to the user to decide.
if I'm following, there are two cases - one where the value is a string that looks like json and one where the value is an actual json blob and needs to treated as such, right?
Do these cover it?
- name: meta1
value: "{\"labels\": [\"one\", \"two\"]}" # string
- name: meta2
valueFrom:
configMapKeyRef:
name: myConfigMap
key: myMeta # string
- name: meta3
valueFrom:
configMapBlobRef:
name: myConfigMap
key: myMetaJson # json
I think that's consistent with how we're using it in the other spots because I'm viewing xxxBlobRef
s as a way of saying "use the json over here".
I'm hoping someone comes up with a better name than "BlobRef" :-)
@duglin yes, it covers it, but I like type
attribute more. It's more flexible, explicit, and extensible for support of other outputs in the future (int/float, array etc).
You can even do this for example:
- name: meta1
type: json
value: "{\"labels\": [\"one\", \"two\"]}" # looks like string, but will be passed as JSON object
@nilebox and I chatted off-line and I see the flexibility of the "type" flag - and since its optional (and we'll default to "string") it seems ok for now. I just wonder where the line will be where we say "if you really want that much flexibility just give us the entire json because we're not a JSON templating language thingy".
I'm closing this because #1075 is more representative of discussion so far and up to date.
This is based on design discussions in a SIG meeting on July 18, 2017.
We discussed the following as guiding factors for the design of parameter handling:
We discussed the following as making up the 80%:
API changes
The following API implements the (1) and (2) parts of the 80% solution:
There should be a validation which ensures ultimately ensures that one and only one field of
Parameters
is set. Future extensions can be implemented as new pointer fields ofParameters
.Example: all parameters from a single secret key:
Example: all parameters from every key in a secret:
Future extensions
We can add future methods of creating parameters to the
Parameters
struct, like so: