Skip to content

Streamline object models #390

Closed
Closed
@admilazz

Description

@admilazz

The generated object models have several problems, in my opinion:

  1. No base class. Every (or almost every?) top-level Kubernetes object has a common shape, but there is no base class that expresses this. This makes it hard to write code that operates on Kubernetes objects generically. I'd expect something like the following. This can be done by having the code generator use the base class whenever an object has an ObjectMeta field called "metadata". The base class can optionally replace the IKubernetesObject interface, or if they should both exist, the IKubernetesObject interface should probably gain a "Metadata" property. (Is there any object implementing IKubernetesObject that has no V1ObjectMetadata anywhere?)
abstract class V1Base
{
    [JsonProperty("metadata")]
    public V1ObjectMetadata Metadata { get; set; }

    [JsonIgnore]
    public string Name { get => Metadata?.Name; set => InitializeMetadata().Name = value; }

    [JsonIgnore]
    public string Namespace { ... }

    [JsonIgnore]
    public string ResourceVersion { ... }

    [JsonIgnore]
    public string Uid { ... }

    [JsonIgnore]
    public IDictionary<string, string> Labels { ... }

    ...

    V1ObjectMetadata InitializeMetadata()
    {
        if(Metadata == null) Metadata = new V1ObjectMetadata();
        return Metadata;
    }
}

class V1Pod : V1Base { ... }
  1. Metadata properties should be inlined, like in the Go client. It's much nicer to write o.Name than o.Metadata.Name, especially when you are setting the value and must optionally initialize o.Metadata first. This can be accomplished with properties as in the above example.

  2. Rename NamespaceProperty, ContinueProperty, etc. to Namespace, Continue, etc. There's no need for the "Property" suffix. The existing properties can be deprecated redirects for backwards compatibility (e.g. public string NamespaceProperty { get => Namespace; set => Namespace = value; }).

  3. Have a base class for lists, too. This makes it possible to write code that operates on generic lists of Kubernetes objects. This can be done by having the code generator use the base class whenever a list contains a ListMeta field.

abstract class V1ListBase
{
    public string ApiVersion { get; set; }
    public string Kind { get; set; }
    public string V1ListMeta Metadata { get; set; }

    [JsonIgnore]
    public string Continue { get => Metadata?.ContinueProperty; set => InitializeMetadata().Continue = value; }

    ...
}

class V1List<T> : V1ListBase
{
    public IList<T> Items { get; set; }
}

class V1PodList : V1List<V1Pod> { }

I realize that some of these changes break binary compatibility. They can go in v2.0.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions