Compare commits

...

20 Commits

Author SHA1 Message Date
Jeff McCune
79e8ab639a (#161) Fix the FormGroup & Refactor API
The way we were organizing fields into section broke Formly validation.
This patch fixes the problem by using the recommended approach of
[Nested Forms][1].

This patch also refactors the PlatformService API to clean it up.
GetForm / PutForm are separated from the Platform methods.  Similarly
GetModel / PutModel are separated out and are specific to get and put
the model data.

NOTE: I'm not sure we should have separated out the platform service
into it's own protobuf package.  Seems maybe unnecessary.

❯ grpcurl -H "x-oidc-id-token: $(holos token)" -d '{"platform_id":"018f36fb-e3ff-7f7f-a5d1-7ca2bf499e94"}' jeff.app.dev.k2.holos.run:443 holos.platform.v1alpha1.PlatformService.GetModel
{
  "model": {
    "org": {
      "contactEmail": "platform@openinfrastructure.co",
      "displayName": "Open Infrastructure Services LLC",
      "domain": "ois.run",
      "name": "ois"
    },
    "privacy": {
      "country": "earth",
      "regions": [
        "us-east-2",
        "us-west-2"
      ]
    },
    "terms": {
      "didAgree": true
    }
  }
}

[1]: https://formly.dev/docs/examples/other/nested-formly-forms
2024-05-04 10:14:37 -07:00
Jeff McCune
a0cc673736 (#150) Wire up select and multi select boxes
This patch wires up a Select and a Multi Select box.  This patch also
establishes a decision as it relates to Formly TypeScript / gRPC Proto3
/ CUE definitions of the form data structure.  The decision is to use
gRPC as a transport for any JSON to avoid friction trying to fit Formly
types into Proto3 messages.

Note when using google.protobuf.Value messages with bufbuild/connect-es,
we need to round trip them one last time through JSON to get the
original JSON on the other side.  This is because connect-es preserves
the type discriminators in the case and value fields of the message.

Refer to: [Accessing oneof
groups](https://github.com/bufbuild/protobuf-es/blob/main/docs/runtime_api.md#accessing-oneof-groups)

NOTE: On the wire, carry any JSON as field configs for expedience.  I
attempted to reflect FormlyFieldConfig in protobuf, but it was too time
consuming.  The loosely defined Formly json data API creates significant
friction when joined with a well defined protobuf API.  Therefore, we do
not specify anything about the Forms API, convey any valid JSON, and
leave it up to CUE and Formly on the sending and receiving side of the
API.

We use CUE to define our own holos form elements as a subset of the loose
Formly definitions.  We further hope Formly will move toward a better JSON
data API, but it's unlikely.  Consider replacing Formly entirely and
building on top of the strongly typed Angular Dyanmic Forms API.

Refer to: https://github.com/ngx-formly/ngx-formly/blob/v6.3.0/src/core/src/lib/models/fieldconfig.ts#L15
Consider: https://angular.io/guide/dynamic-form

Usage:

Generate the form from CUE

    cue export ./forms/platform/ --out json | jq -cM | pbcopy

Store the form JSON in the config_values column of the platforms table.

View the form, and submit some data. Then get the data back out for use rendering the platform:

    grpcurl -H "x-oidc-id-token: $(holos token)" -d '{"platform_id":"'${platformId}'"}' $holos holos.v1alpha1.PlatformService.GetConfig

```json
{
  "platform": {
    "spec": {
      "config": {
        "user": {
          "sections": {
            "org": {
              "fields": {
                "contactEmail": "jeff@openinfrastructure.co",
                "displayName": "Open Infrastructure Services LLC",
                "domain": "ois.run",
                "name": "ois"
              }
            },
            "privacy": {
              "fields": {
                "country": "earth",
                "regions": [
                  "us-east-2",
                  "us-west-2"
                ]
              }
            },
            "terms": {
              "fields": {
                "didAgree": true
              }
            }
          }
        }
      }
    }
  }
}
```
2024-05-03 10:42:03 -07:00
Jeff McCune
d06ecfadc8 (#150) Refactor PlatformService.GetConfig for use with CUE
Problem:
The GetConfig response value isn't directly usable with CUE without some
gymnastics.

Solution:
Refactor the protobuf definition and response output to make the user
defined and supplied config values provided by the API directly usable
in the CUE code that defines the platform.

Result:

The top level platform config is directly usable in the
`internal/platforms/bare` directory:

    grpcurl -H "x-oidc-id-token: $(holos token)" -d '{"platform_id":"'${platformID}'"}' $host \
      holos.v1alpha1.PlatformService.GetConfig \
      > platform.holos.json

Vet the user supplied data:

    cue vet ./ -d '#PlatformConfig' platform.holos.json

Build the holos component.  The ConfigMap consumes the user supplied
data:

    cue export --out yaml -t cluster=k2 ./components/configmap platform.holos.json \
      | yq .spec.components

Note the data provided by the input form is embedded into the
ConfigMap managed by Holos:

```yaml
KubernetesObjectsList:
  - metadata:
      name: platform-configmap
    apiObjectMap:
      ConfigMap:
        platform: |
          metadata:
            name: platform
            namespace: default
            labels:
              app.holos.run/managed: "true"
          data:
            platform: |
              kind: Platform
              spec:
                config:
                  user:
                    sections:
                      org:
                        fields:
                          contactEmail: jeff@openinfrastructure.co
                          displayName: Open Infrastructure Services LLC
                          domain: ois.run
                          name: ois
              apiVersion: app.holos.run/v1alpha1
              metadata:
                name: bare
                labels: {}
                annotations: {}
              holos:
                flags:
                  cluster: k2
          kind: ConfigMap
          apiVersion: v1
    Skip: false
```
2024-05-02 06:39:33 -07:00
Jeff McCune
64a117b0c3 (#150) Add PlatformService.GetConfig and refactor ConfigValues proto
Problem:
The use of google.protobuf.Any was making it awkward to work with the
data provided by the user.  The structure of the form data is defined by
the platform engineer, so the intent of Any was to wrap the data in a
way we can pass over the network and persist in the database.

The escaped JSON encoding was problematic and error prone to decode on
the other end.

Solution:
Define the Platform values as a two level map with string keys, but with
protobuf message fields "sections" and "fields" respectively.  Use
google.protobuf.Value from the struct package to encode the actual
value.

Result:
In TypeScript, google.protobuf.Value encodes and decodes easily to a
JSON value.  On the go side, connect correctly handles the value as
well.

No more ugly error prone escaping:

```
❯ grpcurl -H "x-oidc-id-token: $(holos token)" -d '{"platform_id":"'${platformId}'"}' $host holos.v1alpha1.PlatformService.GetConfig
{
  "sections": {
    "org": {
      "fields": {
        "contactEmail": "jeff@openinfrastructure.co",
        "displayName": "Open Infrastructure Services LLC",
        "domain": "ois.run",
        "name": "ois"
      }
    }
  }
}
```

This return value is intended to be directly usable in the CUE code, so
we may further nest the values into a platform.spec key.
2024-05-01 21:30:30 -07:00
Jeff McCune
cf006be9cf (#150) Add SystemService DropTables and SeedDatabase
Makes it easier to reset the database and give Gary and Nate access to
the same organization I'm in so they can provide feedback.
2024-05-01 14:30:13 -07:00
Jeff McCune
45ad3d8e63 (#150) Fix 500 error when config values aren't provided
AddPlatform was failing with a 500 error trying to decode a nil byte
slice when adding a platform without providing any values.
2024-05-01 11:31:25 -07:00
Jeff McCune
441c968c4f (#150) Look up user by iss sub, not email.
Also log when orgs are created.
2024-05-01 10:02:08 -07:00
Jeff McCune
99f2763fdf (#150) Store Platform Config Form and Values as JSON
This patch changes the backend to store the platform config form
definition and the config values supplied by the form as JSON in the
database.

The gRPC API does not change with this patch, but may need to depending
on how this works and how easy it is to evolve the data model and add
features.
2024-05-01 09:11:53 -07:00
Jeff McCune
1312395a11 (#150) Fix platforms page links
The links were hard to click.  This makes the links a much larger click
target following the example at https://material.angular.io/components/list/overview#navigation-lists
2024-05-01 08:51:29 -07:00
Jeff McCune
615f147bcb (#150) Add PutPlatformConfig to store the config values
This patch is a work in progress wiring up the form to put the values to
the holos server using grpc.

In an effort to simplify the platform configuration, the structure is a
two level map with the top level being configuration sections and the
second level being the fields associated with the config section.

To support multiple kinds of values and field controls, the values are
serialized to JSON for rpc over the network and for storage in the
database.  When they values are used, either by the UI or by the `holos
render` command, they're to be unmarshalled and in-lined into the
Platform Config data structure.

Pick back up ensuring the Platform rpc handler correctly encodes and
decodes the structure to the database.

Consider changing the config_form and config_values fields to JSON field
types in the database.  It will likely make working with this a lot
easier.

With this patch we're ready to wire up the holos render command to fetch
the platform configuration and create the end to end demo.

Here's essentially what the render command will fetch and lay down as a
json file for CUE:

```
❯ grpcurl -H "x-oidc-id-token: $(holos token)" -d '{"platform_id":"018f2c4e-ecde-7bcb-8b89-27a99e6cc7a1"}' jeff.app.dev.k2.holos.run:443 holos.v1alpha1.PlatformService.GetPlatform | jq .platform.config.values
{
  "sections": {
    "org": {
      "values": {
        "contactEmail": "\"platform@openinfrastructure.co\"",
        "displayName": "\"Open Infrastructure Services  LLC\"",
        "domain": "\"ois.run\"",
        "name": "\"ois\""
      }
    }
  }
}
```
2024-04-30 20:21:15 -07:00
Jeff McCune
d0ad3bfc69 (#150) Add Platform Detail to edit platform config
This patch adds a /platform/:id route path to a PlatformDetail
component.  The platform detail component calls the GetPlatform method
given the platform ID and renders the platform config form on the detail
tab.

The submit button is not yet wired up.

The API for adding platforms changes, allowing raw json bytes using the
RawConfig.  The raw bytes are not presented on the read path though,
calling GetPlatforms provides the platform and the config form inline in
the response.

Use the `raw_config` field instead of `config` when creating the form
data.

```
❯ grpcurl -H "x-oidc-id-token: $(holos token)" -d @ jeff.app.dev.k2.holos.run:443 holos.v1alpha1.PlatformService.AddPlatform <<EOF
{
  "platform": {
    "org_id": "018f27cd-e5ac-7f98-bfe1-2dbab208a48c",
    "name": "bare2",
    "raw_config": {
      "form": "$(cue export ./forms/platform/ --out json | jq -cM | base64 -w0)"
    }
  }
}
EOF
```
2024-04-30 14:02:49 -07:00
Jeff McCune
fe58a33747 (#150) Add holos.v1alpha1.PlatformService.GetForm
The GetForm method is intended for the Angular frontend to get
[FormlyFieldConfig][1] data for each section of the Platform config.

[1]: https://formly.dev/docs/api/core/#formlyfieldconfig

Steps to exercise for later testing:

Add the form definition to the database:

```
grpcurl -H "x-oidc-id-token: $(holos token)" -d @ jeff.app.dev.k2.holos.run:443 holos.v1alpha1.PlatformService.AddPlatform <<EOF
{
  "platform": {
    "org_id": "018f27cd-e5ac-7f98-bfe1-2dbab208a48c",
    "name": "bare${RANDOM}",
    "config": {
      "form": "$(cue export ./forms/platform/ --out json | jq -cM | base64 -w0)"
    }
  }
}
EOF
```

Get the form definition back out:

```

❯ grpcurl -H "x-oidc-id-token: $(holos token)" -d '{"platform_id":"018f2bc1-6590-7670-958a-9f3bc02b658f"}' jeff.app.dev.k2.holos.run:443 holos.v1alpha1.PlatformService.GetForm
{
  "apiVersion": "forms.holos.run/v1alpha1",
  "kind": "PlatformForm",
  "metadata": {
    "name": "bare"
  },
  "spec": {
    "sections": [
      {
        "name": "org",
        "displayName": "Organization",
        "description": "Organization config values are used to derive more specific configuration values throughout the platform.",
        "fieldConfigs": [
          {
            "key": "name",
            "type": "input",
            "props": {
              "label": "Name",
              "placeholder": "example",
              "description": "DNS label, e.g. 'example'",
              "required": true
            }
          },
          {
            "key": "domain",
            "type": "input",
            "props": {
              "label": "Domain",
              "placeholder": "example.com",
              "description": "DNS domain, e.g. 'example.com'",
              "required": true
            }
          },
          {
            "key": "displayName",
            "type": "input",
            "props": {
              "label": "Display Name",
              "placeholder": "Example Organization",
              "description": "Display name, e.g. 'Example Organization'",
              "required": true
            }
          },
          {
            "key": "contactEmail",
            "type": "input",
            "props": {
              "label": "Contact Email",
              "placeholder": "platform-team@example.com",
              "description": "Technical contact email address",
              "required": true
            }
          }
        ]
      }
    ]
  }
}
```

References

```
❯ cue export ./forms/platform/ --out yaml | yq
apiVersion: forms.holos.run/v1alpha1
kind: PlatformForm
metadata:
  name: bare
spec:
  sections:
    - name: org
      displayName: Organization
      description: Organization config values are used to derive more specific configuration values throughout the platform.
      fieldConfigs:
        - key: name
          type: input
          props:
            label: Name
            placeholder: example
            description: DNS label, e.g. 'example'
            required: true
        - key: domain
          type: input
          props:
            label: Domain
            placeholder: example.com
            description: DNS domain, e.g. 'example.com'
            required: true
        - key: displayName
          type: input
          props:
            label: Display Name
            placeholder: Example Organization
            description: Display name, e.g. 'Example Organization'
            required: true
        - key: contactEmail
          type: input
          props:
            label: Contact Email
            placeholder: platform-team@example.com
            description: Technical contact email address
            required: true
```
2024-04-29 14:24:16 -07:00
Jeff McCune
26e537e768 (#150) Add platform config form, values, cue
This patch adds 4 fields to the Platform table:

 1. Config Form represents the JSON FormlyFieldConfig for the UI.
 2. Config CUE represents the CUE file containing a definition the
    Config Values must unify with.
 3. Config Definition is the CUE definition variable name used to unify
    the values with the cue code.  Should be #PlatformSpec in most
    cases.
 4. Config Values represents the JSON values provided by the UI.

The use case is the platform engineer defines the #PlatformSpec in cue,
and provides the form field config.  The platform engineer then provides
1-3 above when adding or updating a Platform.

The UI then presents the form to the end user and provides values for 4
when the user submits the form.

This patch also refactors the AddPlatform method to accept a Platform
message.  To do so we make the id field optional since it is server
assigned.

The patch also adds a database constraint to ensure platform names are
unique within the scope of an organization.

Results:

Note how the CUE representation of the Platform Form is exported to JSON
then converted to a base64 encoded string, which is the protobuf JSON
representation of a bytes[] value.

```
grpcurl -H "x-oidc-id-token: $(holos token)" -d @ jeff.app.dev.k2.holos.run:443 holos.v1alpha1.PlatformService.AddPlatform <<EOF
{
  "platform": {
    "id": "0d3dc0c0-bbc8-41f8-8c6e-75f0476509d6",
    "org_id": "018f27cd-e5ac-7f98-bfe1-2dbab208a48c",
    "name": "bare",
    "config": {
      "form": "$(cd internal/platforms/bare && cue export ./forms/platform/ --out json | jq -cM | base64 -w0)"
    }
  }
}
EOF
```

Note the requested platform ID is ignored.

```
{
  "platforms": [
    {
      "id": "018f2af9-f7ba-772a-9db6-f985ece8fed1",
      "timestamps": {
        "createdAt": "2024-04-29T17:49:36.058379Z",
        "updatedAt": "2024-04-29T17:49:36.058379Z"
      },
      "name": "bare",
      "creator": {
        "id": "018f27cd-e591-7f98-a9d2-416167282d37"
      },
      "config": {
        "form": "eyJhcGlWZXJzaW9uIjoiZm9ybXMuaG9sb3MucnVuL3YxYWxwaGExIiwia2luZCI6IlBsYXRmb3JtRm9ybSIsIm1ldGFkYXRhIjp7Im5hbWUiOiJiYXJlIn0sInNwZWMiOnsic2VjdGlvbnMiOlt7Im5hbWUiOiJvcmciLCJkaXNwbGF5TmFtZSI6Ik9yZ2FuaXphdGlvbiIsImRlc2NyaXB0aW9uIjoiT3JnYW5pemF0aW9uIGNvbmZpZyB2YWx1ZXMgYXJlIHVzZWQgdG8gZGVyaXZlIG1vcmUgc3BlY2lmaWMgY29uZmlndXJhdGlvbiB2YWx1ZXMgdGhyb3VnaG91dCB0aGUgcGxhdGZvcm0uIiwiZmllbGRDb25maWdzIjpbeyJrZXkiOiJuYW1lIiwidHlwZSI6ImlucHV0IiwicHJvcHMiOnsibGFiZWwiOiJOYW1lIiwicGxhY2Vob2xkZXIiOiJleGFtcGxlIiwiZGVzY3JpcHRpb24iOiJETlMgbGFiZWwsIGUuZy4gJ2V4YW1wbGUnIiwicmVxdWlyZWQiOnRydWV9fSx7ImtleSI6ImRvbWFpbiIsInR5cGUiOiJpbnB1dCIsInByb3BzIjp7ImxhYmVsIjoiRG9tYWluIiwicGxhY2Vob2xkZXIiOiJleGFtcGxlLmNvbSIsImRlc2NyaXB0aW9uIjoiRE5TIGRvbWFpbiwgZS5nLiAnZXhhbXBsZS5jb20nIiwicmVxdWlyZWQiOnRydWV9fSx7ImtleSI6ImRpc3BsYXlOYW1lIiwidHlwZSI6ImlucHV0IiwicHJvcHMiOnsibGFiZWwiOiJEaXNwbGF5IE5hbWUiLCJwbGFjZWhvbGRlciI6IkV4YW1wbGUgT3JnYW5pemF0aW9uIiwiZGVzY3JpcHRpb24iOiJEaXNwbGF5IG5hbWUsIGUuZy4gJ0V4YW1wbGUgT3JnYW5pemF0aW9uJyIsInJlcXVpcmVkIjp0cnVlfX0seyJrZXkiOiJjb250YWN0RW1haWwiLCJ0eXBlIjoiaW5wdXQiLCJwcm9wcyI6eyJsYWJlbCI6IkNvbnRhY3QgRW1haWwiLCJwbGFjZWhvbGRlciI6InBsYXRmb3JtLXRlYW1AZXhhbXBsZS5jb20iLCJkZXNjcmlwdGlvbiI6IlRlY2huaWNhbCBjb250YWN0IGVtYWlsIGFkZHJlc3MiLCJyZXF1aXJlZCI6dHJ1ZX19XX1dfX0K"
      }
    }
  ]
}
```
2024-04-29 10:53:23 -07:00
Jeff McCune
ad70a6c4fe (#150) Add holos.v1alpha1.PlatformService.AddPlatform
This patch adds a basic AddPlatform method that adds a platform with a
name and a display name.

Next steps are to add fields for the Platform Config Form definition and
the Platform Config values submitted from the form.
2024-04-29 09:35:49 -07:00
Jeff McCune
22a04da6bb (#150) Add holos.v1alpha1.PlatformService.GetPlatforms
Next step: AddPlatform

Also consider extracting the queries to get the requested org_id to a
helper function.  This will likely eventually move to an interceptor
because every request is org scoped and needs authorization checks
against the org.

```
grpcurl -H "x-oidc-id-token: $(holos token)" -d '{"org_id":"018f27cd-e5ac-7f98-bfe1-2dbab208a48c"}' jeff.app.dev.k2.holos.run:443 holos.v1alpha1.PlatformService.GetPlatforms
```
2024-04-28 20:21:32 -07:00
Jeff McCune
dc97fe0ff0 (#150) Define a PlatformForm for platform design
Problem:
Platform engineers need the ability to define custom input fields for
their own platform level configuration values.  The holos web UI needs
to present the platform config values in a clean way.  The values
entered on the form need to make their way into the top level
Platform.spec field for use across all components and clusters in the
platform.

Solution:
Define a Platform Form in a forms cue package.  The output of this
definition is intended to be sent to the holos server to provide to the
web UI.

Result:
Platform engineers can define their platform config input values in
their infrastructure repository.  For example, the bare platform form
inputs are defined at `platforms/bare/forms/platform/platform-form.cue`.

This cue file produces [FormlyFieldConfig][1] output.

```console
cue export ./forms/platform/ --out yaml
```

```yaml
apiVersion: forms.holos.run/v1alpha1
kind: PlatformForm
metadata:
  name: bare
spec:
  sections:
    - name: org
      displayName: Organization
      description: Organization config values are used to derive more specific configuration values throughout the platform.
      fieldConfigs:
        - key: name
          type: input
          props:
            label: Name
            placeholder: example
            description: DNS label, e.g. 'example'
            required: true
        - key: domain
          type: input
          props:
            label: Domain
            placeholder: example.com
            description: DNS domain, e.g. 'example.com'
            required: true
        - key: displayName
          type: input
          props:
            label: Display Name
            placeholder: Example Organization
            description: Display name, e.g. 'Example Organization'
            required: true
        - key: contactEmail
          type: input
          props:
            label: Contact Email
            placeholder: platform-team@example.com
            description: Technical contact email address
            required: true
```

Next Steps:
Add a holos subcommand to produce the output and store it in the
backend.  Wire the front end to fetch the form config from the backend.

[1]: https://formly.dev/docs/api/core#formlyfieldconfig
2024-04-28 11:25:06 -07:00
Jeff McCune
9ca97c6e01 Merge pull request #148 from holos-run/jeff/147-cue-oom
(#147) Add holos render --print-instances flag
2024-04-26 16:31:14 -07:00
Jeff McCune
924653e240 (#150) Bare Platform
This patch adds a bare platform that does nothing but render a configmap
containing the platform config structure itself.

The definition of the platform structure is firming up.  The platform
designer, which may be a holos customer, is responsible for defining the
structure of the `platform.spec` output field.

Us holos developers have a reserved namespace to add configuration
fields and data in the `platform.holos` output file.

Beyond these two fields, the platform config structure has TypeMeta and
ObjectMeta fields similar to a kubernetes api object to support
versioning the platform config data, naming the platform, annotating the
platform, and labeling the platform.

The path forward from here is to:

 1. Eventually move the stable definitions into a CUE module that gets
    imported into the user's package.
 2. As a platform designer, add the organization field to the
    #PlatformSpec definition as a CUE definition.
 3. As a platform designer, add the organization field Form data
    structure as a JSON file.
 4. Add an API to upload the #PlatformSpec cue file and the
    #PlatformSpec form json file to the saas backend.
 5. Wire up Angular to pull the form json from the API and render the
    form.
 6. Wire up Angular to write the form data to a gRPC service method.
 7. Wire up the `holos cli` to read the form data from a gRPC service
    method.
 8. Tie it all together where the holos cli renders the configmap.
2024-04-26 16:14:30 -07:00
Jeff McCune
59d48f8599 (#146) Platform Config Mock Up
This patch adds a mock up of the platform config.  The goal is to use
this to connect to an anemic example platform built from `holos init`.
2024-04-26 11:29:58 -07:00
Jeff McCune
9ae45e260d (#147) Add holos render --print-instances flag
To enumerate all of the instances that could be run in separate
processes with xargs instead of run in the for loop in the Builder Run
method.
2024-04-25 13:59:10 -07:00
143 changed files with 19895 additions and 201 deletions

View File

@@ -9,8 +9,9 @@ import (
type BuildPlan struct {
TypeMeta `json:",inline" yaml:",inline"`
// Metadata represents the holos component name
Metadata ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
Spec BuildPlanSpec `json:"spec,omitempty" yaml:"spec,omitempty"`
Metadata ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
Spec BuildPlanSpec `json:"spec,omitempty" yaml:"spec,omitempty"`
Platform map[string]any `json:"platform,omitempty" yaml:"platform,omitempty"`
}
type BuildPlanSpec struct {

16
hack/setup/bare Executable file
View File

@@ -0,0 +1,16 @@
#! /bin/bash
set -euo pipefail
TOPLEVEL="$(cd $(dirname "$0") && git rev-parse --show-toplevel)"
host="jeff.app.dev.k2.holos.run:443"
read -p "Reset all data in $host? " choice
case "$choice" in
y|Y) echo "proceeding...";;
*) exit 1;;
esac
grpcurl -H "x-oidc-id-token: $(holos token)" $host holos.v1alpha1.SystemService.DropTables
grpcurl -H "x-oidc-id-token: $(holos token)" $host holos.v1alpha1.SystemService.SeedDatabase

View File

@@ -1,6 +1,7 @@
package render
import (
"flag"
"fmt"
"github.com/holos-run/holos/internal/cli/command"
@@ -11,8 +12,21 @@ import (
"github.com/spf13/cobra"
)
func makeRenderRunFunc(cfg *holos.Config) command.RunFunc {
return func(cmd *cobra.Command, args []string) error {
// New returns the render subcommand for the root command
func New(cfg *holos.Config) *cobra.Command {
cmd := command.New("render [directory...]")
cmd.Args = cobra.MinimumNArgs(1)
cmd.Short = "write kubernetes api objects to the filesystem"
cmd.Flags().SortFlags = false
cmd.Flags().AddGoFlagSet(cfg.WriteFlagSet())
cmd.Flags().AddGoFlagSet(cfg.ClusterFlagSet())
var printInstances bool
flagSet := flag.NewFlagSet("", flag.ContinueOnError)
flagSet.BoolVar(&printInstances, "print-instances", false, "expand /... paths for xargs")
cmd.Flags().AddGoFlagSet(flagSet)
cmd.RunE = func(cmd *cobra.Command, args []string) error {
if cfg.ClusterName() == "" {
return errors.Wrap(fmt.Errorf("missing cluster name"))
}
@@ -20,6 +34,18 @@ func makeRenderRunFunc(cfg *holos.Config) command.RunFunc {
ctx := cmd.Context()
log := logger.FromContext(ctx).With("cluster", cfg.ClusterName())
build := builder.New(builder.Entrypoints(args), builder.Cluster(cfg.ClusterName()))
if printInstances {
instances, err := build.Instances(ctx)
if err != nil {
return errors.Wrap(err)
}
for _, instance := range instances {
fmt.Fprintln(cmd.OutOrStdout(), instance.Dir)
}
return nil
}
results, err := build.Run(cmd.Context())
if err != nil {
return errors.Wrap(err)
@@ -45,16 +71,5 @@ func makeRenderRunFunc(cfg *holos.Config) command.RunFunc {
}
return nil
}
}
// New returns the render subcommand for the root command
func New(cfg *holos.Config) *cobra.Command {
cmd := command.New("render [directory...]")
cmd.Args = cobra.MinimumNArgs(1)
cmd.Short = "write kubernetes api objects to the filesystem"
cmd.Flags().SortFlags = false
cmd.Flags().AddGoFlagSet(cfg.WriteFlagSet())
cmd.Flags().AddGoFlagSet(cfg.ClusterFlagSet())
cmd.RunE = makeRenderRunFunc(cfg)
return cmd
}

View File

@@ -17,6 +17,7 @@ import (
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"github.com/holos-run/holos/internal/ent/organization"
entplatform "github.com/holos-run/holos/internal/ent/platform"
"github.com/holos-run/holos/internal/ent/user"
)
@@ -27,6 +28,8 @@ type Client struct {
Schema *migrate.Schema
// Organization is the client for interacting with the Organization builders.
Organization *OrganizationClient
// Platform is the client for interacting with the Platform builders.
Platform *PlatformClient
// User is the client for interacting with the User builders.
User *UserClient
}
@@ -41,6 +44,7 @@ func NewClient(opts ...Option) *Client {
func (c *Client) init() {
c.Schema = migrate.NewSchema(c.driver)
c.Organization = NewOrganizationClient(c.config)
c.Platform = NewPlatformClient(c.config)
c.User = NewUserClient(c.config)
}
@@ -135,6 +139,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) {
ctx: ctx,
config: cfg,
Organization: NewOrganizationClient(cfg),
Platform: NewPlatformClient(cfg),
User: NewUserClient(cfg),
}, nil
}
@@ -156,6 +161,7 @@ func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error)
ctx: ctx,
config: cfg,
Organization: NewOrganizationClient(cfg),
Platform: NewPlatformClient(cfg),
User: NewUserClient(cfg),
}, nil
}
@@ -186,6 +192,7 @@ func (c *Client) Close() error {
// In order to add hooks to a specific client, call: `client.Node.Use(...)`.
func (c *Client) Use(hooks ...Hook) {
c.Organization.Use(hooks...)
c.Platform.Use(hooks...)
c.User.Use(hooks...)
}
@@ -193,6 +200,7 @@ func (c *Client) Use(hooks ...Hook) {
// In order to add interceptors to a specific client, call: `client.Node.Intercept(...)`.
func (c *Client) Intercept(interceptors ...Interceptor) {
c.Organization.Intercept(interceptors...)
c.Platform.Intercept(interceptors...)
c.User.Intercept(interceptors...)
}
@@ -201,6 +209,8 @@ func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) {
switch m := m.(type) {
case *OrganizationMutation:
return c.Organization.mutate(ctx, m)
case *PlatformMutation:
return c.Platform.mutate(ctx, m)
case *UserMutation:
return c.User.mutate(ctx, m)
default:
@@ -348,6 +358,22 @@ func (c *OrganizationClient) QueryUsers(o *Organization) *UserQuery {
return query
}
// QueryPlatforms queries the platforms edge of a Organization.
func (c *OrganizationClient) QueryPlatforms(o *Organization) *PlatformQuery {
query := (&PlatformClient{config: c.config}).Query()
query.path = func(context.Context) (fromV *sql.Selector, _ error) {
id := o.ID
step := sqlgraph.NewStep(
sqlgraph.From(organization.Table, organization.FieldID, id),
sqlgraph.To(entplatform.Table, entplatform.FieldID),
sqlgraph.Edge(sqlgraph.O2M, true, organization.PlatformsTable, organization.PlatformsColumn),
)
fromV = sqlgraph.Neighbors(o.driver.Dialect(), step)
return fromV, nil
}
return query
}
// Hooks returns the client hooks.
func (c *OrganizationClient) Hooks() []Hook {
return c.hooks.Organization
@@ -373,6 +399,171 @@ func (c *OrganizationClient) mutate(ctx context.Context, m *OrganizationMutation
}
}
// PlatformClient is a client for the Platform schema.
type PlatformClient struct {
config
}
// NewPlatformClient returns a client for the Platform from the given config.
func NewPlatformClient(c config) *PlatformClient {
return &PlatformClient{config: c}
}
// Use adds a list of mutation hooks to the hooks stack.
// A call to `Use(f, g, h)` equals to `entplatform.Hooks(f(g(h())))`.
func (c *PlatformClient) Use(hooks ...Hook) {
c.hooks.Platform = append(c.hooks.Platform, hooks...)
}
// Intercept adds a list of query interceptors to the interceptors stack.
// A call to `Intercept(f, g, h)` equals to `entplatform.Intercept(f(g(h())))`.
func (c *PlatformClient) Intercept(interceptors ...Interceptor) {
c.inters.Platform = append(c.inters.Platform, interceptors...)
}
// Create returns a builder for creating a Platform entity.
func (c *PlatformClient) Create() *PlatformCreate {
mutation := newPlatformMutation(c.config, OpCreate)
return &PlatformCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// CreateBulk returns a builder for creating a bulk of Platform entities.
func (c *PlatformClient) CreateBulk(builders ...*PlatformCreate) *PlatformCreateBulk {
return &PlatformCreateBulk{config: c.config, builders: builders}
}
// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates
// a builder and applies setFunc on it.
func (c *PlatformClient) MapCreateBulk(slice any, setFunc func(*PlatformCreate, int)) *PlatformCreateBulk {
rv := reflect.ValueOf(slice)
if rv.Kind() != reflect.Slice {
return &PlatformCreateBulk{err: fmt.Errorf("calling to PlatformClient.MapCreateBulk with wrong type %T, need slice", slice)}
}
builders := make([]*PlatformCreate, rv.Len())
for i := 0; i < rv.Len(); i++ {
builders[i] = c.Create()
setFunc(builders[i], i)
}
return &PlatformCreateBulk{config: c.config, builders: builders}
}
// Update returns an update builder for Platform.
func (c *PlatformClient) Update() *PlatformUpdate {
mutation := newPlatformMutation(c.config, OpUpdate)
return &PlatformUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// UpdateOne returns an update builder for the given entity.
func (c *PlatformClient) UpdateOne(pl *Platform) *PlatformUpdateOne {
mutation := newPlatformMutation(c.config, OpUpdateOne, withPlatform(pl))
return &PlatformUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// UpdateOneID returns an update builder for the given id.
func (c *PlatformClient) UpdateOneID(id uuid.UUID) *PlatformUpdateOne {
mutation := newPlatformMutation(c.config, OpUpdateOne, withPlatformID(id))
return &PlatformUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// Delete returns a delete builder for Platform.
func (c *PlatformClient) Delete() *PlatformDelete {
mutation := newPlatformMutation(c.config, OpDelete)
return &PlatformDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// DeleteOne returns a builder for deleting the given entity.
func (c *PlatformClient) DeleteOne(pl *Platform) *PlatformDeleteOne {
return c.DeleteOneID(pl.ID)
}
// DeleteOneID returns a builder for deleting the given entity by its id.
func (c *PlatformClient) DeleteOneID(id uuid.UUID) *PlatformDeleteOne {
builder := c.Delete().Where(entplatform.ID(id))
builder.mutation.id = &id
builder.mutation.op = OpDeleteOne
return &PlatformDeleteOne{builder}
}
// Query returns a query builder for Platform.
func (c *PlatformClient) Query() *PlatformQuery {
return &PlatformQuery{
config: c.config,
ctx: &QueryContext{Type: TypePlatform},
inters: c.Interceptors(),
}
}
// Get returns a Platform entity by its id.
func (c *PlatformClient) Get(ctx context.Context, id uuid.UUID) (*Platform, error) {
return c.Query().Where(entplatform.ID(id)).Only(ctx)
}
// GetX is like Get, but panics if an error occurs.
func (c *PlatformClient) GetX(ctx context.Context, id uuid.UUID) *Platform {
obj, err := c.Get(ctx, id)
if err != nil {
panic(err)
}
return obj
}
// QueryCreator queries the creator edge of a Platform.
func (c *PlatformClient) QueryCreator(pl *Platform) *UserQuery {
query := (&UserClient{config: c.config}).Query()
query.path = func(context.Context) (fromV *sql.Selector, _ error) {
id := pl.ID
step := sqlgraph.NewStep(
sqlgraph.From(entplatform.Table, entplatform.FieldID, id),
sqlgraph.To(user.Table, user.FieldID),
sqlgraph.Edge(sqlgraph.M2O, false, entplatform.CreatorTable, entplatform.CreatorColumn),
)
fromV = sqlgraph.Neighbors(pl.driver.Dialect(), step)
return fromV, nil
}
return query
}
// QueryOrganization queries the organization edge of a Platform.
func (c *PlatformClient) QueryOrganization(pl *Platform) *OrganizationQuery {
query := (&OrganizationClient{config: c.config}).Query()
query.path = func(context.Context) (fromV *sql.Selector, _ error) {
id := pl.ID
step := sqlgraph.NewStep(
sqlgraph.From(entplatform.Table, entplatform.FieldID, id),
sqlgraph.To(organization.Table, organization.FieldID),
sqlgraph.Edge(sqlgraph.M2O, false, entplatform.OrganizationTable, entplatform.OrganizationColumn),
)
fromV = sqlgraph.Neighbors(pl.driver.Dialect(), step)
return fromV, nil
}
return query
}
// Hooks returns the client hooks.
func (c *PlatformClient) Hooks() []Hook {
return c.hooks.Platform
}
// Interceptors returns the client interceptors.
func (c *PlatformClient) Interceptors() []Interceptor {
return c.inters.Platform
}
func (c *PlatformClient) mutate(ctx context.Context, m *PlatformMutation) (Value, error) {
switch m.Op() {
case OpCreate:
return (&PlatformCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
case OpUpdate:
return (&PlatformUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
case OpUpdateOne:
return (&PlatformUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
case OpDelete, OpDeleteOne:
return (&PlatformDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx)
default:
return nil, fmt.Errorf("ent: unknown Platform mutation op: %q", m.Op())
}
}
// UserClient is a client for the User schema.
type UserClient struct {
config
@@ -525,9 +716,9 @@ func (c *UserClient) mutate(ctx context.Context, m *UserMutation) (Value, error)
// hooks and interceptors per client, for fast access.
type (
hooks struct {
Organization, User []ent.Hook
Organization, Platform, User []ent.Hook
}
inters struct {
Organization, User []ent.Interceptor
Organization, Platform, User []ent.Interceptor
}
)

View File

@@ -13,6 +13,8 @@ import (
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"github.com/holos-run/holos/internal/ent/organization"
entplatform "github.com/holos-run/holos/internal/ent/platform"
"github.com/holos-run/holos/internal/ent/user"
)
@@ -75,6 +77,7 @@ func checkColumn(table, column string) error {
initCheck.Do(func() {
columnCheck = sql.NewColumnCheck(map[string]func(string) bool{
organization.Table: organization.ValidColumn,
entplatform.Table: entplatform.ValidColumn,
user.Table: user.ValidColumn,
})
})

View File

@@ -21,6 +21,18 @@ func (f OrganizationFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.OrganizationMutation", m)
}
// The PlatformFunc type is an adapter to allow the use of ordinary
// function as Platform mutator.
type PlatformFunc func(context.Context, *ent.PlatformMutation) (ent.Value, error)
// Mutate calls f(ctx, m).
func (f PlatformFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
if mv, ok := m.(*ent.PlatformMutation); ok {
return f(ctx, mv)
}
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.PlatformMutation", m)
}
// The UserFunc type is an adapter to allow the use of ordinary
// function as User mutator.
type UserFunc func(context.Context, *ent.UserMutation) (ent.Value, error)

View File

@@ -31,6 +31,47 @@ var (
},
},
}
// PlatformsColumns holds the columns for the "platforms" table.
PlatformsColumns = []*schema.Column{
{Name: "id", Type: field.TypeUUID},
{Name: "created_at", Type: field.TypeTime},
{Name: "updated_at", Type: field.TypeTime},
{Name: "name", Type: field.TypeString},
{Name: "display_name", Type: field.TypeString},
{Name: "form", Type: field.TypeJSON, Nullable: true},
{Name: "model", Type: field.TypeJSON, Nullable: true},
{Name: "cue", Type: field.TypeBytes, Nullable: true},
{Name: "cue_definition", Type: field.TypeString, Nullable: true},
{Name: "creator_id", Type: field.TypeUUID},
{Name: "org_id", Type: field.TypeUUID},
}
// PlatformsTable holds the schema information for the "platforms" table.
PlatformsTable = &schema.Table{
Name: "platforms",
Columns: PlatformsColumns,
PrimaryKey: []*schema.Column{PlatformsColumns[0]},
ForeignKeys: []*schema.ForeignKey{
{
Symbol: "platforms_users_creator",
Columns: []*schema.Column{PlatformsColumns[9]},
RefColumns: []*schema.Column{UsersColumns[0]},
OnDelete: schema.NoAction,
},
{
Symbol: "platforms_organizations_organization",
Columns: []*schema.Column{PlatformsColumns[10]},
RefColumns: []*schema.Column{OrganizationsColumns[0]},
OnDelete: schema.NoAction,
},
},
Indexes: []*schema.Index{
{
Name: "platform_org_id_name",
Unique: true,
Columns: []*schema.Column{PlatformsColumns[10], PlatformsColumns[3]},
},
},
}
// UsersColumns holds the columns for the "users" table.
UsersColumns = []*schema.Column{
{Name: "id", Type: field.TypeUUID},
@@ -82,6 +123,7 @@ var (
// Tables holds all the tables in the schema.
Tables = []*schema.Table{
OrganizationsTable,
PlatformsTable,
UsersTable,
OrganizationUsersTable,
}
@@ -89,6 +131,8 @@ var (
func init() {
OrganizationsTable.ForeignKeys[0].RefTable = UsersTable
PlatformsTable.ForeignKeys[0].RefTable = UsersTable
PlatformsTable.ForeignKeys[1].RefTable = OrganizationsTable
OrganizationUsersTable.ForeignKeys[0].RefTable = OrganizationsTable
OrganizationUsersTable.ForeignKeys[1].RefTable = UsersTable
}

File diff suppressed because it is too large Load Diff

View File

@@ -41,9 +41,11 @@ type OrganizationEdges struct {
Creator *User `json:"creator,omitempty"`
// Users holds the value of the users edge.
Users []*User `json:"users,omitempty"`
// Platforms holds the value of the platforms edge.
Platforms []*Platform `json:"platforms,omitempty"`
// loadedTypes holds the information for reporting if a
// type was loaded (or requested) in eager-loading or not.
loadedTypes [2]bool
loadedTypes [3]bool
}
// CreatorOrErr returns the Creator value or an error if the edge
@@ -66,6 +68,15 @@ func (e OrganizationEdges) UsersOrErr() ([]*User, error) {
return nil, &NotLoadedError{edge: "users"}
}
// PlatformsOrErr returns the Platforms value or an error if the edge
// was not loaded in eager-loading.
func (e OrganizationEdges) PlatformsOrErr() ([]*Platform, error) {
if e.loadedTypes[2] {
return e.Platforms, nil
}
return nil, &NotLoadedError{edge: "platforms"}
}
// scanValues returns the types for scanning values from sql.Rows.
func (*Organization) scanValues(columns []string) ([]any, error) {
values := make([]any, len(columns))
@@ -151,6 +162,11 @@ func (o *Organization) QueryUsers() *UserQuery {
return NewOrganizationClient(o.config).QueryUsers(o)
}
// QueryPlatforms queries the "platforms" edge of the Organization entity.
func (o *Organization) QueryPlatforms() *PlatformQuery {
return NewOrganizationClient(o.config).QueryPlatforms(o)
}
// Update returns a builder for updating this Organization.
// Note that you need to call Organization.Unwrap() before calling this method if this Organization
// was returned from a transaction, and the transaction was committed or rolled back.

View File

@@ -29,6 +29,8 @@ const (
EdgeCreator = "creator"
// EdgeUsers holds the string denoting the users edge name in mutations.
EdgeUsers = "users"
// EdgePlatforms holds the string denoting the platforms edge name in mutations.
EdgePlatforms = "platforms"
// Table holds the table name of the organization in the database.
Table = "organizations"
// CreatorTable is the table that holds the creator relation/edge.
@@ -43,6 +45,13 @@ const (
// UsersInverseTable is the table name for the User entity.
// It exists in this package in order to avoid circular dependency with the "user" package.
UsersInverseTable = "users"
// PlatformsTable is the table that holds the platforms relation/edge.
PlatformsTable = "platforms"
// PlatformsInverseTable is the table name for the Platform entity.
// It exists in this package in order to avoid circular dependency with the "entplatform" package.
PlatformsInverseTable = "platforms"
// PlatformsColumn is the table column denoting the platforms relation/edge.
PlatformsColumn = "org_id"
)
// Columns holds all SQL columns for organization fields.
@@ -137,6 +146,20 @@ func ByUsers(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
sqlgraph.OrderByNeighborTerms(s, newUsersStep(), append([]sql.OrderTerm{term}, terms...)...)
}
}
// ByPlatformsCount orders the results by platforms count.
func ByPlatformsCount(opts ...sql.OrderTermOption) OrderOption {
return func(s *sql.Selector) {
sqlgraph.OrderByNeighborsCount(s, newPlatformsStep(), opts...)
}
}
// ByPlatforms orders the results by platforms terms.
func ByPlatforms(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
return func(s *sql.Selector) {
sqlgraph.OrderByNeighborTerms(s, newPlatformsStep(), append([]sql.OrderTerm{term}, terms...)...)
}
}
func newCreatorStep() *sqlgraph.Step {
return sqlgraph.NewStep(
sqlgraph.From(Table, FieldID),
@@ -151,3 +174,10 @@ func newUsersStep() *sqlgraph.Step {
sqlgraph.Edge(sqlgraph.M2M, false, UsersTable, UsersPrimaryKey...),
)
}
func newPlatformsStep() *sqlgraph.Step {
return sqlgraph.NewStep(
sqlgraph.From(Table, FieldID),
sqlgraph.To(PlatformsInverseTable, FieldID),
sqlgraph.Edge(sqlgraph.O2M, true, PlatformsTable, PlatformsColumn),
)
}

View File

@@ -357,6 +357,29 @@ func HasUsersWith(preds ...predicate.User) predicate.Organization {
})
}
// HasPlatforms applies the HasEdge predicate on the "platforms" edge.
func HasPlatforms() predicate.Organization {
return predicate.Organization(func(s *sql.Selector) {
step := sqlgraph.NewStep(
sqlgraph.From(Table, FieldID),
sqlgraph.Edge(sqlgraph.O2M, true, PlatformsTable, PlatformsColumn),
)
sqlgraph.HasNeighbors(s, step)
})
}
// HasPlatformsWith applies the HasEdge predicate on the "platforms" edge with a given conditions (other predicates).
func HasPlatformsWith(preds ...predicate.Platform) predicate.Organization {
return predicate.Organization(func(s *sql.Selector) {
step := newPlatformsStep()
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
for _, p := range preds {
p(s)
}
})
})
}
// And groups predicates with the AND operator between them.
func And(predicates ...predicate.Organization) predicate.Organization {
return predicate.Organization(sql.AndPredicates(predicates...))

View File

@@ -14,6 +14,7 @@ import (
"entgo.io/ent/schema/field"
"github.com/gofrs/uuid"
"github.com/holos-run/holos/internal/ent/organization"
entplatform "github.com/holos-run/holos/internal/ent/platform"
"github.com/holos-run/holos/internal/ent/user"
)
@@ -105,6 +106,21 @@ func (oc *OrganizationCreate) AddUsers(u ...*User) *OrganizationCreate {
return oc.AddUserIDs(ids...)
}
// AddPlatformIDs adds the "platforms" edge to the Platform entity by IDs.
func (oc *OrganizationCreate) AddPlatformIDs(ids ...uuid.UUID) *OrganizationCreate {
oc.mutation.AddPlatformIDs(ids...)
return oc
}
// AddPlatforms adds the "platforms" edges to the Platform entity.
func (oc *OrganizationCreate) AddPlatforms(p ...*Platform) *OrganizationCreate {
ids := make([]uuid.UUID, len(p))
for i := range p {
ids[i] = p[i].ID
}
return oc.AddPlatformIDs(ids...)
}
// Mutation returns the OrganizationMutation object of the builder.
func (oc *OrganizationCreate) Mutation() *OrganizationMutation {
return oc.mutation
@@ -264,6 +280,22 @@ func (oc *OrganizationCreate) createSpec() (*Organization, *sqlgraph.CreateSpec)
}
_spec.Edges = append(_spec.Edges, edge)
}
if nodes := oc.mutation.PlatformsIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
Inverse: true,
Table: organization.PlatformsTable,
Columns: []string{organization.PlatformsColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(entplatform.FieldID, field.TypeUUID),
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges = append(_spec.Edges, edge)
}
return _node, _spec
}

View File

@@ -13,6 +13,7 @@ import (
"entgo.io/ent/schema/field"
"github.com/gofrs/uuid"
"github.com/holos-run/holos/internal/ent/organization"
entplatform "github.com/holos-run/holos/internal/ent/platform"
"github.com/holos-run/holos/internal/ent/predicate"
"github.com/holos-run/holos/internal/ent/user"
)
@@ -20,12 +21,13 @@ import (
// OrganizationQuery is the builder for querying Organization entities.
type OrganizationQuery struct {
config
ctx *QueryContext
order []organization.OrderOption
inters []Interceptor
predicates []predicate.Organization
withCreator *UserQuery
withUsers *UserQuery
ctx *QueryContext
order []organization.OrderOption
inters []Interceptor
predicates []predicate.Organization
withCreator *UserQuery
withUsers *UserQuery
withPlatforms *PlatformQuery
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
@@ -106,6 +108,28 @@ func (oq *OrganizationQuery) QueryUsers() *UserQuery {
return query
}
// QueryPlatforms chains the current query on the "platforms" edge.
func (oq *OrganizationQuery) QueryPlatforms() *PlatformQuery {
query := (&PlatformClient{config: oq.config}).Query()
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
if err := oq.prepareQuery(ctx); err != nil {
return nil, err
}
selector := oq.sqlQuery(ctx)
if err := selector.Err(); err != nil {
return nil, err
}
step := sqlgraph.NewStep(
sqlgraph.From(organization.Table, organization.FieldID, selector),
sqlgraph.To(entplatform.Table, entplatform.FieldID),
sqlgraph.Edge(sqlgraph.O2M, true, organization.PlatformsTable, organization.PlatformsColumn),
)
fromU = sqlgraph.SetNeighbors(oq.driver.Dialect(), step)
return fromU, nil
}
return query
}
// First returns the first Organization entity from the query.
// Returns a *NotFoundError when no Organization was found.
func (oq *OrganizationQuery) First(ctx context.Context) (*Organization, error) {
@@ -293,13 +317,14 @@ func (oq *OrganizationQuery) Clone() *OrganizationQuery {
return nil
}
return &OrganizationQuery{
config: oq.config,
ctx: oq.ctx.Clone(),
order: append([]organization.OrderOption{}, oq.order...),
inters: append([]Interceptor{}, oq.inters...),
predicates: append([]predicate.Organization{}, oq.predicates...),
withCreator: oq.withCreator.Clone(),
withUsers: oq.withUsers.Clone(),
config: oq.config,
ctx: oq.ctx.Clone(),
order: append([]organization.OrderOption{}, oq.order...),
inters: append([]Interceptor{}, oq.inters...),
predicates: append([]predicate.Organization{}, oq.predicates...),
withCreator: oq.withCreator.Clone(),
withUsers: oq.withUsers.Clone(),
withPlatforms: oq.withPlatforms.Clone(),
// clone intermediate query.
sql: oq.sql.Clone(),
path: oq.path,
@@ -328,6 +353,17 @@ func (oq *OrganizationQuery) WithUsers(opts ...func(*UserQuery)) *OrganizationQu
return oq
}
// WithPlatforms tells the query-builder to eager-load the nodes that are connected to
// the "platforms" edge. The optional arguments are used to configure the query builder of the edge.
func (oq *OrganizationQuery) WithPlatforms(opts ...func(*PlatformQuery)) *OrganizationQuery {
query := (&PlatformClient{config: oq.config}).Query()
for _, opt := range opts {
opt(query)
}
oq.withPlatforms = query
return oq
}
// GroupBy is used to group vertices by one or more fields/columns.
// It is often used with aggregate functions, like: count, max, mean, min, sum.
//
@@ -406,9 +442,10 @@ func (oq *OrganizationQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]
var (
nodes = []*Organization{}
_spec = oq.querySpec()
loadedTypes = [2]bool{
loadedTypes = [3]bool{
oq.withCreator != nil,
oq.withUsers != nil,
oq.withPlatforms != nil,
}
)
_spec.ScanValues = func(columns []string) ([]any, error) {
@@ -442,6 +479,13 @@ func (oq *OrganizationQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]
return nil, err
}
}
if query := oq.withPlatforms; query != nil {
if err := oq.loadPlatforms(ctx, query, nodes,
func(n *Organization) { n.Edges.Platforms = []*Platform{} },
func(n *Organization, e *Platform) { n.Edges.Platforms = append(n.Edges.Platforms, e) }); err != nil {
return nil, err
}
}
return nodes, nil
}
@@ -535,6 +579,36 @@ func (oq *OrganizationQuery) loadUsers(ctx context.Context, query *UserQuery, no
}
return nil
}
func (oq *OrganizationQuery) loadPlatforms(ctx context.Context, query *PlatformQuery, nodes []*Organization, init func(*Organization), assign func(*Organization, *Platform)) error {
fks := make([]driver.Value, 0, len(nodes))
nodeids := make(map[uuid.UUID]*Organization)
for i := range nodes {
fks = append(fks, nodes[i].ID)
nodeids[nodes[i].ID] = nodes[i]
if init != nil {
init(nodes[i])
}
}
if len(query.ctx.Fields) > 0 {
query.ctx.AppendFieldOnce(entplatform.FieldOrgID)
}
query.Where(predicate.Platform(func(s *sql.Selector) {
s.Where(sql.InValues(s.C(organization.PlatformsColumn), fks...))
}))
neighbors, err := query.All(ctx)
if err != nil {
return err
}
for _, n := range neighbors {
fk := n.OrgID
node, ok := nodeids[fk]
if !ok {
return fmt.Errorf(`unexpected referenced foreign-key "org_id" returned %v for node %v`, fk, n.ID)
}
assign(node, n)
}
return nil
}
func (oq *OrganizationQuery) sqlCount(ctx context.Context) (int, error) {
_spec := oq.querySpec()

View File

@@ -13,6 +13,7 @@ import (
"entgo.io/ent/schema/field"
"github.com/gofrs/uuid"
"github.com/holos-run/holos/internal/ent/organization"
entplatform "github.com/holos-run/holos/internal/ent/platform"
"github.com/holos-run/holos/internal/ent/predicate"
"github.com/holos-run/holos/internal/ent/user"
)
@@ -98,6 +99,21 @@ func (ou *OrganizationUpdate) AddUsers(u ...*User) *OrganizationUpdate {
return ou.AddUserIDs(ids...)
}
// AddPlatformIDs adds the "platforms" edge to the Platform entity by IDs.
func (ou *OrganizationUpdate) AddPlatformIDs(ids ...uuid.UUID) *OrganizationUpdate {
ou.mutation.AddPlatformIDs(ids...)
return ou
}
// AddPlatforms adds the "platforms" edges to the Platform entity.
func (ou *OrganizationUpdate) AddPlatforms(p ...*Platform) *OrganizationUpdate {
ids := make([]uuid.UUID, len(p))
for i := range p {
ids[i] = p[i].ID
}
return ou.AddPlatformIDs(ids...)
}
// Mutation returns the OrganizationMutation object of the builder.
func (ou *OrganizationUpdate) Mutation() *OrganizationMutation {
return ou.mutation
@@ -130,6 +146,27 @@ func (ou *OrganizationUpdate) RemoveUsers(u ...*User) *OrganizationUpdate {
return ou.RemoveUserIDs(ids...)
}
// ClearPlatforms clears all "platforms" edges to the Platform entity.
func (ou *OrganizationUpdate) ClearPlatforms() *OrganizationUpdate {
ou.mutation.ClearPlatforms()
return ou
}
// RemovePlatformIDs removes the "platforms" edge to Platform entities by IDs.
func (ou *OrganizationUpdate) RemovePlatformIDs(ids ...uuid.UUID) *OrganizationUpdate {
ou.mutation.RemovePlatformIDs(ids...)
return ou
}
// RemovePlatforms removes "platforms" edges to Platform entities.
func (ou *OrganizationUpdate) RemovePlatforms(p ...*Platform) *OrganizationUpdate {
ids := make([]uuid.UUID, len(p))
for i := range p {
ids[i] = p[i].ID
}
return ou.RemovePlatformIDs(ids...)
}
// Save executes the query and returns the number of nodes affected by the update operation.
func (ou *OrganizationUpdate) Save(ctx context.Context) (int, error) {
ou.defaults()
@@ -274,6 +311,51 @@ func (ou *OrganizationUpdate) sqlSave(ctx context.Context) (n int, err error) {
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
if ou.mutation.PlatformsCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
Inverse: true,
Table: organization.PlatformsTable,
Columns: []string{organization.PlatformsColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(entplatform.FieldID, field.TypeUUID),
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := ou.mutation.RemovedPlatformsIDs(); len(nodes) > 0 && !ou.mutation.PlatformsCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
Inverse: true,
Table: organization.PlatformsTable,
Columns: []string{organization.PlatformsColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(entplatform.FieldID, field.TypeUUID),
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := ou.mutation.PlatformsIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
Inverse: true,
Table: organization.PlatformsTable,
Columns: []string{organization.PlatformsColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(entplatform.FieldID, field.TypeUUID),
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
if n, err = sqlgraph.UpdateNodes(ctx, ou.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{organization.Label}
@@ -362,6 +444,21 @@ func (ouo *OrganizationUpdateOne) AddUsers(u ...*User) *OrganizationUpdateOne {
return ouo.AddUserIDs(ids...)
}
// AddPlatformIDs adds the "platforms" edge to the Platform entity by IDs.
func (ouo *OrganizationUpdateOne) AddPlatformIDs(ids ...uuid.UUID) *OrganizationUpdateOne {
ouo.mutation.AddPlatformIDs(ids...)
return ouo
}
// AddPlatforms adds the "platforms" edges to the Platform entity.
func (ouo *OrganizationUpdateOne) AddPlatforms(p ...*Platform) *OrganizationUpdateOne {
ids := make([]uuid.UUID, len(p))
for i := range p {
ids[i] = p[i].ID
}
return ouo.AddPlatformIDs(ids...)
}
// Mutation returns the OrganizationMutation object of the builder.
func (ouo *OrganizationUpdateOne) Mutation() *OrganizationMutation {
return ouo.mutation
@@ -394,6 +491,27 @@ func (ouo *OrganizationUpdateOne) RemoveUsers(u ...*User) *OrganizationUpdateOne
return ouo.RemoveUserIDs(ids...)
}
// ClearPlatforms clears all "platforms" edges to the Platform entity.
func (ouo *OrganizationUpdateOne) ClearPlatforms() *OrganizationUpdateOne {
ouo.mutation.ClearPlatforms()
return ouo
}
// RemovePlatformIDs removes the "platforms" edge to Platform entities by IDs.
func (ouo *OrganizationUpdateOne) RemovePlatformIDs(ids ...uuid.UUID) *OrganizationUpdateOne {
ouo.mutation.RemovePlatformIDs(ids...)
return ouo
}
// RemovePlatforms removes "platforms" edges to Platform entities.
func (ouo *OrganizationUpdateOne) RemovePlatforms(p ...*Platform) *OrganizationUpdateOne {
ids := make([]uuid.UUID, len(p))
for i := range p {
ids[i] = p[i].ID
}
return ouo.RemovePlatformIDs(ids...)
}
// Where appends a list predicates to the OrganizationUpdate builder.
func (ouo *OrganizationUpdateOne) Where(ps ...predicate.Organization) *OrganizationUpdateOne {
ouo.mutation.Where(ps...)
@@ -568,6 +686,51 @@ func (ouo *OrganizationUpdateOne) sqlSave(ctx context.Context) (_node *Organizat
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
if ouo.mutation.PlatformsCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
Inverse: true,
Table: organization.PlatformsTable,
Columns: []string{organization.PlatformsColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(entplatform.FieldID, field.TypeUUID),
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := ouo.mutation.RemovedPlatformsIDs(); len(nodes) > 0 && !ouo.mutation.PlatformsCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
Inverse: true,
Table: organization.PlatformsTable,
Columns: []string{organization.PlatformsColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(entplatform.FieldID, field.TypeUUID),
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := ouo.mutation.PlatformsIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
Inverse: true,
Table: organization.PlatformsTable,
Columns: []string{organization.PlatformsColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(entplatform.FieldID, field.TypeUUID),
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
_node = &Organization{config: ouo.config}
_spec.Assign = _node.assignValues
_spec.ScanValues = _node.scanValues

262
internal/ent/platform.go Normal file
View File

@@ -0,0 +1,262 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"encoding/json"
"fmt"
"strings"
"time"
"entgo.io/ent"
"entgo.io/ent/dialect/sql"
"github.com/gofrs/uuid"
"github.com/holos-run/holos/internal/ent/organization"
entplatform "github.com/holos-run/holos/internal/ent/platform"
"github.com/holos-run/holos/internal/ent/user"
platform "github.com/holos-run/holos/service/gen/holos/platform/v1alpha1"
)
// Platform is the model entity for the Platform schema.
type Platform struct {
config `json:"-"`
// ID of the ent.
ID uuid.UUID `json:"id,omitempty"`
// CreatedAt holds the value of the "created_at" field.
CreatedAt time.Time `json:"created_at,omitempty"`
// UpdatedAt holds the value of the "updated_at" field.
UpdatedAt time.Time `json:"updated_at,omitempty"`
// OrgID holds the value of the "org_id" field.
OrgID uuid.UUID `json:"org_id,omitempty"`
// Name holds the value of the "name" field.
Name string `json:"name,omitempty"`
// DisplayName holds the value of the "display_name" field.
DisplayName string `json:"display_name,omitempty"`
// CreatorID holds the value of the "creator_id" field.
CreatorID uuid.UUID `json:"creator_id,omitempty"`
// JSON representation of FormlyFormConfig[] refer to https://github.com/holos-run/holos/issues/161
Form *platform.Form `json:"form,omitempty"`
// JSON representation of the form model which holds user input values refer to https://github.com/holos-run/holos/issues/161
Model *platform.Model `json:"model,omitempty"`
// CUE definition to vet the model against e.g. #PlatformConfig
Cue []byte `json:"cue,omitempty"`
// The definition name to vet config_values against config_cue e.g. '#PlatformSpec'
CueDefinition string `json:"cue_definition,omitempty"`
// Edges holds the relations/edges for other nodes in the graph.
// The values are being populated by the PlatformQuery when eager-loading is set.
Edges PlatformEdges `json:"edges"`
selectValues sql.SelectValues
}
// PlatformEdges holds the relations/edges for other nodes in the graph.
type PlatformEdges struct {
// Creator holds the value of the creator edge.
Creator *User `json:"creator,omitempty"`
// Organization holds the value of the organization edge.
Organization *Organization `json:"organization,omitempty"`
// loadedTypes holds the information for reporting if a
// type was loaded (or requested) in eager-loading or not.
loadedTypes [2]bool
}
// CreatorOrErr returns the Creator value or an error if the edge
// was not loaded in eager-loading, or loaded but was not found.
func (e PlatformEdges) CreatorOrErr() (*User, error) {
if e.Creator != nil {
return e.Creator, nil
} else if e.loadedTypes[0] {
return nil, &NotFoundError{label: user.Label}
}
return nil, &NotLoadedError{edge: "creator"}
}
// OrganizationOrErr returns the Organization value or an error if the edge
// was not loaded in eager-loading, or loaded but was not found.
func (e PlatformEdges) OrganizationOrErr() (*Organization, error) {
if e.Organization != nil {
return e.Organization, nil
} else if e.loadedTypes[1] {
return nil, &NotFoundError{label: organization.Label}
}
return nil, &NotLoadedError{edge: "organization"}
}
// scanValues returns the types for scanning values from sql.Rows.
func (*Platform) scanValues(columns []string) ([]any, error) {
values := make([]any, len(columns))
for i := range columns {
switch columns[i] {
case entplatform.FieldForm, entplatform.FieldModel, entplatform.FieldCue:
values[i] = new([]byte)
case entplatform.FieldName, entplatform.FieldDisplayName, entplatform.FieldCueDefinition:
values[i] = new(sql.NullString)
case entplatform.FieldCreatedAt, entplatform.FieldUpdatedAt:
values[i] = new(sql.NullTime)
case entplatform.FieldID, entplatform.FieldOrgID, entplatform.FieldCreatorID:
values[i] = new(uuid.UUID)
default:
values[i] = new(sql.UnknownType)
}
}
return values, nil
}
// assignValues assigns the values that were returned from sql.Rows (after scanning)
// to the Platform fields.
func (pl *Platform) assignValues(columns []string, values []any) error {
if m, n := len(values), len(columns); m < n {
return fmt.Errorf("mismatch number of scan values: %d != %d", m, n)
}
for i := range columns {
switch columns[i] {
case entplatform.FieldID:
if value, ok := values[i].(*uuid.UUID); !ok {
return fmt.Errorf("unexpected type %T for field id", values[i])
} else if value != nil {
pl.ID = *value
}
case entplatform.FieldCreatedAt:
if value, ok := values[i].(*sql.NullTime); !ok {
return fmt.Errorf("unexpected type %T for field created_at", values[i])
} else if value.Valid {
pl.CreatedAt = value.Time
}
case entplatform.FieldUpdatedAt:
if value, ok := values[i].(*sql.NullTime); !ok {
return fmt.Errorf("unexpected type %T for field updated_at", values[i])
} else if value.Valid {
pl.UpdatedAt = value.Time
}
case entplatform.FieldOrgID:
if value, ok := values[i].(*uuid.UUID); !ok {
return fmt.Errorf("unexpected type %T for field org_id", values[i])
} else if value != nil {
pl.OrgID = *value
}
case entplatform.FieldName:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field name", values[i])
} else if value.Valid {
pl.Name = value.String
}
case entplatform.FieldDisplayName:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field display_name", values[i])
} else if value.Valid {
pl.DisplayName = value.String
}
case entplatform.FieldCreatorID:
if value, ok := values[i].(*uuid.UUID); !ok {
return fmt.Errorf("unexpected type %T for field creator_id", values[i])
} else if value != nil {
pl.CreatorID = *value
}
case entplatform.FieldForm:
if value, ok := values[i].(*[]byte); !ok {
return fmt.Errorf("unexpected type %T for field form", values[i])
} else if value != nil && len(*value) > 0 {
if err := json.Unmarshal(*value, &pl.Form); err != nil {
return fmt.Errorf("unmarshal field form: %w", err)
}
}
case entplatform.FieldModel:
if value, ok := values[i].(*[]byte); !ok {
return fmt.Errorf("unexpected type %T for field model", values[i])
} else if value != nil && len(*value) > 0 {
if err := json.Unmarshal(*value, &pl.Model); err != nil {
return fmt.Errorf("unmarshal field model: %w", err)
}
}
case entplatform.FieldCue:
if value, ok := values[i].(*[]byte); !ok {
return fmt.Errorf("unexpected type %T for field cue", values[i])
} else if value != nil {
pl.Cue = *value
}
case entplatform.FieldCueDefinition:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field cue_definition", values[i])
} else if value.Valid {
pl.CueDefinition = value.String
}
default:
pl.selectValues.Set(columns[i], values[i])
}
}
return nil
}
// Value returns the ent.Value that was dynamically selected and assigned to the Platform.
// This includes values selected through modifiers, order, etc.
func (pl *Platform) Value(name string) (ent.Value, error) {
return pl.selectValues.Get(name)
}
// QueryCreator queries the "creator" edge of the Platform entity.
func (pl *Platform) QueryCreator() *UserQuery {
return NewPlatformClient(pl.config).QueryCreator(pl)
}
// QueryOrganization queries the "organization" edge of the Platform entity.
func (pl *Platform) QueryOrganization() *OrganizationQuery {
return NewPlatformClient(pl.config).QueryOrganization(pl)
}
// Update returns a builder for updating this Platform.
// Note that you need to call Platform.Unwrap() before calling this method if this Platform
// was returned from a transaction, and the transaction was committed or rolled back.
func (pl *Platform) Update() *PlatformUpdateOne {
return NewPlatformClient(pl.config).UpdateOne(pl)
}
// Unwrap unwraps the Platform entity that was returned from a transaction after it was closed,
// so that all future queries will be executed through the driver which created the transaction.
func (pl *Platform) Unwrap() *Platform {
_tx, ok := pl.config.driver.(*txDriver)
if !ok {
panic("ent: Platform is not a transactional entity")
}
pl.config.driver = _tx.drv
return pl
}
// String implements the fmt.Stringer.
func (pl *Platform) String() string {
var builder strings.Builder
builder.WriteString("Platform(")
builder.WriteString(fmt.Sprintf("id=%v, ", pl.ID))
builder.WriteString("created_at=")
builder.WriteString(pl.CreatedAt.Format(time.ANSIC))
builder.WriteString(", ")
builder.WriteString("updated_at=")
builder.WriteString(pl.UpdatedAt.Format(time.ANSIC))
builder.WriteString(", ")
builder.WriteString("org_id=")
builder.WriteString(fmt.Sprintf("%v", pl.OrgID))
builder.WriteString(", ")
builder.WriteString("name=")
builder.WriteString(pl.Name)
builder.WriteString(", ")
builder.WriteString("display_name=")
builder.WriteString(pl.DisplayName)
builder.WriteString(", ")
builder.WriteString("creator_id=")
builder.WriteString(fmt.Sprintf("%v", pl.CreatorID))
builder.WriteString(", ")
builder.WriteString("form=")
builder.WriteString(fmt.Sprintf("%v", pl.Form))
builder.WriteString(", ")
builder.WriteString("model=")
builder.WriteString(fmt.Sprintf("%v", pl.Model))
builder.WriteString(", ")
builder.WriteString("cue=")
builder.WriteString(fmt.Sprintf("%v", pl.Cue))
builder.WriteString(", ")
builder.WriteString("cue_definition=")
builder.WriteString(pl.CueDefinition)
builder.WriteByte(')')
return builder.String()
}
// Platforms is a parsable slice of Platform.
type Platforms []*Platform

View File

@@ -0,0 +1,167 @@
// Code generated by ent, DO NOT EDIT.
package entplatform
import (
"time"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"github.com/gofrs/uuid"
)
const (
// Label holds the string label denoting the platform type in the database.
Label = "platform"
// FieldID holds the string denoting the id field in the database.
FieldID = "id"
// FieldCreatedAt holds the string denoting the created_at field in the database.
FieldCreatedAt = "created_at"
// FieldUpdatedAt holds the string denoting the updated_at field in the database.
FieldUpdatedAt = "updated_at"
// FieldOrgID holds the string denoting the org_id field in the database.
FieldOrgID = "org_id"
// FieldName holds the string denoting the name field in the database.
FieldName = "name"
// FieldDisplayName holds the string denoting the display_name field in the database.
FieldDisplayName = "display_name"
// FieldCreatorID holds the string denoting the creator_id field in the database.
FieldCreatorID = "creator_id"
// FieldForm holds the string denoting the form field in the database.
FieldForm = "form"
// FieldModel holds the string denoting the model field in the database.
FieldModel = "model"
// FieldCue holds the string denoting the cue field in the database.
FieldCue = "cue"
// FieldCueDefinition holds the string denoting the cue_definition field in the database.
FieldCueDefinition = "cue_definition"
// EdgeCreator holds the string denoting the creator edge name in mutations.
EdgeCreator = "creator"
// EdgeOrganization holds the string denoting the organization edge name in mutations.
EdgeOrganization = "organization"
// Table holds the table name of the platform in the database.
Table = "platforms"
// CreatorTable is the table that holds the creator relation/edge.
CreatorTable = "platforms"
// CreatorInverseTable is the table name for the User entity.
// It exists in this package in order to avoid circular dependency with the "user" package.
CreatorInverseTable = "users"
// CreatorColumn is the table column denoting the creator relation/edge.
CreatorColumn = "creator_id"
// OrganizationTable is the table that holds the organization relation/edge.
OrganizationTable = "platforms"
// OrganizationInverseTable is the table name for the Organization entity.
// It exists in this package in order to avoid circular dependency with the "organization" package.
OrganizationInverseTable = "organizations"
// OrganizationColumn is the table column denoting the organization relation/edge.
OrganizationColumn = "org_id"
)
// Columns holds all SQL columns for platform fields.
var Columns = []string{
FieldID,
FieldCreatedAt,
FieldUpdatedAt,
FieldOrgID,
FieldName,
FieldDisplayName,
FieldCreatorID,
FieldForm,
FieldModel,
FieldCue,
FieldCueDefinition,
}
// ValidColumn reports if the column name is valid (part of the table columns).
func ValidColumn(column string) bool {
for i := range Columns {
if column == Columns[i] {
return true
}
}
return false
}
var (
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
DefaultCreatedAt func() time.Time
// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
DefaultUpdatedAt func() time.Time
// UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field.
UpdateDefaultUpdatedAt func() time.Time
// NameValidator is a validator for the "name" field. It is called by the builders before save.
NameValidator func(string) error
// DefaultID holds the default value on creation for the "id" field.
DefaultID func() uuid.UUID
)
// OrderOption defines the ordering options for the Platform queries.
type OrderOption func(*sql.Selector)
// ByID orders the results by the id field.
func ByID(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldID, opts...).ToFunc()
}
// ByCreatedAt orders the results by the created_at field.
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
}
// ByUpdatedAt orders the results by the updated_at field.
func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc()
}
// ByOrgID orders the results by the org_id field.
func ByOrgID(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldOrgID, opts...).ToFunc()
}
// ByName orders the results by the name field.
func ByName(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldName, opts...).ToFunc()
}
// ByDisplayName orders the results by the display_name field.
func ByDisplayName(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldDisplayName, opts...).ToFunc()
}
// ByCreatorID orders the results by the creator_id field.
func ByCreatorID(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldCreatorID, opts...).ToFunc()
}
// ByCueDefinition orders the results by the cue_definition field.
func ByCueDefinition(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldCueDefinition, opts...).ToFunc()
}
// ByCreatorField orders the results by creator field.
func ByCreatorField(field string, opts ...sql.OrderTermOption) OrderOption {
return func(s *sql.Selector) {
sqlgraph.OrderByNeighborTerms(s, newCreatorStep(), sql.OrderByField(field, opts...))
}
}
// ByOrganizationField orders the results by organization field.
func ByOrganizationField(field string, opts ...sql.OrderTermOption) OrderOption {
return func(s *sql.Selector) {
sqlgraph.OrderByNeighborTerms(s, newOrganizationStep(), sql.OrderByField(field, opts...))
}
}
func newCreatorStep() *sqlgraph.Step {
return sqlgraph.NewStep(
sqlgraph.From(Table, FieldID),
sqlgraph.To(CreatorInverseTable, FieldID),
sqlgraph.Edge(sqlgraph.M2O, false, CreatorTable, CreatorColumn),
)
}
func newOrganizationStep() *sqlgraph.Step {
return sqlgraph.NewStep(
sqlgraph.From(Table, FieldID),
sqlgraph.To(OrganizationInverseTable, FieldID),
sqlgraph.Edge(sqlgraph.M2O, false, OrganizationTable, OrganizationColumn),
)
}

View File

@@ -0,0 +1,553 @@
// Code generated by ent, DO NOT EDIT.
package entplatform
import (
"time"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"github.com/gofrs/uuid"
"github.com/holos-run/holos/internal/ent/predicate"
)
// ID filters vertices based on their ID field.
func ID(id uuid.UUID) predicate.Platform {
return predicate.Platform(sql.FieldEQ(FieldID, id))
}
// IDEQ applies the EQ predicate on the ID field.
func IDEQ(id uuid.UUID) predicate.Platform {
return predicate.Platform(sql.FieldEQ(FieldID, id))
}
// IDNEQ applies the NEQ predicate on the ID field.
func IDNEQ(id uuid.UUID) predicate.Platform {
return predicate.Platform(sql.FieldNEQ(FieldID, id))
}
// IDIn applies the In predicate on the ID field.
func IDIn(ids ...uuid.UUID) predicate.Platform {
return predicate.Platform(sql.FieldIn(FieldID, ids...))
}
// IDNotIn applies the NotIn predicate on the ID field.
func IDNotIn(ids ...uuid.UUID) predicate.Platform {
return predicate.Platform(sql.FieldNotIn(FieldID, ids...))
}
// IDGT applies the GT predicate on the ID field.
func IDGT(id uuid.UUID) predicate.Platform {
return predicate.Platform(sql.FieldGT(FieldID, id))
}
// IDGTE applies the GTE predicate on the ID field.
func IDGTE(id uuid.UUID) predicate.Platform {
return predicate.Platform(sql.FieldGTE(FieldID, id))
}
// IDLT applies the LT predicate on the ID field.
func IDLT(id uuid.UUID) predicate.Platform {
return predicate.Platform(sql.FieldLT(FieldID, id))
}
// IDLTE applies the LTE predicate on the ID field.
func IDLTE(id uuid.UUID) predicate.Platform {
return predicate.Platform(sql.FieldLTE(FieldID, id))
}
// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
func CreatedAt(v time.Time) predicate.Platform {
return predicate.Platform(sql.FieldEQ(FieldCreatedAt, v))
}
// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ.
func UpdatedAt(v time.Time) predicate.Platform {
return predicate.Platform(sql.FieldEQ(FieldUpdatedAt, v))
}
// OrgID applies equality check predicate on the "org_id" field. It's identical to OrgIDEQ.
func OrgID(v uuid.UUID) predicate.Platform {
return predicate.Platform(sql.FieldEQ(FieldOrgID, v))
}
// Name applies equality check predicate on the "name" field. It's identical to NameEQ.
func Name(v string) predicate.Platform {
return predicate.Platform(sql.FieldEQ(FieldName, v))
}
// DisplayName applies equality check predicate on the "display_name" field. It's identical to DisplayNameEQ.
func DisplayName(v string) predicate.Platform {
return predicate.Platform(sql.FieldEQ(FieldDisplayName, v))
}
// CreatorID applies equality check predicate on the "creator_id" field. It's identical to CreatorIDEQ.
func CreatorID(v uuid.UUID) predicate.Platform {
return predicate.Platform(sql.FieldEQ(FieldCreatorID, v))
}
// Cue applies equality check predicate on the "cue" field. It's identical to CueEQ.
func Cue(v []byte) predicate.Platform {
return predicate.Platform(sql.FieldEQ(FieldCue, v))
}
// CueDefinition applies equality check predicate on the "cue_definition" field. It's identical to CueDefinitionEQ.
func CueDefinition(v string) predicate.Platform {
return predicate.Platform(sql.FieldEQ(FieldCueDefinition, v))
}
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
func CreatedAtEQ(v time.Time) predicate.Platform {
return predicate.Platform(sql.FieldEQ(FieldCreatedAt, v))
}
// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
func CreatedAtNEQ(v time.Time) predicate.Platform {
return predicate.Platform(sql.FieldNEQ(FieldCreatedAt, v))
}
// CreatedAtIn applies the In predicate on the "created_at" field.
func CreatedAtIn(vs ...time.Time) predicate.Platform {
return predicate.Platform(sql.FieldIn(FieldCreatedAt, vs...))
}
// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
func CreatedAtNotIn(vs ...time.Time) predicate.Platform {
return predicate.Platform(sql.FieldNotIn(FieldCreatedAt, vs...))
}
// CreatedAtGT applies the GT predicate on the "created_at" field.
func CreatedAtGT(v time.Time) predicate.Platform {
return predicate.Platform(sql.FieldGT(FieldCreatedAt, v))
}
// CreatedAtGTE applies the GTE predicate on the "created_at" field.
func CreatedAtGTE(v time.Time) predicate.Platform {
return predicate.Platform(sql.FieldGTE(FieldCreatedAt, v))
}
// CreatedAtLT applies the LT predicate on the "created_at" field.
func CreatedAtLT(v time.Time) predicate.Platform {
return predicate.Platform(sql.FieldLT(FieldCreatedAt, v))
}
// CreatedAtLTE applies the LTE predicate on the "created_at" field.
func CreatedAtLTE(v time.Time) predicate.Platform {
return predicate.Platform(sql.FieldLTE(FieldCreatedAt, v))
}
// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
func UpdatedAtEQ(v time.Time) predicate.Platform {
return predicate.Platform(sql.FieldEQ(FieldUpdatedAt, v))
}
// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
func UpdatedAtNEQ(v time.Time) predicate.Platform {
return predicate.Platform(sql.FieldNEQ(FieldUpdatedAt, v))
}
// UpdatedAtIn applies the In predicate on the "updated_at" field.
func UpdatedAtIn(vs ...time.Time) predicate.Platform {
return predicate.Platform(sql.FieldIn(FieldUpdatedAt, vs...))
}
// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
func UpdatedAtNotIn(vs ...time.Time) predicate.Platform {
return predicate.Platform(sql.FieldNotIn(FieldUpdatedAt, vs...))
}
// UpdatedAtGT applies the GT predicate on the "updated_at" field.
func UpdatedAtGT(v time.Time) predicate.Platform {
return predicate.Platform(sql.FieldGT(FieldUpdatedAt, v))
}
// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
func UpdatedAtGTE(v time.Time) predicate.Platform {
return predicate.Platform(sql.FieldGTE(FieldUpdatedAt, v))
}
// UpdatedAtLT applies the LT predicate on the "updated_at" field.
func UpdatedAtLT(v time.Time) predicate.Platform {
return predicate.Platform(sql.FieldLT(FieldUpdatedAt, v))
}
// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
func UpdatedAtLTE(v time.Time) predicate.Platform {
return predicate.Platform(sql.FieldLTE(FieldUpdatedAt, v))
}
// OrgIDEQ applies the EQ predicate on the "org_id" field.
func OrgIDEQ(v uuid.UUID) predicate.Platform {
return predicate.Platform(sql.FieldEQ(FieldOrgID, v))
}
// OrgIDNEQ applies the NEQ predicate on the "org_id" field.
func OrgIDNEQ(v uuid.UUID) predicate.Platform {
return predicate.Platform(sql.FieldNEQ(FieldOrgID, v))
}
// OrgIDIn applies the In predicate on the "org_id" field.
func OrgIDIn(vs ...uuid.UUID) predicate.Platform {
return predicate.Platform(sql.FieldIn(FieldOrgID, vs...))
}
// OrgIDNotIn applies the NotIn predicate on the "org_id" field.
func OrgIDNotIn(vs ...uuid.UUID) predicate.Platform {
return predicate.Platform(sql.FieldNotIn(FieldOrgID, vs...))
}
// NameEQ applies the EQ predicate on the "name" field.
func NameEQ(v string) predicate.Platform {
return predicate.Platform(sql.FieldEQ(FieldName, v))
}
// NameNEQ applies the NEQ predicate on the "name" field.
func NameNEQ(v string) predicate.Platform {
return predicate.Platform(sql.FieldNEQ(FieldName, v))
}
// NameIn applies the In predicate on the "name" field.
func NameIn(vs ...string) predicate.Platform {
return predicate.Platform(sql.FieldIn(FieldName, vs...))
}
// NameNotIn applies the NotIn predicate on the "name" field.
func NameNotIn(vs ...string) predicate.Platform {
return predicate.Platform(sql.FieldNotIn(FieldName, vs...))
}
// NameGT applies the GT predicate on the "name" field.
func NameGT(v string) predicate.Platform {
return predicate.Platform(sql.FieldGT(FieldName, v))
}
// NameGTE applies the GTE predicate on the "name" field.
func NameGTE(v string) predicate.Platform {
return predicate.Platform(sql.FieldGTE(FieldName, v))
}
// NameLT applies the LT predicate on the "name" field.
func NameLT(v string) predicate.Platform {
return predicate.Platform(sql.FieldLT(FieldName, v))
}
// NameLTE applies the LTE predicate on the "name" field.
func NameLTE(v string) predicate.Platform {
return predicate.Platform(sql.FieldLTE(FieldName, v))
}
// NameContains applies the Contains predicate on the "name" field.
func NameContains(v string) predicate.Platform {
return predicate.Platform(sql.FieldContains(FieldName, v))
}
// NameHasPrefix applies the HasPrefix predicate on the "name" field.
func NameHasPrefix(v string) predicate.Platform {
return predicate.Platform(sql.FieldHasPrefix(FieldName, v))
}
// NameHasSuffix applies the HasSuffix predicate on the "name" field.
func NameHasSuffix(v string) predicate.Platform {
return predicate.Platform(sql.FieldHasSuffix(FieldName, v))
}
// NameEqualFold applies the EqualFold predicate on the "name" field.
func NameEqualFold(v string) predicate.Platform {
return predicate.Platform(sql.FieldEqualFold(FieldName, v))
}
// NameContainsFold applies the ContainsFold predicate on the "name" field.
func NameContainsFold(v string) predicate.Platform {
return predicate.Platform(sql.FieldContainsFold(FieldName, v))
}
// DisplayNameEQ applies the EQ predicate on the "display_name" field.
func DisplayNameEQ(v string) predicate.Platform {
return predicate.Platform(sql.FieldEQ(FieldDisplayName, v))
}
// DisplayNameNEQ applies the NEQ predicate on the "display_name" field.
func DisplayNameNEQ(v string) predicate.Platform {
return predicate.Platform(sql.FieldNEQ(FieldDisplayName, v))
}
// DisplayNameIn applies the In predicate on the "display_name" field.
func DisplayNameIn(vs ...string) predicate.Platform {
return predicate.Platform(sql.FieldIn(FieldDisplayName, vs...))
}
// DisplayNameNotIn applies the NotIn predicate on the "display_name" field.
func DisplayNameNotIn(vs ...string) predicate.Platform {
return predicate.Platform(sql.FieldNotIn(FieldDisplayName, vs...))
}
// DisplayNameGT applies the GT predicate on the "display_name" field.
func DisplayNameGT(v string) predicate.Platform {
return predicate.Platform(sql.FieldGT(FieldDisplayName, v))
}
// DisplayNameGTE applies the GTE predicate on the "display_name" field.
func DisplayNameGTE(v string) predicate.Platform {
return predicate.Platform(sql.FieldGTE(FieldDisplayName, v))
}
// DisplayNameLT applies the LT predicate on the "display_name" field.
func DisplayNameLT(v string) predicate.Platform {
return predicate.Platform(sql.FieldLT(FieldDisplayName, v))
}
// DisplayNameLTE applies the LTE predicate on the "display_name" field.
func DisplayNameLTE(v string) predicate.Platform {
return predicate.Platform(sql.FieldLTE(FieldDisplayName, v))
}
// DisplayNameContains applies the Contains predicate on the "display_name" field.
func DisplayNameContains(v string) predicate.Platform {
return predicate.Platform(sql.FieldContains(FieldDisplayName, v))
}
// DisplayNameHasPrefix applies the HasPrefix predicate on the "display_name" field.
func DisplayNameHasPrefix(v string) predicate.Platform {
return predicate.Platform(sql.FieldHasPrefix(FieldDisplayName, v))
}
// DisplayNameHasSuffix applies the HasSuffix predicate on the "display_name" field.
func DisplayNameHasSuffix(v string) predicate.Platform {
return predicate.Platform(sql.FieldHasSuffix(FieldDisplayName, v))
}
// DisplayNameEqualFold applies the EqualFold predicate on the "display_name" field.
func DisplayNameEqualFold(v string) predicate.Platform {
return predicate.Platform(sql.FieldEqualFold(FieldDisplayName, v))
}
// DisplayNameContainsFold applies the ContainsFold predicate on the "display_name" field.
func DisplayNameContainsFold(v string) predicate.Platform {
return predicate.Platform(sql.FieldContainsFold(FieldDisplayName, v))
}
// CreatorIDEQ applies the EQ predicate on the "creator_id" field.
func CreatorIDEQ(v uuid.UUID) predicate.Platform {
return predicate.Platform(sql.FieldEQ(FieldCreatorID, v))
}
// CreatorIDNEQ applies the NEQ predicate on the "creator_id" field.
func CreatorIDNEQ(v uuid.UUID) predicate.Platform {
return predicate.Platform(sql.FieldNEQ(FieldCreatorID, v))
}
// CreatorIDIn applies the In predicate on the "creator_id" field.
func CreatorIDIn(vs ...uuid.UUID) predicate.Platform {
return predicate.Platform(sql.FieldIn(FieldCreatorID, vs...))
}
// CreatorIDNotIn applies the NotIn predicate on the "creator_id" field.
func CreatorIDNotIn(vs ...uuid.UUID) predicate.Platform {
return predicate.Platform(sql.FieldNotIn(FieldCreatorID, vs...))
}
// FormIsNil applies the IsNil predicate on the "form" field.
func FormIsNil() predicate.Platform {
return predicate.Platform(sql.FieldIsNull(FieldForm))
}
// FormNotNil applies the NotNil predicate on the "form" field.
func FormNotNil() predicate.Platform {
return predicate.Platform(sql.FieldNotNull(FieldForm))
}
// ModelIsNil applies the IsNil predicate on the "model" field.
func ModelIsNil() predicate.Platform {
return predicate.Platform(sql.FieldIsNull(FieldModel))
}
// ModelNotNil applies the NotNil predicate on the "model" field.
func ModelNotNil() predicate.Platform {
return predicate.Platform(sql.FieldNotNull(FieldModel))
}
// CueEQ applies the EQ predicate on the "cue" field.
func CueEQ(v []byte) predicate.Platform {
return predicate.Platform(sql.FieldEQ(FieldCue, v))
}
// CueNEQ applies the NEQ predicate on the "cue" field.
func CueNEQ(v []byte) predicate.Platform {
return predicate.Platform(sql.FieldNEQ(FieldCue, v))
}
// CueIn applies the In predicate on the "cue" field.
func CueIn(vs ...[]byte) predicate.Platform {
return predicate.Platform(sql.FieldIn(FieldCue, vs...))
}
// CueNotIn applies the NotIn predicate on the "cue" field.
func CueNotIn(vs ...[]byte) predicate.Platform {
return predicate.Platform(sql.FieldNotIn(FieldCue, vs...))
}
// CueGT applies the GT predicate on the "cue" field.
func CueGT(v []byte) predicate.Platform {
return predicate.Platform(sql.FieldGT(FieldCue, v))
}
// CueGTE applies the GTE predicate on the "cue" field.
func CueGTE(v []byte) predicate.Platform {
return predicate.Platform(sql.FieldGTE(FieldCue, v))
}
// CueLT applies the LT predicate on the "cue" field.
func CueLT(v []byte) predicate.Platform {
return predicate.Platform(sql.FieldLT(FieldCue, v))
}
// CueLTE applies the LTE predicate on the "cue" field.
func CueLTE(v []byte) predicate.Platform {
return predicate.Platform(sql.FieldLTE(FieldCue, v))
}
// CueIsNil applies the IsNil predicate on the "cue" field.
func CueIsNil() predicate.Platform {
return predicate.Platform(sql.FieldIsNull(FieldCue))
}
// CueNotNil applies the NotNil predicate on the "cue" field.
func CueNotNil() predicate.Platform {
return predicate.Platform(sql.FieldNotNull(FieldCue))
}
// CueDefinitionEQ applies the EQ predicate on the "cue_definition" field.
func CueDefinitionEQ(v string) predicate.Platform {
return predicate.Platform(sql.FieldEQ(FieldCueDefinition, v))
}
// CueDefinitionNEQ applies the NEQ predicate on the "cue_definition" field.
func CueDefinitionNEQ(v string) predicate.Platform {
return predicate.Platform(sql.FieldNEQ(FieldCueDefinition, v))
}
// CueDefinitionIn applies the In predicate on the "cue_definition" field.
func CueDefinitionIn(vs ...string) predicate.Platform {
return predicate.Platform(sql.FieldIn(FieldCueDefinition, vs...))
}
// CueDefinitionNotIn applies the NotIn predicate on the "cue_definition" field.
func CueDefinitionNotIn(vs ...string) predicate.Platform {
return predicate.Platform(sql.FieldNotIn(FieldCueDefinition, vs...))
}
// CueDefinitionGT applies the GT predicate on the "cue_definition" field.
func CueDefinitionGT(v string) predicate.Platform {
return predicate.Platform(sql.FieldGT(FieldCueDefinition, v))
}
// CueDefinitionGTE applies the GTE predicate on the "cue_definition" field.
func CueDefinitionGTE(v string) predicate.Platform {
return predicate.Platform(sql.FieldGTE(FieldCueDefinition, v))
}
// CueDefinitionLT applies the LT predicate on the "cue_definition" field.
func CueDefinitionLT(v string) predicate.Platform {
return predicate.Platform(sql.FieldLT(FieldCueDefinition, v))
}
// CueDefinitionLTE applies the LTE predicate on the "cue_definition" field.
func CueDefinitionLTE(v string) predicate.Platform {
return predicate.Platform(sql.FieldLTE(FieldCueDefinition, v))
}
// CueDefinitionContains applies the Contains predicate on the "cue_definition" field.
func CueDefinitionContains(v string) predicate.Platform {
return predicate.Platform(sql.FieldContains(FieldCueDefinition, v))
}
// CueDefinitionHasPrefix applies the HasPrefix predicate on the "cue_definition" field.
func CueDefinitionHasPrefix(v string) predicate.Platform {
return predicate.Platform(sql.FieldHasPrefix(FieldCueDefinition, v))
}
// CueDefinitionHasSuffix applies the HasSuffix predicate on the "cue_definition" field.
func CueDefinitionHasSuffix(v string) predicate.Platform {
return predicate.Platform(sql.FieldHasSuffix(FieldCueDefinition, v))
}
// CueDefinitionIsNil applies the IsNil predicate on the "cue_definition" field.
func CueDefinitionIsNil() predicate.Platform {
return predicate.Platform(sql.FieldIsNull(FieldCueDefinition))
}
// CueDefinitionNotNil applies the NotNil predicate on the "cue_definition" field.
func CueDefinitionNotNil() predicate.Platform {
return predicate.Platform(sql.FieldNotNull(FieldCueDefinition))
}
// CueDefinitionEqualFold applies the EqualFold predicate on the "cue_definition" field.
func CueDefinitionEqualFold(v string) predicate.Platform {
return predicate.Platform(sql.FieldEqualFold(FieldCueDefinition, v))
}
// CueDefinitionContainsFold applies the ContainsFold predicate on the "cue_definition" field.
func CueDefinitionContainsFold(v string) predicate.Platform {
return predicate.Platform(sql.FieldContainsFold(FieldCueDefinition, v))
}
// HasCreator applies the HasEdge predicate on the "creator" edge.
func HasCreator() predicate.Platform {
return predicate.Platform(func(s *sql.Selector) {
step := sqlgraph.NewStep(
sqlgraph.From(Table, FieldID),
sqlgraph.Edge(sqlgraph.M2O, false, CreatorTable, CreatorColumn),
)
sqlgraph.HasNeighbors(s, step)
})
}
// HasCreatorWith applies the HasEdge predicate on the "creator" edge with a given conditions (other predicates).
func HasCreatorWith(preds ...predicate.User) predicate.Platform {
return predicate.Platform(func(s *sql.Selector) {
step := newCreatorStep()
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
for _, p := range preds {
p(s)
}
})
})
}
// HasOrganization applies the HasEdge predicate on the "organization" edge.
func HasOrganization() predicate.Platform {
return predicate.Platform(func(s *sql.Selector) {
step := sqlgraph.NewStep(
sqlgraph.From(Table, FieldID),
sqlgraph.Edge(sqlgraph.M2O, false, OrganizationTable, OrganizationColumn),
)
sqlgraph.HasNeighbors(s, step)
})
}
// HasOrganizationWith applies the HasEdge predicate on the "organization" edge with a given conditions (other predicates).
func HasOrganizationWith(preds ...predicate.Organization) predicate.Platform {
return predicate.Platform(func(s *sql.Selector) {
step := newOrganizationStep()
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
for _, p := range preds {
p(s)
}
})
})
}
// And groups predicates with the AND operator between them.
func And(predicates ...predicate.Platform) predicate.Platform {
return predicate.Platform(sql.AndPredicates(predicates...))
}
// Or groups predicates with the OR operator between them.
func Or(predicates ...predicate.Platform) predicate.Platform {
return predicate.Platform(sql.OrPredicates(predicates...))
}
// Not applies the not operator on the given predicate.
func Not(p predicate.Platform) predicate.Platform {
return predicate.Platform(sql.NotPredicates(p))
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,89 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/holos-run/holos/internal/ent/predicate"
entplatform "github.com/holos-run/holos/internal/ent/platform"
)
// PlatformDelete is the builder for deleting a Platform entity.
type PlatformDelete struct {
config
hooks []Hook
mutation *PlatformMutation
}
// Where appends a list predicates to the PlatformDelete builder.
func (pd *PlatformDelete) Where(ps ...predicate.Platform) *PlatformDelete {
pd.mutation.Where(ps...)
return pd
}
// Exec executes the deletion query and returns how many vertices were deleted.
func (pd *PlatformDelete) Exec(ctx context.Context) (int, error) {
return withHooks(ctx, pd.sqlExec, pd.mutation, pd.hooks)
}
// ExecX is like Exec, but panics if an error occurs.
func (pd *PlatformDelete) ExecX(ctx context.Context) int {
n, err := pd.Exec(ctx)
if err != nil {
panic(err)
}
return n
}
func (pd *PlatformDelete) sqlExec(ctx context.Context) (int, error) {
_spec := sqlgraph.NewDeleteSpec(entplatform.Table, sqlgraph.NewFieldSpec(entplatform.FieldID, field.TypeUUID))
if ps := pd.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
affected, err := sqlgraph.DeleteNodes(ctx, pd.driver, _spec)
if err != nil && sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
pd.mutation.done = true
return affected, err
}
// PlatformDeleteOne is the builder for deleting a single Platform entity.
type PlatformDeleteOne struct {
pd *PlatformDelete
}
// Where appends a list predicates to the PlatformDelete builder.
func (pdo *PlatformDeleteOne) Where(ps ...predicate.Platform) *PlatformDeleteOne {
pdo.pd.mutation.Where(ps...)
return pdo
}
// Exec executes the deletion query.
func (pdo *PlatformDeleteOne) Exec(ctx context.Context) error {
n, err := pdo.pd.Exec(ctx)
switch {
case err != nil:
return err
case n == 0:
return &NotFoundError{entplatform.Label}
default:
return nil
}
}
// ExecX is like Exec, but panics if an error occurs.
func (pdo *PlatformDeleteOne) ExecX(ctx context.Context) {
if err := pdo.Exec(ctx); err != nil {
panic(err)
}
}

View File

@@ -0,0 +1,681 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"fmt"
"math"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/gofrs/uuid"
"github.com/holos-run/holos/internal/ent/organization"
entplatform "github.com/holos-run/holos/internal/ent/platform"
"github.com/holos-run/holos/internal/ent/predicate"
"github.com/holos-run/holos/internal/ent/user"
)
// PlatformQuery is the builder for querying Platform entities.
type PlatformQuery struct {
config
ctx *QueryContext
order []entplatform.OrderOption
inters []Interceptor
predicates []predicate.Platform
withCreator *UserQuery
withOrganization *OrganizationQuery
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
}
// Where adds a new predicate for the PlatformQuery builder.
func (pq *PlatformQuery) Where(ps ...predicate.Platform) *PlatformQuery {
pq.predicates = append(pq.predicates, ps...)
return pq
}
// Limit the number of records to be returned by this query.
func (pq *PlatformQuery) Limit(limit int) *PlatformQuery {
pq.ctx.Limit = &limit
return pq
}
// Offset to start from.
func (pq *PlatformQuery) Offset(offset int) *PlatformQuery {
pq.ctx.Offset = &offset
return pq
}
// Unique configures the query builder to filter duplicate records on query.
// By default, unique is set to true, and can be disabled using this method.
func (pq *PlatformQuery) Unique(unique bool) *PlatformQuery {
pq.ctx.Unique = &unique
return pq
}
// Order specifies how the records should be ordered.
func (pq *PlatformQuery) Order(o ...entplatform.OrderOption) *PlatformQuery {
pq.order = append(pq.order, o...)
return pq
}
// QueryCreator chains the current query on the "creator" edge.
func (pq *PlatformQuery) QueryCreator() *UserQuery {
query := (&UserClient{config: pq.config}).Query()
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
if err := pq.prepareQuery(ctx); err != nil {
return nil, err
}
selector := pq.sqlQuery(ctx)
if err := selector.Err(); err != nil {
return nil, err
}
step := sqlgraph.NewStep(
sqlgraph.From(entplatform.Table, entplatform.FieldID, selector),
sqlgraph.To(user.Table, user.FieldID),
sqlgraph.Edge(sqlgraph.M2O, false, entplatform.CreatorTable, entplatform.CreatorColumn),
)
fromU = sqlgraph.SetNeighbors(pq.driver.Dialect(), step)
return fromU, nil
}
return query
}
// QueryOrganization chains the current query on the "organization" edge.
func (pq *PlatformQuery) QueryOrganization() *OrganizationQuery {
query := (&OrganizationClient{config: pq.config}).Query()
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
if err := pq.prepareQuery(ctx); err != nil {
return nil, err
}
selector := pq.sqlQuery(ctx)
if err := selector.Err(); err != nil {
return nil, err
}
step := sqlgraph.NewStep(
sqlgraph.From(entplatform.Table, entplatform.FieldID, selector),
sqlgraph.To(organization.Table, organization.FieldID),
sqlgraph.Edge(sqlgraph.M2O, false, entplatform.OrganizationTable, entplatform.OrganizationColumn),
)
fromU = sqlgraph.SetNeighbors(pq.driver.Dialect(), step)
return fromU, nil
}
return query
}
// First returns the first Platform entity from the query.
// Returns a *NotFoundError when no Platform was found.
func (pq *PlatformQuery) First(ctx context.Context) (*Platform, error) {
nodes, err := pq.Limit(1).All(setContextOp(ctx, pq.ctx, "First"))
if err != nil {
return nil, err
}
if len(nodes) == 0 {
return nil, &NotFoundError{entplatform.Label}
}
return nodes[0], nil
}
// FirstX is like First, but panics if an error occurs.
func (pq *PlatformQuery) FirstX(ctx context.Context) *Platform {
node, err := pq.First(ctx)
if err != nil && !IsNotFound(err) {
panic(err)
}
return node
}
// FirstID returns the first Platform ID from the query.
// Returns a *NotFoundError when no Platform ID was found.
func (pq *PlatformQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) {
var ids []uuid.UUID
if ids, err = pq.Limit(1).IDs(setContextOp(ctx, pq.ctx, "FirstID")); err != nil {
return
}
if len(ids) == 0 {
err = &NotFoundError{entplatform.Label}
return
}
return ids[0], nil
}
// FirstIDX is like FirstID, but panics if an error occurs.
func (pq *PlatformQuery) FirstIDX(ctx context.Context) uuid.UUID {
id, err := pq.FirstID(ctx)
if err != nil && !IsNotFound(err) {
panic(err)
}
return id
}
// Only returns a single Platform entity found by the query, ensuring it only returns one.
// Returns a *NotSingularError when more than one Platform entity is found.
// Returns a *NotFoundError when no Platform entities are found.
func (pq *PlatformQuery) Only(ctx context.Context) (*Platform, error) {
nodes, err := pq.Limit(2).All(setContextOp(ctx, pq.ctx, "Only"))
if err != nil {
return nil, err
}
switch len(nodes) {
case 1:
return nodes[0], nil
case 0:
return nil, &NotFoundError{entplatform.Label}
default:
return nil, &NotSingularError{entplatform.Label}
}
}
// OnlyX is like Only, but panics if an error occurs.
func (pq *PlatformQuery) OnlyX(ctx context.Context) *Platform {
node, err := pq.Only(ctx)
if err != nil {
panic(err)
}
return node
}
// OnlyID is like Only, but returns the only Platform ID in the query.
// Returns a *NotSingularError when more than one Platform ID is found.
// Returns a *NotFoundError when no entities are found.
func (pq *PlatformQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) {
var ids []uuid.UUID
if ids, err = pq.Limit(2).IDs(setContextOp(ctx, pq.ctx, "OnlyID")); err != nil {
return
}
switch len(ids) {
case 1:
id = ids[0]
case 0:
err = &NotFoundError{entplatform.Label}
default:
err = &NotSingularError{entplatform.Label}
}
return
}
// OnlyIDX is like OnlyID, but panics if an error occurs.
func (pq *PlatformQuery) OnlyIDX(ctx context.Context) uuid.UUID {
id, err := pq.OnlyID(ctx)
if err != nil {
panic(err)
}
return id
}
// All executes the query and returns a list of Platforms.
func (pq *PlatformQuery) All(ctx context.Context) ([]*Platform, error) {
ctx = setContextOp(ctx, pq.ctx, "All")
if err := pq.prepareQuery(ctx); err != nil {
return nil, err
}
qr := querierAll[[]*Platform, *PlatformQuery]()
return withInterceptors[[]*Platform](ctx, pq, qr, pq.inters)
}
// AllX is like All, but panics if an error occurs.
func (pq *PlatformQuery) AllX(ctx context.Context) []*Platform {
nodes, err := pq.All(ctx)
if err != nil {
panic(err)
}
return nodes
}
// IDs executes the query and returns a list of Platform IDs.
func (pq *PlatformQuery) IDs(ctx context.Context) (ids []uuid.UUID, err error) {
if pq.ctx.Unique == nil && pq.path != nil {
pq.Unique(true)
}
ctx = setContextOp(ctx, pq.ctx, "IDs")
if err = pq.Select(entplatform.FieldID).Scan(ctx, &ids); err != nil {
return nil, err
}
return ids, nil
}
// IDsX is like IDs, but panics if an error occurs.
func (pq *PlatformQuery) IDsX(ctx context.Context) []uuid.UUID {
ids, err := pq.IDs(ctx)
if err != nil {
panic(err)
}
return ids
}
// Count returns the count of the given query.
func (pq *PlatformQuery) Count(ctx context.Context) (int, error) {
ctx = setContextOp(ctx, pq.ctx, "Count")
if err := pq.prepareQuery(ctx); err != nil {
return 0, err
}
return withInterceptors[int](ctx, pq, querierCount[*PlatformQuery](), pq.inters)
}
// CountX is like Count, but panics if an error occurs.
func (pq *PlatformQuery) CountX(ctx context.Context) int {
count, err := pq.Count(ctx)
if err != nil {
panic(err)
}
return count
}
// Exist returns true if the query has elements in the graph.
func (pq *PlatformQuery) Exist(ctx context.Context) (bool, error) {
ctx = setContextOp(ctx, pq.ctx, "Exist")
switch _, err := pq.FirstID(ctx); {
case IsNotFound(err):
return false, nil
case err != nil:
return false, fmt.Errorf("ent: check existence: %w", err)
default:
return true, nil
}
}
// ExistX is like Exist, but panics if an error occurs.
func (pq *PlatformQuery) ExistX(ctx context.Context) bool {
exist, err := pq.Exist(ctx)
if err != nil {
panic(err)
}
return exist
}
// Clone returns a duplicate of the PlatformQuery builder, including all associated steps. It can be
// used to prepare common query builders and use them differently after the clone is made.
func (pq *PlatformQuery) Clone() *PlatformQuery {
if pq == nil {
return nil
}
return &PlatformQuery{
config: pq.config,
ctx: pq.ctx.Clone(),
order: append([]entplatform.OrderOption{}, pq.order...),
inters: append([]Interceptor{}, pq.inters...),
predicates: append([]predicate.Platform{}, pq.predicates...),
withCreator: pq.withCreator.Clone(),
withOrganization: pq.withOrganization.Clone(),
// clone intermediate query.
sql: pq.sql.Clone(),
path: pq.path,
}
}
// WithCreator tells the query-builder to eager-load the nodes that are connected to
// the "creator" edge. The optional arguments are used to configure the query builder of the edge.
func (pq *PlatformQuery) WithCreator(opts ...func(*UserQuery)) *PlatformQuery {
query := (&UserClient{config: pq.config}).Query()
for _, opt := range opts {
opt(query)
}
pq.withCreator = query
return pq
}
// WithOrganization tells the query-builder to eager-load the nodes that are connected to
// the "organization" edge. The optional arguments are used to configure the query builder of the edge.
func (pq *PlatformQuery) WithOrganization(opts ...func(*OrganizationQuery)) *PlatformQuery {
query := (&OrganizationClient{config: pq.config}).Query()
for _, opt := range opts {
opt(query)
}
pq.withOrganization = query
return pq
}
// GroupBy is used to group vertices by one or more fields/columns.
// It is often used with aggregate functions, like: count, max, mean, min, sum.
//
// Example:
//
// var v []struct {
// CreatedAt time.Time `json:"created_at,omitempty"`
// Count int `json:"count,omitempty"`
// }
//
// client.Platform.Query().
// GroupBy(entplatform.FieldCreatedAt).
// Aggregate(ent.Count()).
// Scan(ctx, &v)
func (pq *PlatformQuery) GroupBy(field string, fields ...string) *PlatformGroupBy {
pq.ctx.Fields = append([]string{field}, fields...)
grbuild := &PlatformGroupBy{build: pq}
grbuild.flds = &pq.ctx.Fields
grbuild.label = entplatform.Label
grbuild.scan = grbuild.Scan
return grbuild
}
// Select allows the selection one or more fields/columns for the given query,
// instead of selecting all fields in the entity.
//
// Example:
//
// var v []struct {
// CreatedAt time.Time `json:"created_at,omitempty"`
// }
//
// client.Platform.Query().
// Select(entplatform.FieldCreatedAt).
// Scan(ctx, &v)
func (pq *PlatformQuery) Select(fields ...string) *PlatformSelect {
pq.ctx.Fields = append(pq.ctx.Fields, fields...)
sbuild := &PlatformSelect{PlatformQuery: pq}
sbuild.label = entplatform.Label
sbuild.flds, sbuild.scan = &pq.ctx.Fields, sbuild.Scan
return sbuild
}
// Aggregate returns a PlatformSelect configured with the given aggregations.
func (pq *PlatformQuery) Aggregate(fns ...AggregateFunc) *PlatformSelect {
return pq.Select().Aggregate(fns...)
}
func (pq *PlatformQuery) prepareQuery(ctx context.Context) error {
for _, inter := range pq.inters {
if inter == nil {
return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)")
}
if trv, ok := inter.(Traverser); ok {
if err := trv.Traverse(ctx, pq); err != nil {
return err
}
}
}
for _, f := range pq.ctx.Fields {
if !entplatform.ValidColumn(f) {
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
}
}
if pq.path != nil {
prev, err := pq.path(ctx)
if err != nil {
return err
}
pq.sql = prev
}
return nil
}
func (pq *PlatformQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Platform, error) {
var (
nodes = []*Platform{}
_spec = pq.querySpec()
loadedTypes = [2]bool{
pq.withCreator != nil,
pq.withOrganization != nil,
}
)
_spec.ScanValues = func(columns []string) ([]any, error) {
return (*Platform).scanValues(nil, columns)
}
_spec.Assign = func(columns []string, values []any) error {
node := &Platform{config: pq.config}
nodes = append(nodes, node)
node.Edges.loadedTypes = loadedTypes
return node.assignValues(columns, values)
}
for i := range hooks {
hooks[i](ctx, _spec)
}
if err := sqlgraph.QueryNodes(ctx, pq.driver, _spec); err != nil {
return nil, err
}
if len(nodes) == 0 {
return nodes, nil
}
if query := pq.withCreator; query != nil {
if err := pq.loadCreator(ctx, query, nodes, nil,
func(n *Platform, e *User) { n.Edges.Creator = e }); err != nil {
return nil, err
}
}
if query := pq.withOrganization; query != nil {
if err := pq.loadOrganization(ctx, query, nodes, nil,
func(n *Platform, e *Organization) { n.Edges.Organization = e }); err != nil {
return nil, err
}
}
return nodes, nil
}
func (pq *PlatformQuery) loadCreator(ctx context.Context, query *UserQuery, nodes []*Platform, init func(*Platform), assign func(*Platform, *User)) error {
ids := make([]uuid.UUID, 0, len(nodes))
nodeids := make(map[uuid.UUID][]*Platform)
for i := range nodes {
fk := nodes[i].CreatorID
if _, ok := nodeids[fk]; !ok {
ids = append(ids, fk)
}
nodeids[fk] = append(nodeids[fk], nodes[i])
}
if len(ids) == 0 {
return nil
}
query.Where(user.IDIn(ids...))
neighbors, err := query.All(ctx)
if err != nil {
return err
}
for _, n := range neighbors {
nodes, ok := nodeids[n.ID]
if !ok {
return fmt.Errorf(`unexpected foreign-key "creator_id" returned %v`, n.ID)
}
for i := range nodes {
assign(nodes[i], n)
}
}
return nil
}
func (pq *PlatformQuery) loadOrganization(ctx context.Context, query *OrganizationQuery, nodes []*Platform, init func(*Platform), assign func(*Platform, *Organization)) error {
ids := make([]uuid.UUID, 0, len(nodes))
nodeids := make(map[uuid.UUID][]*Platform)
for i := range nodes {
fk := nodes[i].OrgID
if _, ok := nodeids[fk]; !ok {
ids = append(ids, fk)
}
nodeids[fk] = append(nodeids[fk], nodes[i])
}
if len(ids) == 0 {
return nil
}
query.Where(organization.IDIn(ids...))
neighbors, err := query.All(ctx)
if err != nil {
return err
}
for _, n := range neighbors {
nodes, ok := nodeids[n.ID]
if !ok {
return fmt.Errorf(`unexpected foreign-key "org_id" returned %v`, n.ID)
}
for i := range nodes {
assign(nodes[i], n)
}
}
return nil
}
func (pq *PlatformQuery) sqlCount(ctx context.Context) (int, error) {
_spec := pq.querySpec()
_spec.Node.Columns = pq.ctx.Fields
if len(pq.ctx.Fields) > 0 {
_spec.Unique = pq.ctx.Unique != nil && *pq.ctx.Unique
}
return sqlgraph.CountNodes(ctx, pq.driver, _spec)
}
func (pq *PlatformQuery) querySpec() *sqlgraph.QuerySpec {
_spec := sqlgraph.NewQuerySpec(entplatform.Table, entplatform.Columns, sqlgraph.NewFieldSpec(entplatform.FieldID, field.TypeUUID))
_spec.From = pq.sql
if unique := pq.ctx.Unique; unique != nil {
_spec.Unique = *unique
} else if pq.path != nil {
_spec.Unique = true
}
if fields := pq.ctx.Fields; len(fields) > 0 {
_spec.Node.Columns = make([]string, 0, len(fields))
_spec.Node.Columns = append(_spec.Node.Columns, entplatform.FieldID)
for i := range fields {
if fields[i] != entplatform.FieldID {
_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
}
}
if pq.withCreator != nil {
_spec.Node.AddColumnOnce(entplatform.FieldCreatorID)
}
if pq.withOrganization != nil {
_spec.Node.AddColumnOnce(entplatform.FieldOrgID)
}
}
if ps := pq.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if limit := pq.ctx.Limit; limit != nil {
_spec.Limit = *limit
}
if offset := pq.ctx.Offset; offset != nil {
_spec.Offset = *offset
}
if ps := pq.order; len(ps) > 0 {
_spec.Order = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
return _spec
}
func (pq *PlatformQuery) sqlQuery(ctx context.Context) *sql.Selector {
builder := sql.Dialect(pq.driver.Dialect())
t1 := builder.Table(entplatform.Table)
columns := pq.ctx.Fields
if len(columns) == 0 {
columns = entplatform.Columns
}
selector := builder.Select(t1.Columns(columns...)...).From(t1)
if pq.sql != nil {
selector = pq.sql
selector.Select(selector.Columns(columns...)...)
}
if pq.ctx.Unique != nil && *pq.ctx.Unique {
selector.Distinct()
}
for _, p := range pq.predicates {
p(selector)
}
for _, p := range pq.order {
p(selector)
}
if offset := pq.ctx.Offset; offset != nil {
// limit is mandatory for offset clause. We start
// with default value, and override it below if needed.
selector.Offset(*offset).Limit(math.MaxInt32)
}
if limit := pq.ctx.Limit; limit != nil {
selector.Limit(*limit)
}
return selector
}
// PlatformGroupBy is the group-by builder for Platform entities.
type PlatformGroupBy struct {
selector
build *PlatformQuery
}
// Aggregate adds the given aggregation functions to the group-by query.
func (pgb *PlatformGroupBy) Aggregate(fns ...AggregateFunc) *PlatformGroupBy {
pgb.fns = append(pgb.fns, fns...)
return pgb
}
// Scan applies the selector query and scans the result into the given value.
func (pgb *PlatformGroupBy) Scan(ctx context.Context, v any) error {
ctx = setContextOp(ctx, pgb.build.ctx, "GroupBy")
if err := pgb.build.prepareQuery(ctx); err != nil {
return err
}
return scanWithInterceptors[*PlatformQuery, *PlatformGroupBy](ctx, pgb.build, pgb, pgb.build.inters, v)
}
func (pgb *PlatformGroupBy) sqlScan(ctx context.Context, root *PlatformQuery, v any) error {
selector := root.sqlQuery(ctx).Select()
aggregation := make([]string, 0, len(pgb.fns))
for _, fn := range pgb.fns {
aggregation = append(aggregation, fn(selector))
}
if len(selector.SelectedColumns()) == 0 {
columns := make([]string, 0, len(*pgb.flds)+len(pgb.fns))
for _, f := range *pgb.flds {
columns = append(columns, selector.C(f))
}
columns = append(columns, aggregation...)
selector.Select(columns...)
}
selector.GroupBy(selector.Columns(*pgb.flds...)...)
if err := selector.Err(); err != nil {
return err
}
rows := &sql.Rows{}
query, args := selector.Query()
if err := pgb.build.driver.Query(ctx, query, args, rows); err != nil {
return err
}
defer rows.Close()
return sql.ScanSlice(rows, v)
}
// PlatformSelect is the builder for selecting fields of Platform entities.
type PlatformSelect struct {
*PlatformQuery
selector
}
// Aggregate adds the given aggregation functions to the selector query.
func (ps *PlatformSelect) Aggregate(fns ...AggregateFunc) *PlatformSelect {
ps.fns = append(ps.fns, fns...)
return ps
}
// Scan applies the selector query and scans the result into the given value.
func (ps *PlatformSelect) Scan(ctx context.Context, v any) error {
ctx = setContextOp(ctx, ps.ctx, "Select")
if err := ps.prepareQuery(ctx); err != nil {
return err
}
return scanWithInterceptors[*PlatformQuery, *PlatformSelect](ctx, ps.PlatformQuery, ps, ps.inters, v)
}
func (ps *PlatformSelect) sqlScan(ctx context.Context, root *PlatformQuery, v any) error {
selector := root.sqlQuery(ctx)
aggregation := make([]string, 0, len(ps.fns))
for _, fn := range ps.fns {
aggregation = append(aggregation, fn(selector))
}
switch n := len(*ps.selector.flds); {
case n == 0 && len(aggregation) > 0:
selector.Select(aggregation...)
case n != 0 && len(aggregation) > 0:
selector.AppendSelect(aggregation...)
}
rows := &sql.Rows{}
query, args := selector.Query()
if err := ps.driver.Query(ctx, query, args, rows); err != nil {
return err
}
defer rows.Close()
return sql.ScanSlice(rows, v)
}

View File

@@ -0,0 +1,710 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"errors"
"fmt"
"time"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/gofrs/uuid"
"github.com/holos-run/holos/internal/ent/organization"
entplatform "github.com/holos-run/holos/internal/ent/platform"
"github.com/holos-run/holos/internal/ent/predicate"
"github.com/holos-run/holos/internal/ent/user"
platform "github.com/holos-run/holos/service/gen/holos/platform/v1alpha1"
)
// PlatformUpdate is the builder for updating Platform entities.
type PlatformUpdate struct {
config
hooks []Hook
mutation *PlatformMutation
}
// Where appends a list predicates to the PlatformUpdate builder.
func (pu *PlatformUpdate) Where(ps ...predicate.Platform) *PlatformUpdate {
pu.mutation.Where(ps...)
return pu
}
// SetUpdatedAt sets the "updated_at" field.
func (pu *PlatformUpdate) SetUpdatedAt(t time.Time) *PlatformUpdate {
pu.mutation.SetUpdatedAt(t)
return pu
}
// SetOrgID sets the "org_id" field.
func (pu *PlatformUpdate) SetOrgID(u uuid.UUID) *PlatformUpdate {
pu.mutation.SetOrgID(u)
return pu
}
// SetNillableOrgID sets the "org_id" field if the given value is not nil.
func (pu *PlatformUpdate) SetNillableOrgID(u *uuid.UUID) *PlatformUpdate {
if u != nil {
pu.SetOrgID(*u)
}
return pu
}
// SetName sets the "name" field.
func (pu *PlatformUpdate) SetName(s string) *PlatformUpdate {
pu.mutation.SetName(s)
return pu
}
// SetNillableName sets the "name" field if the given value is not nil.
func (pu *PlatformUpdate) SetNillableName(s *string) *PlatformUpdate {
if s != nil {
pu.SetName(*s)
}
return pu
}
// SetDisplayName sets the "display_name" field.
func (pu *PlatformUpdate) SetDisplayName(s string) *PlatformUpdate {
pu.mutation.SetDisplayName(s)
return pu
}
// SetNillableDisplayName sets the "display_name" field if the given value is not nil.
func (pu *PlatformUpdate) SetNillableDisplayName(s *string) *PlatformUpdate {
if s != nil {
pu.SetDisplayName(*s)
}
return pu
}
// SetCreatorID sets the "creator_id" field.
func (pu *PlatformUpdate) SetCreatorID(u uuid.UUID) *PlatformUpdate {
pu.mutation.SetCreatorID(u)
return pu
}
// SetNillableCreatorID sets the "creator_id" field if the given value is not nil.
func (pu *PlatformUpdate) SetNillableCreatorID(u *uuid.UUID) *PlatformUpdate {
if u != nil {
pu.SetCreatorID(*u)
}
return pu
}
// SetForm sets the "form" field.
func (pu *PlatformUpdate) SetForm(pl *platform.Form) *PlatformUpdate {
pu.mutation.SetForm(pl)
return pu
}
// ClearForm clears the value of the "form" field.
func (pu *PlatformUpdate) ClearForm() *PlatformUpdate {
pu.mutation.ClearForm()
return pu
}
// SetModel sets the "model" field.
func (pu *PlatformUpdate) SetModel(pl *platform.Model) *PlatformUpdate {
pu.mutation.SetModel(pl)
return pu
}
// ClearModel clears the value of the "model" field.
func (pu *PlatformUpdate) ClearModel() *PlatformUpdate {
pu.mutation.ClearModel()
return pu
}
// SetCue sets the "cue" field.
func (pu *PlatformUpdate) SetCue(b []byte) *PlatformUpdate {
pu.mutation.SetCue(b)
return pu
}
// ClearCue clears the value of the "cue" field.
func (pu *PlatformUpdate) ClearCue() *PlatformUpdate {
pu.mutation.ClearCue()
return pu
}
// SetCueDefinition sets the "cue_definition" field.
func (pu *PlatformUpdate) SetCueDefinition(s string) *PlatformUpdate {
pu.mutation.SetCueDefinition(s)
return pu
}
// SetNillableCueDefinition sets the "cue_definition" field if the given value is not nil.
func (pu *PlatformUpdate) SetNillableCueDefinition(s *string) *PlatformUpdate {
if s != nil {
pu.SetCueDefinition(*s)
}
return pu
}
// ClearCueDefinition clears the value of the "cue_definition" field.
func (pu *PlatformUpdate) ClearCueDefinition() *PlatformUpdate {
pu.mutation.ClearCueDefinition()
return pu
}
// SetCreator sets the "creator" edge to the User entity.
func (pu *PlatformUpdate) SetCreator(u *User) *PlatformUpdate {
return pu.SetCreatorID(u.ID)
}
// SetOrganizationID sets the "organization" edge to the Organization entity by ID.
func (pu *PlatformUpdate) SetOrganizationID(id uuid.UUID) *PlatformUpdate {
pu.mutation.SetOrganizationID(id)
return pu
}
// SetOrganization sets the "organization" edge to the Organization entity.
func (pu *PlatformUpdate) SetOrganization(o *Organization) *PlatformUpdate {
return pu.SetOrganizationID(o.ID)
}
// Mutation returns the PlatformMutation object of the builder.
func (pu *PlatformUpdate) Mutation() *PlatformMutation {
return pu.mutation
}
// ClearCreator clears the "creator" edge to the User entity.
func (pu *PlatformUpdate) ClearCreator() *PlatformUpdate {
pu.mutation.ClearCreator()
return pu
}
// ClearOrganization clears the "organization" edge to the Organization entity.
func (pu *PlatformUpdate) ClearOrganization() *PlatformUpdate {
pu.mutation.ClearOrganization()
return pu
}
// Save executes the query and returns the number of nodes affected by the update operation.
func (pu *PlatformUpdate) Save(ctx context.Context) (int, error) {
pu.defaults()
return withHooks(ctx, pu.sqlSave, pu.mutation, pu.hooks)
}
// SaveX is like Save, but panics if an error occurs.
func (pu *PlatformUpdate) SaveX(ctx context.Context) int {
affected, err := pu.Save(ctx)
if err != nil {
panic(err)
}
return affected
}
// Exec executes the query.
func (pu *PlatformUpdate) Exec(ctx context.Context) error {
_, err := pu.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (pu *PlatformUpdate) ExecX(ctx context.Context) {
if err := pu.Exec(ctx); err != nil {
panic(err)
}
}
// defaults sets the default values of the builder before save.
func (pu *PlatformUpdate) defaults() {
if _, ok := pu.mutation.UpdatedAt(); !ok {
v := entplatform.UpdateDefaultUpdatedAt()
pu.mutation.SetUpdatedAt(v)
}
}
// check runs all checks and user-defined validators on the builder.
func (pu *PlatformUpdate) check() error {
if v, ok := pu.mutation.Name(); ok {
if err := entplatform.NameValidator(v); err != nil {
return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "Platform.name": %w`, err)}
}
}
if _, ok := pu.mutation.CreatorID(); pu.mutation.CreatorCleared() && !ok {
return errors.New(`ent: clearing a required unique edge "Platform.creator"`)
}
if _, ok := pu.mutation.OrganizationID(); pu.mutation.OrganizationCleared() && !ok {
return errors.New(`ent: clearing a required unique edge "Platform.organization"`)
}
return nil
}
func (pu *PlatformUpdate) sqlSave(ctx context.Context) (n int, err error) {
if err := pu.check(); err != nil {
return n, err
}
_spec := sqlgraph.NewUpdateSpec(entplatform.Table, entplatform.Columns, sqlgraph.NewFieldSpec(entplatform.FieldID, field.TypeUUID))
if ps := pu.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if value, ok := pu.mutation.UpdatedAt(); ok {
_spec.SetField(entplatform.FieldUpdatedAt, field.TypeTime, value)
}
if value, ok := pu.mutation.Name(); ok {
_spec.SetField(entplatform.FieldName, field.TypeString, value)
}
if value, ok := pu.mutation.DisplayName(); ok {
_spec.SetField(entplatform.FieldDisplayName, field.TypeString, value)
}
if value, ok := pu.mutation.Form(); ok {
_spec.SetField(entplatform.FieldForm, field.TypeJSON, value)
}
if pu.mutation.FormCleared() {
_spec.ClearField(entplatform.FieldForm, field.TypeJSON)
}
if value, ok := pu.mutation.Model(); ok {
_spec.SetField(entplatform.FieldModel, field.TypeJSON, value)
}
if pu.mutation.ModelCleared() {
_spec.ClearField(entplatform.FieldModel, field.TypeJSON)
}
if value, ok := pu.mutation.Cue(); ok {
_spec.SetField(entplatform.FieldCue, field.TypeBytes, value)
}
if pu.mutation.CueCleared() {
_spec.ClearField(entplatform.FieldCue, field.TypeBytes)
}
if value, ok := pu.mutation.CueDefinition(); ok {
_spec.SetField(entplatform.FieldCueDefinition, field.TypeString, value)
}
if pu.mutation.CueDefinitionCleared() {
_spec.ClearField(entplatform.FieldCueDefinition, field.TypeString)
}
if pu.mutation.CreatorCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: false,
Table: entplatform.CreatorTable,
Columns: []string{entplatform.CreatorColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUUID),
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := pu.mutation.CreatorIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: false,
Table: entplatform.CreatorTable,
Columns: []string{entplatform.CreatorColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUUID),
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
if pu.mutation.OrganizationCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: false,
Table: entplatform.OrganizationTable,
Columns: []string{entplatform.OrganizationColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(organization.FieldID, field.TypeUUID),
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := pu.mutation.OrganizationIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: false,
Table: entplatform.OrganizationTable,
Columns: []string{entplatform.OrganizationColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(organization.FieldID, field.TypeUUID),
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
if n, err = sqlgraph.UpdateNodes(ctx, pu.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{entplatform.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
return 0, err
}
pu.mutation.done = true
return n, nil
}
// PlatformUpdateOne is the builder for updating a single Platform entity.
type PlatformUpdateOne struct {
config
fields []string
hooks []Hook
mutation *PlatformMutation
}
// SetUpdatedAt sets the "updated_at" field.
func (puo *PlatformUpdateOne) SetUpdatedAt(t time.Time) *PlatformUpdateOne {
puo.mutation.SetUpdatedAt(t)
return puo
}
// SetOrgID sets the "org_id" field.
func (puo *PlatformUpdateOne) SetOrgID(u uuid.UUID) *PlatformUpdateOne {
puo.mutation.SetOrgID(u)
return puo
}
// SetNillableOrgID sets the "org_id" field if the given value is not nil.
func (puo *PlatformUpdateOne) SetNillableOrgID(u *uuid.UUID) *PlatformUpdateOne {
if u != nil {
puo.SetOrgID(*u)
}
return puo
}
// SetName sets the "name" field.
func (puo *PlatformUpdateOne) SetName(s string) *PlatformUpdateOne {
puo.mutation.SetName(s)
return puo
}
// SetNillableName sets the "name" field if the given value is not nil.
func (puo *PlatformUpdateOne) SetNillableName(s *string) *PlatformUpdateOne {
if s != nil {
puo.SetName(*s)
}
return puo
}
// SetDisplayName sets the "display_name" field.
func (puo *PlatformUpdateOne) SetDisplayName(s string) *PlatformUpdateOne {
puo.mutation.SetDisplayName(s)
return puo
}
// SetNillableDisplayName sets the "display_name" field if the given value is not nil.
func (puo *PlatformUpdateOne) SetNillableDisplayName(s *string) *PlatformUpdateOne {
if s != nil {
puo.SetDisplayName(*s)
}
return puo
}
// SetCreatorID sets the "creator_id" field.
func (puo *PlatformUpdateOne) SetCreatorID(u uuid.UUID) *PlatformUpdateOne {
puo.mutation.SetCreatorID(u)
return puo
}
// SetNillableCreatorID sets the "creator_id" field if the given value is not nil.
func (puo *PlatformUpdateOne) SetNillableCreatorID(u *uuid.UUID) *PlatformUpdateOne {
if u != nil {
puo.SetCreatorID(*u)
}
return puo
}
// SetForm sets the "form" field.
func (puo *PlatformUpdateOne) SetForm(pl *platform.Form) *PlatformUpdateOne {
puo.mutation.SetForm(pl)
return puo
}
// ClearForm clears the value of the "form" field.
func (puo *PlatformUpdateOne) ClearForm() *PlatformUpdateOne {
puo.mutation.ClearForm()
return puo
}
// SetModel sets the "model" field.
func (puo *PlatformUpdateOne) SetModel(pl *platform.Model) *PlatformUpdateOne {
puo.mutation.SetModel(pl)
return puo
}
// ClearModel clears the value of the "model" field.
func (puo *PlatformUpdateOne) ClearModel() *PlatformUpdateOne {
puo.mutation.ClearModel()
return puo
}
// SetCue sets the "cue" field.
func (puo *PlatformUpdateOne) SetCue(b []byte) *PlatformUpdateOne {
puo.mutation.SetCue(b)
return puo
}
// ClearCue clears the value of the "cue" field.
func (puo *PlatformUpdateOne) ClearCue() *PlatformUpdateOne {
puo.mutation.ClearCue()
return puo
}
// SetCueDefinition sets the "cue_definition" field.
func (puo *PlatformUpdateOne) SetCueDefinition(s string) *PlatformUpdateOne {
puo.mutation.SetCueDefinition(s)
return puo
}
// SetNillableCueDefinition sets the "cue_definition" field if the given value is not nil.
func (puo *PlatformUpdateOne) SetNillableCueDefinition(s *string) *PlatformUpdateOne {
if s != nil {
puo.SetCueDefinition(*s)
}
return puo
}
// ClearCueDefinition clears the value of the "cue_definition" field.
func (puo *PlatformUpdateOne) ClearCueDefinition() *PlatformUpdateOne {
puo.mutation.ClearCueDefinition()
return puo
}
// SetCreator sets the "creator" edge to the User entity.
func (puo *PlatformUpdateOne) SetCreator(u *User) *PlatformUpdateOne {
return puo.SetCreatorID(u.ID)
}
// SetOrganizationID sets the "organization" edge to the Organization entity by ID.
func (puo *PlatformUpdateOne) SetOrganizationID(id uuid.UUID) *PlatformUpdateOne {
puo.mutation.SetOrganizationID(id)
return puo
}
// SetOrganization sets the "organization" edge to the Organization entity.
func (puo *PlatformUpdateOne) SetOrganization(o *Organization) *PlatformUpdateOne {
return puo.SetOrganizationID(o.ID)
}
// Mutation returns the PlatformMutation object of the builder.
func (puo *PlatformUpdateOne) Mutation() *PlatformMutation {
return puo.mutation
}
// ClearCreator clears the "creator" edge to the User entity.
func (puo *PlatformUpdateOne) ClearCreator() *PlatformUpdateOne {
puo.mutation.ClearCreator()
return puo
}
// ClearOrganization clears the "organization" edge to the Organization entity.
func (puo *PlatformUpdateOne) ClearOrganization() *PlatformUpdateOne {
puo.mutation.ClearOrganization()
return puo
}
// Where appends a list predicates to the PlatformUpdate builder.
func (puo *PlatformUpdateOne) Where(ps ...predicate.Platform) *PlatformUpdateOne {
puo.mutation.Where(ps...)
return puo
}
// Select allows selecting one or more fields (columns) of the returned entity.
// The default is selecting all fields defined in the entity schema.
func (puo *PlatformUpdateOne) Select(field string, fields ...string) *PlatformUpdateOne {
puo.fields = append([]string{field}, fields...)
return puo
}
// Save executes the query and returns the updated Platform entity.
func (puo *PlatformUpdateOne) Save(ctx context.Context) (*Platform, error) {
puo.defaults()
return withHooks(ctx, puo.sqlSave, puo.mutation, puo.hooks)
}
// SaveX is like Save, but panics if an error occurs.
func (puo *PlatformUpdateOne) SaveX(ctx context.Context) *Platform {
node, err := puo.Save(ctx)
if err != nil {
panic(err)
}
return node
}
// Exec executes the query on the entity.
func (puo *PlatformUpdateOne) Exec(ctx context.Context) error {
_, err := puo.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (puo *PlatformUpdateOne) ExecX(ctx context.Context) {
if err := puo.Exec(ctx); err != nil {
panic(err)
}
}
// defaults sets the default values of the builder before save.
func (puo *PlatformUpdateOne) defaults() {
if _, ok := puo.mutation.UpdatedAt(); !ok {
v := entplatform.UpdateDefaultUpdatedAt()
puo.mutation.SetUpdatedAt(v)
}
}
// check runs all checks and user-defined validators on the builder.
func (puo *PlatformUpdateOne) check() error {
if v, ok := puo.mutation.Name(); ok {
if err := entplatform.NameValidator(v); err != nil {
return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "Platform.name": %w`, err)}
}
}
if _, ok := puo.mutation.CreatorID(); puo.mutation.CreatorCleared() && !ok {
return errors.New(`ent: clearing a required unique edge "Platform.creator"`)
}
if _, ok := puo.mutation.OrganizationID(); puo.mutation.OrganizationCleared() && !ok {
return errors.New(`ent: clearing a required unique edge "Platform.organization"`)
}
return nil
}
func (puo *PlatformUpdateOne) sqlSave(ctx context.Context) (_node *Platform, err error) {
if err := puo.check(); err != nil {
return _node, err
}
_spec := sqlgraph.NewUpdateSpec(entplatform.Table, entplatform.Columns, sqlgraph.NewFieldSpec(entplatform.FieldID, field.TypeUUID))
id, ok := puo.mutation.ID()
if !ok {
return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "Platform.id" for update`)}
}
_spec.Node.ID.Value = id
if fields := puo.fields; len(fields) > 0 {
_spec.Node.Columns = make([]string, 0, len(fields))
_spec.Node.Columns = append(_spec.Node.Columns, entplatform.FieldID)
for _, f := range fields {
if !entplatform.ValidColumn(f) {
return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
}
if f != entplatform.FieldID {
_spec.Node.Columns = append(_spec.Node.Columns, f)
}
}
}
if ps := puo.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if value, ok := puo.mutation.UpdatedAt(); ok {
_spec.SetField(entplatform.FieldUpdatedAt, field.TypeTime, value)
}
if value, ok := puo.mutation.Name(); ok {
_spec.SetField(entplatform.FieldName, field.TypeString, value)
}
if value, ok := puo.mutation.DisplayName(); ok {
_spec.SetField(entplatform.FieldDisplayName, field.TypeString, value)
}
if value, ok := puo.mutation.Form(); ok {
_spec.SetField(entplatform.FieldForm, field.TypeJSON, value)
}
if puo.mutation.FormCleared() {
_spec.ClearField(entplatform.FieldForm, field.TypeJSON)
}
if value, ok := puo.mutation.Model(); ok {
_spec.SetField(entplatform.FieldModel, field.TypeJSON, value)
}
if puo.mutation.ModelCleared() {
_spec.ClearField(entplatform.FieldModel, field.TypeJSON)
}
if value, ok := puo.mutation.Cue(); ok {
_spec.SetField(entplatform.FieldCue, field.TypeBytes, value)
}
if puo.mutation.CueCleared() {
_spec.ClearField(entplatform.FieldCue, field.TypeBytes)
}
if value, ok := puo.mutation.CueDefinition(); ok {
_spec.SetField(entplatform.FieldCueDefinition, field.TypeString, value)
}
if puo.mutation.CueDefinitionCleared() {
_spec.ClearField(entplatform.FieldCueDefinition, field.TypeString)
}
if puo.mutation.CreatorCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: false,
Table: entplatform.CreatorTable,
Columns: []string{entplatform.CreatorColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUUID),
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := puo.mutation.CreatorIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: false,
Table: entplatform.CreatorTable,
Columns: []string{entplatform.CreatorColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUUID),
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
if puo.mutation.OrganizationCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: false,
Table: entplatform.OrganizationTable,
Columns: []string{entplatform.OrganizationColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(organization.FieldID, field.TypeUUID),
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := puo.mutation.OrganizationIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: false,
Table: entplatform.OrganizationTable,
Columns: []string{entplatform.OrganizationColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(organization.FieldID, field.TypeUUID),
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
_node = &Platform{config: puo.config}
_spec.Assign = _node.assignValues
_spec.ScanValues = _node.scanValues
if err = sqlgraph.UpdateNode(ctx, puo.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{entplatform.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
return nil, err
}
puo.mutation.done = true
return _node, nil
}

View File

@@ -9,5 +9,8 @@ import (
// Organization is the predicate function for organization builders.
type Organization func(*sql.Selector)
// Platform is the predicate function for entplatform builders.
type Platform func(*sql.Selector)
// User is the predicate function for user builders.
type User func(*sql.Selector)

View File

@@ -7,6 +7,7 @@ import (
"github.com/gofrs/uuid"
"github.com/holos-run/holos/internal/ent/organization"
entplatform "github.com/holos-run/holos/internal/ent/platform"
"github.com/holos-run/holos/internal/ent/schema"
"github.com/holos-run/holos/internal/ent/user"
)
@@ -40,6 +41,31 @@ func init() {
organizationDescID := organizationMixinFields0[0].Descriptor()
// organization.DefaultID holds the default value on creation for the id field.
organization.DefaultID = organizationDescID.Default.(func() uuid.UUID)
entplatformMixin := schema.Platform{}.Mixin()
entplatformMixinFields0 := entplatformMixin[0].Fields()
_ = entplatformMixinFields0
entplatformMixinFields1 := entplatformMixin[1].Fields()
_ = entplatformMixinFields1
entplatformFields := schema.Platform{}.Fields()
_ = entplatformFields
// entplatformDescCreatedAt is the schema descriptor for created_at field.
entplatformDescCreatedAt := entplatformMixinFields1[0].Descriptor()
// entplatform.DefaultCreatedAt holds the default value on creation for the created_at field.
entplatform.DefaultCreatedAt = entplatformDescCreatedAt.Default.(func() time.Time)
// entplatformDescUpdatedAt is the schema descriptor for updated_at field.
entplatformDescUpdatedAt := entplatformMixinFields1[1].Descriptor()
// entplatform.DefaultUpdatedAt holds the default value on creation for the updated_at field.
entplatform.DefaultUpdatedAt = entplatformDescUpdatedAt.Default.(func() time.Time)
// entplatform.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
entplatform.UpdateDefaultUpdatedAt = entplatformDescUpdatedAt.UpdateDefault.(func() time.Time)
// entplatformDescName is the schema descriptor for name field.
entplatformDescName := entplatformFields[1].Descriptor()
// entplatform.NameValidator is a validator for the "name" field. It is called by the builders before save.
entplatform.NameValidator = entplatformDescName.Validators[0].(func(string) error)
// entplatformDescID is the schema descriptor for id field.
entplatformDescID := entplatformMixinFields0[0].Descriptor()
// entplatform.DefaultID holds the default value on creation for the id field.
entplatform.DefaultID = entplatformDescID.Default.(func() uuid.UUID)
userMixin := schema.User{}.Mixin()
userMixinFields0 := userMixin[0].Fields()
_ = userMixinFields0

View File

@@ -34,5 +34,7 @@ func (Organization) Edges() []ent.Edge {
Unique().
Required(),
edge.To("users", User.Type),
edge.From("platforms", Platform.Type).
Ref("organization"),
}
}

View File

@@ -0,0 +1,62 @@
package schema
import (
"entgo.io/ent"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/index"
"github.com/gofrs/uuid"
platform "github.com/holos-run/holos/service/gen/holos/platform/v1alpha1"
)
type Platform struct {
ent.Schema
}
func (Platform) Mixin() []ent.Mixin {
return []ent.Mixin{
BaseMixin{},
TimeMixin{},
}
}
func (Platform) Fields() []ent.Field {
return []ent.Field{
field.UUID("org_id", uuid.UUID{}),
field.String("name").NotEmpty(),
field.String("display_name"),
field.UUID("creator_id", uuid.UUID{}),
field.JSON("form", &platform.Form{}).
Optional().
Comment("JSON representation of FormlyFormConfig[] refer to https://github.com/holos-run/holos/issues/161"),
field.JSON("model", &platform.Model{}).
Optional().
Comment("JSON representation of the form model which holds user input values refer to https://github.com/holos-run/holos/issues/161"),
field.Bytes("cue").
Optional().
Comment("CUE definition to vet the model against e.g. #PlatformConfig"),
field.String("cue_definition").
Optional().
Comment("The definition name to vet config_values against config_cue e.g. '#PlatformSpec'"),
}
}
func (Platform) Edges() []ent.Edge {
return []ent.Edge{
edge.To("creator", User.Type).
Field("creator_id").
Unique().
Required(),
edge.To("organization", Organization.Type).
Field("org_id").
Unique().
Required(),
}
}
func (Platform) Indexes() []ent.Index {
return []ent.Index{
// One org cannot have two platforms with the same name.
index.Fields("org_id", "name").Unique(),
}
}

View File

@@ -14,6 +14,8 @@ type Tx struct {
config
// Organization is the client for interacting with the Organization builders.
Organization *OrganizationClient
// Platform is the client for interacting with the Platform builders.
Platform *PlatformClient
// User is the client for interacting with the User builders.
User *UserClient
@@ -148,6 +150,7 @@ func (tx *Tx) Client() *Client {
func (tx *Tx) init() {
tx.Organization = NewOrganizationClient(tx.config)
tx.Platform = NewPlatformClient(tx.config)
tx.User = NewUserClient(tx.config)
}

View File

@@ -45,7 +45,7 @@
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "1mb"
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",

View File

@@ -22,6 +22,8 @@
"@connectrpc/connect": "^1.4.0",
"@connectrpc/connect-query": "^1.3.1",
"@connectrpc/connect-web": "^1.4.0",
"@ngx-formly/core": "^6.3.0",
"@ngx-formly/material": "^6.3.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.3"
@@ -34,6 +36,7 @@
"@bufbuild/protoc-gen-es": "^1.9.0",
"@connectrpc/protoc-gen-connect-es": "^1.4.0",
"@connectrpc/protoc-gen-connect-query": "^1.3.1",
"@ngx-formly/schematics": "^6.3.0",
"@types/jasmine": "~5.1.0",
"jasmine-core": "~5.1.0",
"karma": "~6.4.0",
@@ -3943,6 +3946,160 @@
"webpack": "^5.54.0"
}
},
"node_modules/@ngx-formly/core": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/@ngx-formly/core/-/core-6.3.0.tgz",
"integrity": "sha512-9qCoPdLLVShoruzXeJUjMdIhfIlHCI+TggA3Wc01ISHTK2vXx1gNIFLuS+hez3JEzu8nIDRuA/nWqj4j8fJCNg==",
"dependencies": {
"tslib": "^2.0.0"
},
"peerDependencies": {
"@angular/forms": ">=13.2.0",
"rxjs": "^6.5.3 || ^7.0.0"
}
},
"node_modules/@ngx-formly/material": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/@ngx-formly/material/-/material-6.3.0.tgz",
"integrity": "sha512-kzNNXQhOtPf2Uc4l02CO7njwKNJsaP+dpLt6cvYQA04fVALrO/dEJNbgUW6rlVp0oQQmobiu83lN1qWKmqAcng==",
"dependencies": {
"tslib": "^2.0.0"
},
"peerDependencies": {
"@angular/material": ">=13.0.0",
"@ngx-formly/core": "6.3.0"
}
},
"node_modules/@ngx-formly/schematics": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/@ngx-formly/schematics/-/schematics-6.3.0.tgz",
"integrity": "sha512-XSzOvrZ1NoUhmd733bcgUFkl+26pSw8eyXChi9LwrS26nEPweR8RA/JxN+lFvIb92MWzLShLd1DY2oBz/0r0ZQ==",
"dev": true,
"dependencies": {
"@angular-devkit/core": "^13.0.3",
"@angular-devkit/schematics": "^13.0.3",
"@schematics/angular": "^13.0.3"
}
},
"node_modules/@ngx-formly/schematics/node_modules/@angular-devkit/core": {
"version": "13.3.11",
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.3.11.tgz",
"integrity": "sha512-rfqoLMRYhlz0wzKlHx7FfyIyQq8dKTsmbCoIVU1cEIH0gyTMVY7PbVzwRRcO6xp5waY+0hA+0Brriujpuhkm4w==",
"dev": true,
"dependencies": {
"ajv": "8.9.0",
"ajv-formats": "2.1.1",
"fast-json-stable-stringify": "2.1.0",
"magic-string": "0.25.7",
"rxjs": "6.6.7",
"source-map": "0.7.3"
},
"engines": {
"node": "^12.20.0 || ^14.15.0 || >=16.10.0",
"npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
"yarn": ">= 1.13.0"
},
"peerDependencies": {
"chokidar": "^3.5.2"
},
"peerDependenciesMeta": {
"chokidar": {
"optional": true
}
}
},
"node_modules/@ngx-formly/schematics/node_modules/@angular-devkit/schematics": {
"version": "13.3.11",
"resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-13.3.11.tgz",
"integrity": "sha512-ben+EGXpCrClnIVAAnEQmhQdKmnnqFhMp5BqMxgOslSYBAmCutLA6rBu5vsc8kZcGian1wt+lueF7G1Uk5cGBg==",
"dev": true,
"dependencies": {
"@angular-devkit/core": "13.3.11",
"jsonc-parser": "3.0.0",
"magic-string": "0.25.7",
"ora": "5.4.1",
"rxjs": "6.6.7"
},
"engines": {
"node": "^12.20.0 || ^14.15.0 || >=16.10.0",
"npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
"yarn": ">= 1.13.0"
}
},
"node_modules/@ngx-formly/schematics/node_modules/@schematics/angular": {
"version": "13.3.11",
"resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-13.3.11.tgz",
"integrity": "sha512-imKBnKYEse0SBVELZO/753nkpt3eEgpjrYkB+AFWF9YfO/4RGnYXDHoH8CFkzxPH9QQCgNrmsVFNiYGS+P/S1A==",
"dev": true,
"dependencies": {
"@angular-devkit/core": "13.3.11",
"@angular-devkit/schematics": "13.3.11",
"jsonc-parser": "3.0.0"
},
"engines": {
"node": "^12.20.0 || ^14.15.0 || >=16.10.0",
"npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
"yarn": ">= 1.13.0"
}
},
"node_modules/@ngx-formly/schematics/node_modules/ajv": {
"version": "8.9.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz",
"integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==",
"dev": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/@ngx-formly/schematics/node_modules/jsonc-parser": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz",
"integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==",
"dev": true
},
"node_modules/@ngx-formly/schematics/node_modules/magic-string": {
"version": "0.25.7",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
"integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==",
"dev": true,
"dependencies": {
"sourcemap-codec": "^1.4.4"
}
},
"node_modules/@ngx-formly/schematics/node_modules/rxjs": {
"version": "6.6.7",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
"integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
"dev": true,
"dependencies": {
"tslib": "^1.9.0"
},
"engines": {
"npm": ">=2.0.0"
}
},
"node_modules/@ngx-formly/schematics/node_modules/source-map": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
"integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
"dev": true,
"engines": {
"node": ">= 8"
}
},
"node_modules/@ngx-formly/schematics/node_modules/tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"dev": true
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -11874,6 +12031,13 @@
"node": ">=0.10.0"
}
},
"node_modules/sourcemap-codec": {
"version": "1.4.8",
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
"deprecated": "Please use @jridgewell/sourcemap-codec instead",
"dev": true
},
"node_modules/spdx-correct": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",

View File

@@ -24,6 +24,8 @@
"@connectrpc/connect": "^1.4.0",
"@connectrpc/connect-query": "^1.3.1",
"@connectrpc/connect-web": "^1.4.0",
"@ngx-formly/core": "^6.3.0",
"@ngx-formly/material": "^6.3.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.3"
@@ -36,6 +38,7 @@
"@bufbuild/protoc-gen-es": "^1.9.0",
"@connectrpc/protoc-gen-connect-es": "^1.4.0",
"@connectrpc/protoc-gen-connect-query": "^1.3.1",
"@ngx-formly/schematics": "^6.3.0",
"@types/jasmine": "~5.1.0",
"jasmine-core": "~5.1.0",
"karma": "~6.4.0",

View File

@@ -1,25 +1,31 @@
import { ApplicationConfig, importProvidersFrom } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideRouter, withComponentInputBinding } from '@angular/router';
import { FormlyModule } from '@ngx-formly/core';
// import { provideHttpClient, withFetch } from '@angular/common/http';
import { routes } from './app.routes';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import { ConnectModule } from '../connect/connect.module';
import { provideClient } from "../connect/client.provider";
import { UserService } from './gen/holos/v1alpha1/user_connect';
import { OrganizationService } from './gen/holos/v1alpha1/organization_connect';
import { PlatformService } from './gen/holos/v1alpha1/platform_connect';
import { HolosPanelWrapperComponent } from '../wrappers/holos-panel-wrapper/holos-panel-wrapper.component';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
provideRouter(routes, withComponentInputBinding()),
provideAnimationsAsync(),
// provideHttpClient(withFetch()),
provideClient(UserService),
provideClient(OrganizationService),
provideClient(PlatformService),
importProvidersFrom(
ConnectModule.forRoot({
baseUrl: window.location.origin
}),
FormlyModule.forRoot({
wrappers: [{ name: 'holos-panel', component: HolosPanelWrapperComponent }],
}),
),
]
};

View File

@@ -1,11 +1,13 @@
import { Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { ClusterListComponent } from './cluster-list/cluster-list.component';
import { ErrorNotFoundComponent } from './error-not-found/error-not-found.component';
import { PlatformsComponent } from './views/platforms/platforms.component'
import { PlatformDetailComponent } from './views/platform-detail/platform-detail.component';
export const routes: Routes = [
{ path: 'platform/:id', component: PlatformDetailComponent },
{ path: 'platforms', component: PlatformsComponent },
{ path: 'home', component: HomeComponent },
{ path: 'clusters', component: ClusterListComponent },
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: '', redirectTo: '/platforms', pathMatch: 'full' },
{ path: '**', component: ErrorNotFoundComponent },
];

View File

@@ -1,26 +0,0 @@
<div class="grid-container">
<h1 class="mat-h1">Clusters</h1>
<mat-grid-list cols="2" rowHeight="350px">
@for (card of cards | async; track card) {
<mat-grid-tile [colspan]="card.cols" [rowspan]="card.rows">
<mat-card class="dashboard-card">
<mat-card-header>
<mat-card-title>
{{card.title}}
<button mat-icon-button class="more-button" [matMenuTriggerFor]="menu" aria-label="Toggle menu">
<mat-icon>more_vert</mat-icon>
</button>
<mat-menu #menu="matMenu" xPosition="before">
<button mat-menu-item>Expand</button>
<button mat-menu-item>Remove</button>
</mat-menu>
</mat-card-title>
</mat-card-header>
<mat-card-content class="dashboard-card-content">
<div>Card Content Here</div>
</mat-card-content>
</mat-card>
</mat-grid-tile>
}
</mat-grid-list>
</div>

View File

@@ -1,21 +0,0 @@
.grid-container {
margin: 20px;
}
.dashboard-card {
position: absolute;
top: 15px;
left: 15px;
right: 15px;
bottom: 15px;
}
.more-button {
position: absolute;
top: 5px;
right: 10px;
}
.dashboard-card-content {
text-align: center;
}

View File

@@ -1,25 +0,0 @@
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { ClusterListComponent } from './cluster-list.component';
describe('ClusterListComponent', () => {
let component: ClusterListComponent;
let fixture: ComponentFixture<ClusterListComponent>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [NoopAnimationsModule]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ClusterListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should compile', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -1,48 +0,0 @@
import { Component, inject } from '@angular/core';
import { Breakpoints, BreakpointObserver } from '@angular/cdk/layout';
import { map } from 'rxjs/operators';
import { AsyncPipe } from '@angular/common';
import { MatGridListModule } from '@angular/material/grid-list';
import { MatMenuModule } from '@angular/material/menu';
import { MatIconModule } from '@angular/material/icon';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
@Component({
selector: 'app-cluster-list',
templateUrl: './cluster-list.component.html',
styleUrl: './cluster-list.component.scss',
standalone: true,
imports: [
AsyncPipe,
MatGridListModule,
MatMenuModule,
MatIconModule,
MatButtonModule,
MatCardModule
]
})
export class ClusterListComponent {
private breakpointObserver = inject(BreakpointObserver);
/** Based on the screen size, switch from standard to one column per row */
cards = this.breakpointObserver.observe(Breakpoints.Handset).pipe(
map(({ matches }) => {
if (matches) {
return [
{ title: 'Card 1', cols: 1, rows: 1 },
{ title: 'Card 2', cols: 1, rows: 1 },
{ title: 'Card 3', cols: 1, rows: 1 },
{ title: 'Card 4', cols: 1, rows: 1 }
];
}
return [
{ title: 'Card 1', cols: 2, rows: 1 },
{ title: 'Card 2', cols: 1, rows: 1 },
{ title: 'Card 3', cols: 1, rows: 2 },
{ title: 'Card 4', cols: 1, rows: 1 }
];
})
);
}

View File

@@ -0,0 +1,105 @@
// @generated by protoc-gen-connect-query v1.3.1 with parameter "target=ts"
// @generated from file holos/platform/v1alpha1/platform.proto (package holos.platform.v1alpha1, syntax proto3)
/* eslint-disable */
// @ts-nocheck
import { MethodKind } from "@bufbuild/protobuf";
import { AddPlatformRequest, AddPlatformResponse, GetFormRequest, GetFormResponse, GetModelRequest, GetModelResponse, GetPlatformRequest, GetPlatformResponse, ListPlatformsRequest, ListPlatformsResponse, PutFormRequest, PutFormResponse, PutModelRequest, PutModelResponse } from "./platform_pb.js";
/**
* @generated from rpc holos.platform.v1alpha1.PlatformService.AddPlatform
*/
export const addPlatform = {
localName: "addPlatform",
name: "AddPlatform",
kind: MethodKind.Unary,
I: AddPlatformRequest,
O: AddPlatformResponse,
service: {
typeName: "holos.platform.v1alpha1.PlatformService"
}
} as const;
/**
* @generated from rpc holos.platform.v1alpha1.PlatformService.GetPlatform
*/
export const getPlatform = {
localName: "getPlatform",
name: "GetPlatform",
kind: MethodKind.Unary,
I: GetPlatformRequest,
O: GetPlatformResponse,
service: {
typeName: "holos.platform.v1alpha1.PlatformService"
}
} as const;
/**
* @generated from rpc holos.platform.v1alpha1.PlatformService.ListPlatforms
*/
export const listPlatforms = {
localName: "listPlatforms",
name: "ListPlatforms",
kind: MethodKind.Unary,
I: ListPlatformsRequest,
O: ListPlatformsResponse,
service: {
typeName: "holos.platform.v1alpha1.PlatformService"
}
} as const;
/**
* @generated from rpc holos.platform.v1alpha1.PlatformService.GetForm
*/
export const getForm = {
localName: "getForm",
name: "GetForm",
kind: MethodKind.Unary,
I: GetFormRequest,
O: GetFormResponse,
service: {
typeName: "holos.platform.v1alpha1.PlatformService"
}
} as const;
/**
* @generated from rpc holos.platform.v1alpha1.PlatformService.PutForm
*/
export const putForm = {
localName: "putForm",
name: "PutForm",
kind: MethodKind.Unary,
I: PutFormRequest,
O: PutFormResponse,
service: {
typeName: "holos.platform.v1alpha1.PlatformService"
}
} as const;
/**
* @generated from rpc holos.platform.v1alpha1.PlatformService.GetModel
*/
export const getModel = {
localName: "getModel",
name: "GetModel",
kind: MethodKind.Unary,
I: GetModelRequest,
O: GetModelResponse,
service: {
typeName: "holos.platform.v1alpha1.PlatformService"
}
} as const;
/**
* @generated from rpc holos.platform.v1alpha1.PlatformService.PutModel
*/
export const putModel = {
localName: "putModel",
name: "PutModel",
kind: MethodKind.Unary,
I: PutModelRequest,
O: PutModelResponse,
service: {
typeName: "holos.platform.v1alpha1.PlatformService"
}
} as const;

View File

@@ -0,0 +1,80 @@
// @generated by protoc-gen-connect-es v1.4.0 with parameter "target=ts"
// @generated from file holos/platform/v1alpha1/platform.proto (package holos.platform.v1alpha1, syntax proto3)
/* eslint-disable */
// @ts-nocheck
import { AddPlatformRequest, AddPlatformResponse, GetFormRequest, GetFormResponse, GetModelRequest, GetModelResponse, GetPlatformRequest, GetPlatformResponse, ListPlatformsRequest, ListPlatformsResponse, PutFormRequest, PutFormResponse, PutModelRequest, PutModelResponse } from "./platform_pb.js";
import { MethodKind } from "@bufbuild/protobuf";
/**
* @generated from service holos.platform.v1alpha1.PlatformService
*/
export const PlatformService = {
typeName: "holos.platform.v1alpha1.PlatformService",
methods: {
/**
* @generated from rpc holos.platform.v1alpha1.PlatformService.AddPlatform
*/
addPlatform: {
name: "AddPlatform",
I: AddPlatformRequest,
O: AddPlatformResponse,
kind: MethodKind.Unary,
},
/**
* @generated from rpc holos.platform.v1alpha1.PlatformService.GetPlatform
*/
getPlatform: {
name: "GetPlatform",
I: GetPlatformRequest,
O: GetPlatformResponse,
kind: MethodKind.Unary,
},
/**
* @generated from rpc holos.platform.v1alpha1.PlatformService.ListPlatforms
*/
listPlatforms: {
name: "ListPlatforms",
I: ListPlatformsRequest,
O: ListPlatformsResponse,
kind: MethodKind.Unary,
},
/**
* @generated from rpc holos.platform.v1alpha1.PlatformService.GetForm
*/
getForm: {
name: "GetForm",
I: GetFormRequest,
O: GetFormResponse,
kind: MethodKind.Unary,
},
/**
* @generated from rpc holos.platform.v1alpha1.PlatformService.PutForm
*/
putForm: {
name: "PutForm",
I: PutFormRequest,
O: PutFormResponse,
kind: MethodKind.Unary,
},
/**
* @generated from rpc holos.platform.v1alpha1.PlatformService.GetModel
*/
getModel: {
name: "GetModel",
I: GetModelRequest,
O: GetModelResponse,
kind: MethodKind.Unary,
},
/**
* @generated from rpc holos.platform.v1alpha1.PlatformService.PutModel
*/
putModel: {
name: "PutModel",
I: PutModelRequest,
O: PutModelResponse,
kind: MethodKind.Unary,
},
}
} as const;

View File

@@ -0,0 +1,732 @@
// @generated by protoc-gen-es v1.9.0 with parameter "target=ts"
// @generated from file holos/platform/v1alpha1/platform.proto (package holos.platform.v1alpha1, syntax proto3)
/* eslint-disable */
// @ts-nocheck
import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf";
import { Message, proto3, Struct } from "@bufbuild/protobuf";
/**
* @generated from message holos.platform.v1alpha1.Platform
*/
export class Platform extends Message<Platform> {
/**
* Unique id assigned by the server.
*
* @generated from field: string id = 1;
*/
id = "";
/**
* Organization ID resource owner.
*
* @generated from field: string org_id = 2;
*/
orgId = "";
/**
* name is the platform short name as a dns label.
*
* @generated from field: string name = 3;
*/
name = "";
/**
* @generated from field: string display_name = 4;
*/
displayName = "";
/**
* @generated from field: holos.platform.v1alpha1.PlatformSpec spec = 5;
*/
spec?: PlatformSpec;
constructor(data?: PartialMessage<Platform>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.Platform";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 2, name: "org_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 3, name: "name", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 4, name: "display_name", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 5, name: "spec", kind: "message", T: PlatformSpec },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): Platform {
return new Platform().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): Platform {
return new Platform().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): Platform {
return new Platform().fromJsonString(jsonString, options);
}
static equals(a: Platform | PlainMessage<Platform> | undefined, b: Platform | PlainMessage<Platform> | undefined): boolean {
return proto3.util.equals(Platform, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.PlatformSpec
*/
export class PlatformSpec extends Message<PlatformSpec> {
/**
* model represents the user-defined and user-supplied form field values.
*
* @generated from field: google.protobuf.Struct model = 1;
*/
model?: Struct;
constructor(data?: PartialMessage<PlatformSpec>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.PlatformSpec";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "model", kind: "message", T: Struct },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): PlatformSpec {
return new PlatformSpec().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): PlatformSpec {
return new PlatformSpec().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): PlatformSpec {
return new PlatformSpec().fromJsonString(jsonString, options);
}
static equals(a: PlatformSpec | PlainMessage<PlatformSpec> | undefined, b: PlatformSpec | PlainMessage<PlatformSpec> | undefined): boolean {
return proto3.util.equals(PlatformSpec, a, b);
}
}
/**
* Form represents the Formly input form.
*
* @generated from message holos.platform.v1alpha1.Form
*/
export class Form extends Message<Form> {
/**
* fields represents FormlyFieldConfig[] encoded as a JSON array.
*
* @generated from field: repeated google.protobuf.Struct fields = 1;
*/
fields: Struct[] = [];
constructor(data?: PartialMessage<Form>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.Form";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "fields", kind: "message", T: Struct, repeated: true },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): Form {
return new Form().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): Form {
return new Form().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): Form {
return new Form().fromJsonString(jsonString, options);
}
static equals(a: Form | PlainMessage<Form> | undefined, b: Form | PlainMessage<Form> | undefined): boolean {
return proto3.util.equals(Form, a, b);
}
}
/**
* Model represents the values entered into the form, stored in the form's model
* in the web app, and persisted into the backend database. The model is
* ultimately intended as the input to platform rendering.
*
* @generated from message holos.platform.v1alpha1.Model
*/
export class Model extends Message<Model> {
/**
* @generated from field: google.protobuf.Struct model = 1;
*/
model?: Struct;
constructor(data?: PartialMessage<Model>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.Model";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "model", kind: "message", T: Struct },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): Model {
return new Model().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): Model {
return new Model().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): Model {
return new Model().fromJsonString(jsonString, options);
}
static equals(a: Model | PlainMessage<Model> | undefined, b: Model | PlainMessage<Model> | undefined): boolean {
return proto3.util.equals(Model, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.ListPlatformsRequest
*/
export class ListPlatformsRequest extends Message<ListPlatformsRequest> {
/**
* @generated from field: string org_id = 1;
*/
orgId = "";
constructor(data?: PartialMessage<ListPlatformsRequest>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.ListPlatformsRequest";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "org_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): ListPlatformsRequest {
return new ListPlatformsRequest().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): ListPlatformsRequest {
return new ListPlatformsRequest().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): ListPlatformsRequest {
return new ListPlatformsRequest().fromJsonString(jsonString, options);
}
static equals(a: ListPlatformsRequest | PlainMessage<ListPlatformsRequest> | undefined, b: ListPlatformsRequest | PlainMessage<ListPlatformsRequest> | undefined): boolean {
return proto3.util.equals(ListPlatformsRequest, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.ListPlatformsResponse
*/
export class ListPlatformsResponse extends Message<ListPlatformsResponse> {
/**
* @generated from field: repeated holos.platform.v1alpha1.Platform platforms = 1;
*/
platforms: Platform[] = [];
constructor(data?: PartialMessage<ListPlatformsResponse>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.ListPlatformsResponse";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "platforms", kind: "message", T: Platform, repeated: true },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): ListPlatformsResponse {
return new ListPlatformsResponse().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): ListPlatformsResponse {
return new ListPlatformsResponse().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): ListPlatformsResponse {
return new ListPlatformsResponse().fromJsonString(jsonString, options);
}
static equals(a: ListPlatformsResponse | PlainMessage<ListPlatformsResponse> | undefined, b: ListPlatformsResponse | PlainMessage<ListPlatformsResponse> | undefined): boolean {
return proto3.util.equals(ListPlatformsResponse, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.AddPlatformRequest
*/
export class AddPlatformRequest extends Message<AddPlatformRequest> {
/**
* @generated from field: holos.platform.v1alpha1.Platform platform = 1;
*/
platform?: Platform;
constructor(data?: PartialMessage<AddPlatformRequest>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.AddPlatformRequest";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "platform", kind: "message", T: Platform },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): AddPlatformRequest {
return new AddPlatformRequest().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): AddPlatformRequest {
return new AddPlatformRequest().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): AddPlatformRequest {
return new AddPlatformRequest().fromJsonString(jsonString, options);
}
static equals(a: AddPlatformRequest | PlainMessage<AddPlatformRequest> | undefined, b: AddPlatformRequest | PlainMessage<AddPlatformRequest> | undefined): boolean {
return proto3.util.equals(AddPlatformRequest, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.AddPlatformResponse
*/
export class AddPlatformResponse extends Message<AddPlatformResponse> {
/**
* @generated from field: repeated holos.platform.v1alpha1.Platform platforms = 1;
*/
platforms: Platform[] = [];
constructor(data?: PartialMessage<AddPlatformResponse>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.AddPlatformResponse";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "platforms", kind: "message", T: Platform, repeated: true },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): AddPlatformResponse {
return new AddPlatformResponse().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): AddPlatformResponse {
return new AddPlatformResponse().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): AddPlatformResponse {
return new AddPlatformResponse().fromJsonString(jsonString, options);
}
static equals(a: AddPlatformResponse | PlainMessage<AddPlatformResponse> | undefined, b: AddPlatformResponse | PlainMessage<AddPlatformResponse> | undefined): boolean {
return proto3.util.equals(AddPlatformResponse, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.GetPlatformRequest
*/
export class GetPlatformRequest extends Message<GetPlatformRequest> {
/**
* @generated from field: string platform_id = 1;
*/
platformId = "";
constructor(data?: PartialMessage<GetPlatformRequest>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.GetPlatformRequest";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "platform_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetPlatformRequest {
return new GetPlatformRequest().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetPlatformRequest {
return new GetPlatformRequest().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetPlatformRequest {
return new GetPlatformRequest().fromJsonString(jsonString, options);
}
static equals(a: GetPlatformRequest | PlainMessage<GetPlatformRequest> | undefined, b: GetPlatformRequest | PlainMessage<GetPlatformRequest> | undefined): boolean {
return proto3.util.equals(GetPlatformRequest, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.GetPlatformResponse
*/
export class GetPlatformResponse extends Message<GetPlatformResponse> {
/**
* @generated from field: holos.platform.v1alpha1.Platform platform = 1;
*/
platform?: Platform;
constructor(data?: PartialMessage<GetPlatformResponse>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.GetPlatformResponse";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "platform", kind: "message", T: Platform },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetPlatformResponse {
return new GetPlatformResponse().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetPlatformResponse {
return new GetPlatformResponse().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetPlatformResponse {
return new GetPlatformResponse().fromJsonString(jsonString, options);
}
static equals(a: GetPlatformResponse | PlainMessage<GetPlatformResponse> | undefined, b: GetPlatformResponse | PlainMessage<GetPlatformResponse> | undefined): boolean {
return proto3.util.equals(GetPlatformResponse, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.GetFormRequest
*/
export class GetFormRequest extends Message<GetFormRequest> {
/**
* @generated from field: string platform_id = 1;
*/
platformId = "";
constructor(data?: PartialMessage<GetFormRequest>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.GetFormRequest";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "platform_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetFormRequest {
return new GetFormRequest().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetFormRequest {
return new GetFormRequest().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetFormRequest {
return new GetFormRequest().fromJsonString(jsonString, options);
}
static equals(a: GetFormRequest | PlainMessage<GetFormRequest> | undefined, b: GetFormRequest | PlainMessage<GetFormRequest> | undefined): boolean {
return proto3.util.equals(GetFormRequest, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.GetFormResponse
*/
export class GetFormResponse extends Message<GetFormResponse> {
/**
* @generated from field: repeated google.protobuf.Struct fields = 1;
*/
fields: Struct[] = [];
/**
* @generated from field: google.protobuf.Struct model = 2;
*/
model?: Struct;
constructor(data?: PartialMessage<GetFormResponse>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.GetFormResponse";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "fields", kind: "message", T: Struct, repeated: true },
{ no: 2, name: "model", kind: "message", T: Struct },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetFormResponse {
return new GetFormResponse().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetFormResponse {
return new GetFormResponse().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetFormResponse {
return new GetFormResponse().fromJsonString(jsonString, options);
}
static equals(a: GetFormResponse | PlainMessage<GetFormResponse> | undefined, b: GetFormResponse | PlainMessage<GetFormResponse> | undefined): boolean {
return proto3.util.equals(GetFormResponse, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.GetModelRequest
*/
export class GetModelRequest extends Message<GetModelRequest> {
/**
* @generated from field: string platform_id = 1;
*/
platformId = "";
constructor(data?: PartialMessage<GetModelRequest>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.GetModelRequest";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "platform_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetModelRequest {
return new GetModelRequest().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetModelRequest {
return new GetModelRequest().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetModelRequest {
return new GetModelRequest().fromJsonString(jsonString, options);
}
static equals(a: GetModelRequest | PlainMessage<GetModelRequest> | undefined, b: GetModelRequest | PlainMessage<GetModelRequest> | undefined): boolean {
return proto3.util.equals(GetModelRequest, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.GetModelResponse
*/
export class GetModelResponse extends Message<GetModelResponse> {
/**
* @generated from field: google.protobuf.Struct model = 1;
*/
model?: Struct;
constructor(data?: PartialMessage<GetModelResponse>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.GetModelResponse";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "model", kind: "message", T: Struct },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetModelResponse {
return new GetModelResponse().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetModelResponse {
return new GetModelResponse().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetModelResponse {
return new GetModelResponse().fromJsonString(jsonString, options);
}
static equals(a: GetModelResponse | PlainMessage<GetModelResponse> | undefined, b: GetModelResponse | PlainMessage<GetModelResponse> | undefined): boolean {
return proto3.util.equals(GetModelResponse, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.PutModelRequest
*/
export class PutModelRequest extends Message<PutModelRequest> {
/**
* @generated from field: string platform_id = 1;
*/
platformId = "";
/**
* @generated from field: google.protobuf.Struct model = 2;
*/
model?: Struct;
constructor(data?: PartialMessage<PutModelRequest>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.PutModelRequest";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "platform_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 2, name: "model", kind: "message", T: Struct },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): PutModelRequest {
return new PutModelRequest().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): PutModelRequest {
return new PutModelRequest().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): PutModelRequest {
return new PutModelRequest().fromJsonString(jsonString, options);
}
static equals(a: PutModelRequest | PlainMessage<PutModelRequest> | undefined, b: PutModelRequest | PlainMessage<PutModelRequest> | undefined): boolean {
return proto3.util.equals(PutModelRequest, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.PutModelResponse
*/
export class PutModelResponse extends Message<PutModelResponse> {
/**
* @generated from field: google.protobuf.Struct model = 1;
*/
model?: Struct;
constructor(data?: PartialMessage<PutModelResponse>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.PutModelResponse";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "model", kind: "message", T: Struct },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): PutModelResponse {
return new PutModelResponse().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): PutModelResponse {
return new PutModelResponse().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): PutModelResponse {
return new PutModelResponse().fromJsonString(jsonString, options);
}
static equals(a: PutModelResponse | PlainMessage<PutModelResponse> | undefined, b: PutModelResponse | PlainMessage<PutModelResponse> | undefined): boolean {
return proto3.util.equals(PutModelResponse, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.PutFormRequest
*/
export class PutFormRequest extends Message<PutFormRequest> {
/**
* @generated from field: string platform_id = 1;
*/
platformId = "";
/**
* @generated from field: repeated google.protobuf.Struct fields = 2;
*/
fields: Struct[] = [];
constructor(data?: PartialMessage<PutFormRequest>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.PutFormRequest";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "platform_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 2, name: "fields", kind: "message", T: Struct, repeated: true },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): PutFormRequest {
return new PutFormRequest().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): PutFormRequest {
return new PutFormRequest().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): PutFormRequest {
return new PutFormRequest().fromJsonString(jsonString, options);
}
static equals(a: PutFormRequest | PlainMessage<PutFormRequest> | undefined, b: PutFormRequest | PlainMessage<PutFormRequest> | undefined): boolean {
return proto3.util.equals(PutFormRequest, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.PutFormResponse
*/
export class PutFormResponse extends Message<PutFormResponse> {
/**
* @generated from field: repeated google.protobuf.Struct fields = 1;
*/
fields: Struct[] = [];
constructor(data?: PartialMessage<PutFormResponse>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.PutFormResponse";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "fields", kind: "message", T: Struct, repeated: true },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): PutFormResponse {
return new PutFormResponse().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): PutFormResponse {
return new PutFormResponse().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): PutFormResponse {
return new PutFormResponse().fromJsonString(jsonString, options);
}
static equals(a: PutFormResponse | PlainMessage<PutFormResponse> | undefined, b: PutFormResponse | PlainMessage<PutFormResponse> | undefined): boolean {
return proto3.util.equals(PutFormResponse, a, b);
}
}

View File

@@ -6,7 +6,7 @@
import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf";
import { Message, proto3 } from "@bufbuild/protobuf";
import { Timestamps } from "./timestamps_pb.js";
import { User } from "./user_pb.js";
import { Creator, User } from "./user_pb.js";
/**
* @generated from message holos.v1alpha1.Organization
@@ -34,6 +34,11 @@ export class Organization extends Message<Organization> {
*/
timestamps?: Timestamps;
/**
* @generated from field: holos.v1alpha1.Creator creator = 5;
*/
creator?: Creator;
constructor(data?: PartialMessage<Organization>) {
super();
proto3.util.initPartial(data, this);
@@ -46,6 +51,7 @@ export class Organization extends Message<Organization> {
{ no: 2, name: "name", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 3, name: "display_name", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 4, name: "timestamps", kind: "message", T: Timestamps },
{ no: 5, name: "creator", kind: "message", T: Creator },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): Organization {

View File

@@ -0,0 +1,91 @@
// @generated by protoc-gen-connect-query v1.3.1 with parameter "target=ts"
// @generated from file holos/v1alpha1/platform.proto (package holos.platform.v1alpha1, syntax proto3)
/* eslint-disable */
// @ts-nocheck
import { MethodKind } from "@bufbuild/protobuf";
import { AddPlatformRequest, AddPlatformResponse, GetFormRequest, GetFormResponse, GetModelRequest, GetModelResponse, GetPlatformRequest, GetPlatformResponse, ListPlatformsRequest, ListPlatformsResponse, PutModelRequest, PutModelResponse } from "./platform_pb.js";
/**
* @generated from rpc holos.platform.v1alpha1.PlatformService.AddPlatform
*/
export const addPlatform = {
localName: "addPlatform",
name: "AddPlatform",
kind: MethodKind.Unary,
I: AddPlatformRequest,
O: AddPlatformResponse,
service: {
typeName: "holos.platform.v1alpha1.PlatformService"
}
} as const;
/**
* @generated from rpc holos.platform.v1alpha1.PlatformService.GetPlatform
*/
export const getPlatform = {
localName: "getPlatform",
name: "GetPlatform",
kind: MethodKind.Unary,
I: GetPlatformRequest,
O: GetPlatformResponse,
service: {
typeName: "holos.platform.v1alpha1.PlatformService"
}
} as const;
/**
* @generated from rpc holos.platform.v1alpha1.PlatformService.ListPlatforms
*/
export const listPlatforms = {
localName: "listPlatforms",
name: "ListPlatforms",
kind: MethodKind.Unary,
I: ListPlatformsRequest,
O: ListPlatformsResponse,
service: {
typeName: "holos.platform.v1alpha1.PlatformService"
}
} as const;
/**
* @generated from rpc holos.platform.v1alpha1.PlatformService.GetForm
*/
export const getForm = {
localName: "getForm",
name: "GetForm",
kind: MethodKind.Unary,
I: GetFormRequest,
O: GetFormResponse,
service: {
typeName: "holos.platform.v1alpha1.PlatformService"
}
} as const;
/**
* @generated from rpc holos.platform.v1alpha1.PlatformService.GetModel
*/
export const getModel = {
localName: "getModel",
name: "GetModel",
kind: MethodKind.Unary,
I: GetModelRequest,
O: GetModelResponse,
service: {
typeName: "holos.platform.v1alpha1.PlatformService"
}
} as const;
/**
* @generated from rpc holos.platform.v1alpha1.PlatformService.PutModel
*/
export const putModel = {
localName: "putModel",
name: "PutModel",
kind: MethodKind.Unary,
I: PutModelRequest,
O: PutModelResponse,
service: {
typeName: "holos.platform.v1alpha1.PlatformService"
}
} as const;

View File

@@ -0,0 +1,71 @@
// @generated by protoc-gen-connect-es v1.4.0 with parameter "target=ts"
// @generated from file holos/v1alpha1/platform.proto (package holos.platform.v1alpha1, syntax proto3)
/* eslint-disable */
// @ts-nocheck
import { AddPlatformRequest, AddPlatformResponse, GetFormRequest, GetFormResponse, GetModelRequest, GetModelResponse, GetPlatformRequest, GetPlatformResponse, ListPlatformsRequest, ListPlatformsResponse, PutModelRequest, PutModelResponse } from "./platform_pb.js";
import { MethodKind } from "@bufbuild/protobuf";
/**
* @generated from service holos.platform.v1alpha1.PlatformService
*/
export const PlatformService = {
typeName: "holos.platform.v1alpha1.PlatformService",
methods: {
/**
* @generated from rpc holos.platform.v1alpha1.PlatformService.AddPlatform
*/
addPlatform: {
name: "AddPlatform",
I: AddPlatformRequest,
O: AddPlatformResponse,
kind: MethodKind.Unary,
},
/**
* @generated from rpc holos.platform.v1alpha1.PlatformService.GetPlatform
*/
getPlatform: {
name: "GetPlatform",
I: GetPlatformRequest,
O: GetPlatformResponse,
kind: MethodKind.Unary,
},
/**
* @generated from rpc holos.platform.v1alpha1.PlatformService.ListPlatforms
*/
listPlatforms: {
name: "ListPlatforms",
I: ListPlatformsRequest,
O: ListPlatformsResponse,
kind: MethodKind.Unary,
},
/**
* @generated from rpc holos.platform.v1alpha1.PlatformService.GetForm
*/
getForm: {
name: "GetForm",
I: GetFormRequest,
O: GetFormResponse,
kind: MethodKind.Unary,
},
/**
* @generated from rpc holos.platform.v1alpha1.PlatformService.GetModel
*/
getModel: {
name: "GetModel",
I: GetModelRequest,
O: GetModelResponse,
kind: MethodKind.Unary,
},
/**
* @generated from rpc holos.platform.v1alpha1.PlatformService.PutModel
*/
putModel: {
name: "PutModel",
I: PutModelRequest,
O: PutModelResponse,
kind: MethodKind.Unary,
},
}
} as const;

View File

@@ -0,0 +1,576 @@
// @generated by protoc-gen-es v1.9.0 with parameter "target=ts"
// @generated from file holos/v1alpha1/platform.proto (package holos.platform.v1alpha1, syntax proto3)
/* eslint-disable */
// @ts-nocheck
import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf";
import { Message, proto3, Struct } from "@bufbuild/protobuf";
/**
* @generated from message holos.platform.v1alpha1.Platform
*/
export class Platform extends Message<Platform> {
/**
* Unique id assigned by the server.
*
* @generated from field: string id = 1;
*/
id = "";
/**
* Organization ID resource owner.
*
* @generated from field: string org_id = 2;
*/
orgId = "";
/**
* name is the platform short name as a dns label.
*
* @generated from field: string name = 3;
*/
name = "";
/**
* @generated from field: string display_name = 4;
*/
displayName = "";
/**
* @generated from field: holos.platform.v1alpha1.PlatformSpec spec = 5;
*/
spec?: PlatformSpec;
constructor(data?: PartialMessage<Platform>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.Platform";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 2, name: "org_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 3, name: "name", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 4, name: "display_name", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 5, name: "spec", kind: "message", T: PlatformSpec },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): Platform {
return new Platform().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): Platform {
return new Platform().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): Platform {
return new Platform().fromJsonString(jsonString, options);
}
static equals(a: Platform | PlainMessage<Platform> | undefined, b: Platform | PlainMessage<Platform> | undefined): boolean {
return proto3.util.equals(Platform, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.PlatformSpec
*/
export class PlatformSpec extends Message<PlatformSpec> {
/**
* model represents the user-defined and user-supplied form field values.
*
* @generated from field: google.protobuf.Struct model = 1;
*/
model?: Struct;
constructor(data?: PartialMessage<PlatformSpec>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.PlatformSpec";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "model", kind: "message", T: Struct },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): PlatformSpec {
return new PlatformSpec().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): PlatformSpec {
return new PlatformSpec().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): PlatformSpec {
return new PlatformSpec().fromJsonString(jsonString, options);
}
static equals(a: PlatformSpec | PlainMessage<PlatformSpec> | undefined, b: PlatformSpec | PlainMessage<PlatformSpec> | undefined): boolean {
return proto3.util.equals(PlatformSpec, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.ListPlatformsRequest
*/
export class ListPlatformsRequest extends Message<ListPlatformsRequest> {
/**
* @generated from field: string org_id = 1;
*/
orgId = "";
constructor(data?: PartialMessage<ListPlatformsRequest>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.ListPlatformsRequest";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "org_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): ListPlatformsRequest {
return new ListPlatformsRequest().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): ListPlatformsRequest {
return new ListPlatformsRequest().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): ListPlatformsRequest {
return new ListPlatformsRequest().fromJsonString(jsonString, options);
}
static equals(a: ListPlatformsRequest | PlainMessage<ListPlatformsRequest> | undefined, b: ListPlatformsRequest | PlainMessage<ListPlatformsRequest> | undefined): boolean {
return proto3.util.equals(ListPlatformsRequest, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.ListPlatformsResponse
*/
export class ListPlatformsResponse extends Message<ListPlatformsResponse> {
/**
* @generated from field: repeated holos.platform.v1alpha1.Platform platforms = 1;
*/
platforms: Platform[] = [];
constructor(data?: PartialMessage<ListPlatformsResponse>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.ListPlatformsResponse";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "platforms", kind: "message", T: Platform, repeated: true },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): ListPlatformsResponse {
return new ListPlatformsResponse().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): ListPlatformsResponse {
return new ListPlatformsResponse().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): ListPlatformsResponse {
return new ListPlatformsResponse().fromJsonString(jsonString, options);
}
static equals(a: ListPlatformsResponse | PlainMessage<ListPlatformsResponse> | undefined, b: ListPlatformsResponse | PlainMessage<ListPlatformsResponse> | undefined): boolean {
return proto3.util.equals(ListPlatformsResponse, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.AddPlatformRequest
*/
export class AddPlatformRequest extends Message<AddPlatformRequest> {
/**
* @generated from field: holos.platform.v1alpha1.Platform platform = 1;
*/
platform?: Platform;
constructor(data?: PartialMessage<AddPlatformRequest>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.AddPlatformRequest";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "platform", kind: "message", T: Platform },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): AddPlatformRequest {
return new AddPlatformRequest().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): AddPlatformRequest {
return new AddPlatformRequest().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): AddPlatformRequest {
return new AddPlatformRequest().fromJsonString(jsonString, options);
}
static equals(a: AddPlatformRequest | PlainMessage<AddPlatformRequest> | undefined, b: AddPlatformRequest | PlainMessage<AddPlatformRequest> | undefined): boolean {
return proto3.util.equals(AddPlatformRequest, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.AddPlatformResponse
*/
export class AddPlatformResponse extends Message<AddPlatformResponse> {
/**
* @generated from field: repeated holos.platform.v1alpha1.Platform platform = 1;
*/
platform: Platform[] = [];
constructor(data?: PartialMessage<AddPlatformResponse>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.AddPlatformResponse";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "platform", kind: "message", T: Platform, repeated: true },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): AddPlatformResponse {
return new AddPlatformResponse().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): AddPlatformResponse {
return new AddPlatformResponse().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): AddPlatformResponse {
return new AddPlatformResponse().fromJsonString(jsonString, options);
}
static equals(a: AddPlatformResponse | PlainMessage<AddPlatformResponse> | undefined, b: AddPlatformResponse | PlainMessage<AddPlatformResponse> | undefined): boolean {
return proto3.util.equals(AddPlatformResponse, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.GetPlatformRequest
*/
export class GetPlatformRequest extends Message<GetPlatformRequest> {
/**
* @generated from field: string platform_id = 1;
*/
platformId = "";
constructor(data?: PartialMessage<GetPlatformRequest>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.GetPlatformRequest";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "platform_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetPlatformRequest {
return new GetPlatformRequest().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetPlatformRequest {
return new GetPlatformRequest().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetPlatformRequest {
return new GetPlatformRequest().fromJsonString(jsonString, options);
}
static equals(a: GetPlatformRequest | PlainMessage<GetPlatformRequest> | undefined, b: GetPlatformRequest | PlainMessage<GetPlatformRequest> | undefined): boolean {
return proto3.util.equals(GetPlatformRequest, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.GetPlatformResponse
*/
export class GetPlatformResponse extends Message<GetPlatformResponse> {
/**
* @generated from field: holos.platform.v1alpha1.Platform platform = 1;
*/
platform?: Platform;
constructor(data?: PartialMessage<GetPlatformResponse>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.GetPlatformResponse";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "platform", kind: "message", T: Platform },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetPlatformResponse {
return new GetPlatformResponse().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetPlatformResponse {
return new GetPlatformResponse().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetPlatformResponse {
return new GetPlatformResponse().fromJsonString(jsonString, options);
}
static equals(a: GetPlatformResponse | PlainMessage<GetPlatformResponse> | undefined, b: GetPlatformResponse | PlainMessage<GetPlatformResponse> | undefined): boolean {
return proto3.util.equals(GetPlatformResponse, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.GetFormRequest
*/
export class GetFormRequest extends Message<GetFormRequest> {
/**
* @generated from field: string platform_id = 1;
*/
platformId = "";
constructor(data?: PartialMessage<GetFormRequest>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.GetFormRequest";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "platform_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetFormRequest {
return new GetFormRequest().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetFormRequest {
return new GetFormRequest().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetFormRequest {
return new GetFormRequest().fromJsonString(jsonString, options);
}
static equals(a: GetFormRequest | PlainMessage<GetFormRequest> | undefined, b: GetFormRequest | PlainMessage<GetFormRequest> | undefined): boolean {
return proto3.util.equals(GetFormRequest, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.GetFormResponse
*/
export class GetFormResponse extends Message<GetFormResponse> {
/**
* model represents the persisted state of the form model.
*
* @generated from field: google.protobuf.Struct model = 1;
*/
model?: Struct;
/**
* fields represents FormlyFieldConfig[] encoded as a JSON array.
*
* @generated from field: repeated google.protobuf.Struct fields = 2;
*/
fields: Struct[] = [];
constructor(data?: PartialMessage<GetFormResponse>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.GetFormResponse";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "model", kind: "message", T: Struct },
{ no: 2, name: "fields", kind: "message", T: Struct, repeated: true },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetFormResponse {
return new GetFormResponse().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetFormResponse {
return new GetFormResponse().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetFormResponse {
return new GetFormResponse().fromJsonString(jsonString, options);
}
static equals(a: GetFormResponse | PlainMessage<GetFormResponse> | undefined, b: GetFormResponse | PlainMessage<GetFormResponse> | undefined): boolean {
return proto3.util.equals(GetFormResponse, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.GetModelRequest
*/
export class GetModelRequest extends Message<GetModelRequest> {
/**
* @generated from field: string platform_id = 1;
*/
platformId = "";
constructor(data?: PartialMessage<GetModelRequest>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.GetModelRequest";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "platform_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetModelRequest {
return new GetModelRequest().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetModelRequest {
return new GetModelRequest().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetModelRequest {
return new GetModelRequest().fromJsonString(jsonString, options);
}
static equals(a: GetModelRequest | PlainMessage<GetModelRequest> | undefined, b: GetModelRequest | PlainMessage<GetModelRequest> | undefined): boolean {
return proto3.util.equals(GetModelRequest, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.GetModelResponse
*/
export class GetModelResponse extends Message<GetModelResponse> {
/**
* model represents the persisted state of the form model.
*
* @generated from field: google.protobuf.Struct model = 1;
*/
model?: Struct;
constructor(data?: PartialMessage<GetModelResponse>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.GetModelResponse";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "model", kind: "message", T: Struct },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetModelResponse {
return new GetModelResponse().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetModelResponse {
return new GetModelResponse().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetModelResponse {
return new GetModelResponse().fromJsonString(jsonString, options);
}
static equals(a: GetModelResponse | PlainMessage<GetModelResponse> | undefined, b: GetModelResponse | PlainMessage<GetModelResponse> | undefined): boolean {
return proto3.util.equals(GetModelResponse, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.PutModelRequest
*/
export class PutModelRequest extends Message<PutModelRequest> {
/**
* @generated from field: string platform_id = 1;
*/
platformId = "";
/**
* @generated from field: google.protobuf.Struct model = 2;
*/
model?: Struct;
constructor(data?: PartialMessage<PutModelRequest>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.PutModelRequest";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "platform_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 2, name: "model", kind: "message", T: Struct },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): PutModelRequest {
return new PutModelRequest().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): PutModelRequest {
return new PutModelRequest().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): PutModelRequest {
return new PutModelRequest().fromJsonString(jsonString, options);
}
static equals(a: PutModelRequest | PlainMessage<PutModelRequest> | undefined, b: PutModelRequest | PlainMessage<PutModelRequest> | undefined): boolean {
return proto3.util.equals(PutModelRequest, a, b);
}
}
/**
* @generated from message holos.platform.v1alpha1.PutModelResponse
*/
export class PutModelResponse extends Message<PutModelResponse> {
/**
* @generated from field: google.protobuf.Struct model = 1;
*/
model?: Struct;
constructor(data?: PartialMessage<PutModelResponse>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.platform.v1alpha1.PutModelResponse";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "model", kind: "message", T: Struct },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): PutModelResponse {
return new PutModelResponse().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): PutModelResponse {
return new PutModelResponse().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): PutModelResponse {
return new PutModelResponse().fromJsonString(jsonString, options);
}
static equals(a: PutModelResponse | PlainMessage<PutModelResponse> | undefined, b: PutModelResponse | PlainMessage<PutModelResponse> | undefined): boolean {
return proto3.util.equals(PutModelResponse, a, b);
}
}

View File

@@ -0,0 +1,35 @@
// @generated by protoc-gen-connect-query v1.3.1 with parameter "target=ts"
// @generated from file holos/v1alpha1/system.proto (package holos.v1alpha1, syntax proto3)
/* eslint-disable */
// @ts-nocheck
import { MethodKind } from "@bufbuild/protobuf";
import { EmptyRequest, EmptyResponse } from "./system_pb.js";
/**
* @generated from rpc holos.v1alpha1.SystemService.SeedDatabase
*/
export const seedDatabase = {
localName: "seedDatabase",
name: "SeedDatabase",
kind: MethodKind.Unary,
I: EmptyRequest,
O: EmptyResponse,
service: {
typeName: "holos.v1alpha1.SystemService"
}
} as const;
/**
* @generated from rpc holos.v1alpha1.SystemService.DropTables
*/
export const dropTables = {
localName: "dropTables",
name: "DropTables",
kind: MethodKind.Unary,
I: EmptyRequest,
O: EmptyResponse,
service: {
typeName: "holos.v1alpha1.SystemService"
}
} as const;

View File

@@ -0,0 +1,35 @@
// @generated by protoc-gen-connect-es v1.4.0 with parameter "target=ts"
// @generated from file holos/v1alpha1/system.proto (package holos.v1alpha1, syntax proto3)
/* eslint-disable */
// @ts-nocheck
import { EmptyRequest, EmptyResponse } from "./system_pb.js";
import { MethodKind } from "@bufbuild/protobuf";
/**
* @generated from service holos.v1alpha1.SystemService
*/
export const SystemService = {
typeName: "holos.v1alpha1.SystemService",
methods: {
/**
* @generated from rpc holos.v1alpha1.SystemService.SeedDatabase
*/
seedDatabase: {
name: "SeedDatabase",
I: EmptyRequest,
O: EmptyResponse,
kind: MethodKind.Unary,
},
/**
* @generated from rpc holos.v1alpha1.SystemService.DropTables
*/
dropTables: {
name: "DropTables",
I: EmptyRequest,
O: EmptyResponse,
kind: MethodKind.Unary,
},
}
} as const;

View File

@@ -0,0 +1,70 @@
// @generated by protoc-gen-es v1.9.0 with parameter "target=ts"
// @generated from file holos/v1alpha1/system.proto (package holos.v1alpha1, syntax proto3)
/* eslint-disable */
// @ts-nocheck
import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf";
import { Message, proto3 } from "@bufbuild/protobuf";
/**
* @generated from message holos.v1alpha1.EmptyRequest
*/
export class EmptyRequest extends Message<EmptyRequest> {
constructor(data?: PartialMessage<EmptyRequest>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.v1alpha1.EmptyRequest";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): EmptyRequest {
return new EmptyRequest().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): EmptyRequest {
return new EmptyRequest().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): EmptyRequest {
return new EmptyRequest().fromJsonString(jsonString, options);
}
static equals(a: EmptyRequest | PlainMessage<EmptyRequest> | undefined, b: EmptyRequest | PlainMessage<EmptyRequest> | undefined): boolean {
return proto3.util.equals(EmptyRequest, a, b);
}
}
/**
* @generated from message holos.v1alpha1.EmptyResponse
*/
export class EmptyResponse extends Message<EmptyResponse> {
constructor(data?: PartialMessage<EmptyResponse>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.v1alpha1.EmptyResponse";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): EmptyResponse {
return new EmptyResponse().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): EmptyResponse {
return new EmptyResponse().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): EmptyResponse {
return new EmptyResponse().fromJsonString(jsonString, options);
}
static equals(a: EmptyResponse | PlainMessage<EmptyResponse> | undefined, b: EmptyResponse | PlainMessage<EmptyResponse> | undefined): boolean {
return proto3.util.equals(EmptyResponse, a, b);
}
}

View File

@@ -256,6 +256,43 @@ export class Claims extends Message<Claims> {
}
}
/**
* @generated from message holos.v1alpha1.Creator
*/
export class Creator extends Message<Creator> {
/**
* @generated from field: string id = 1;
*/
id = "";
constructor(data?: PartialMessage<Creator>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "holos.v1alpha1.Creator";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): Creator {
return new Creator().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): Creator {
return new Creator().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): Creator {
return new Creator().fromJsonString(jsonString, options);
}
static equals(a: Creator | PlainMessage<Creator> | undefined, b: Creator | PlainMessage<Creator> | undefined): boolean {
return proto3.util.equals(Creator, a, b);
}
}
/**
* UserClaims represents id token claims
*

View File

@@ -8,7 +8,7 @@
</mat-toolbar>
<mat-nav-list>
<a mat-list-item routerLink="/home" routerLinkActive="active-link">Home</a>
<a mat-list-item routerLink="/clusters" routerLinkActive="active-link">Clusters</a>
<a mat-list-item routerLink="/platforms" routerLinkActive="active-link">Platforms</a>
</mat-nav-list>
</mat-sidenav>
<mat-sidenav-content>

View File

@@ -13,7 +13,7 @@
.mat-toolbar.mat-primary {
position: sticky;
top: 0;
z-index: 1;
z-index: 1000;
}
.toolbar-spacer {

View File

@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { PlatformService } from './platform.service';
describe('PlatformService', () => {
let service: PlatformService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(PlatformService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View File

@@ -0,0 +1,40 @@
import { Inject, Injectable } from '@angular/core';
import { PlatformService as ConnectPlatformService } from '../gen/holos/v1alpha1/platform_connect';
import { Observable, filter, of, switchMap } from 'rxjs';
import { ObservableClient } from '../../connect/observable-client';
import { Platform, GetFormResponse, ListPlatformsRequest, PutModelRequest, PutModelResponse } from '../gen/holos/v1alpha1/platform_pb';
import { Organization } from '../gen/holos/v1alpha1/organization_pb';
import { JsonValue, Struct, } from '@bufbuild/protobuf';
@Injectable({
providedIn: 'root'
})
export class PlatformService {
listPlatforms(org: Observable<Organization>): Observable<Platform[]> {
return org.pipe(
switchMap(org => {
const req = new ListPlatformsRequest({ orgId: org.id })
return this.client.listPlatforms(req).pipe(
switchMap(resp => { return of(resp.platforms) })
)
})
)
}
getForm(id: string): Observable<GetFormResponse> {
return this.client.getForm({ platformId: id })
}
putModel(id: string, model: JsonValue): Observable<PutModelResponse> {
const req = new PutModelRequest({
platformId: id,
// "We recommend to use fromJson() to construct Struct literals" refer to
// https://github.com/bufbuild/protobuf-es/blob/main/docs/runtime_api.md#struct
model: Struct.fromJson(model),
})
return this.client.putModel(req)
}
constructor(@Inject(ConnectPlatformService) private client: ObservableClient<typeof ConnectPlatformService>) { }
}

View File

@@ -0,0 +1,23 @@
<div class="content-container">
<mat-tab-group>
<mat-tab label="Detail">
<div class="grid-container">
<form [formGroup]="form" (ngSubmit)="onSubmit(model)">
<formly-form [model]="model" [form]="form" [fields]="fields"></formly-form>
<button type="submit" mat-flat-button color="primary">Submit</button>
</form>
</div>
</mat-tab>
<mat-tab label="Model">
<div class="grid-container">
<pre>{{ model | json }}</pre>
</div>
</mat-tab>
<mat-tab label="Fields">
<div class="grid-container">
<pre>{{ fields | json }}</pre>
</div>
</mat-tab>
</mat-tab-group>
</div>

View File

@@ -0,0 +1,3 @@
.grid-container {
margin: 20px;
}

View File

@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PlatformDetailComponent } from './platform-detail.component';
describe('PlatformDetailComponent', () => {
let component: PlatformDetailComponent;
let fixture: ComponentFixture<PlatformDetailComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [PlatformDetailComponent]
})
.compileComponents();
fixture = TestBed.createComponent(PlatformDetailComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,78 @@
import { Component, Input, OnDestroy, inject } from '@angular/core';
import { Observable, Subject, shareReplay, takeUntil } from 'rxjs';
import { PlatformService } from '../../services/platform.service';
import { GetFormResponse } from '../../gen/holos/v1alpha1/platform_pb';
import { MatTab, MatTabGroup } from '@angular/material/tabs';
import { AsyncPipe, CommonModule } from '@angular/common';
import { FormGroup, ReactiveFormsModule } from '@angular/forms';
import { FormlyMaterialModule } from '@ngx-formly/material';
import { FormlyFieldConfig, FormlyFormOptions, FormlyModule } from '@ngx-formly/core';
import { MatButton } from '@angular/material/button';
import { MatDivider } from '@angular/material/divider';
import { JsonObject, JsonValue } from '@bufbuild/protobuf';
@Component({
selector: 'app-platform-detail',
standalone: true,
imports: [
AsyncPipe,
CommonModule,
FormlyMaterialModule,
FormlyModule,
MatButton,
MatDivider,
MatTab,
MatTabGroup,
ReactiveFormsModule,
],
templateUrl: './platform-detail.component.html',
styleUrl: './platform-detail.component.scss'
})
export class PlatformDetailComponent implements OnDestroy {
private platformService = inject(PlatformService);
private platformId: string = "";
private destroy$: Subject<any> = new Subject<any>();
form = new FormGroup({});
model: JsonValue = {};
options: FormlyFormOptions = {};
fields: FormlyFieldConfig[] = [];
onSubmit(model: JsonValue) {
// if (this.form.valid) {
console.log(model)
this.platformService
.putModel(this.platformId, model)
.pipe(takeUntil(this.destroy$))
.subscribe(resp => {
const model = JSON.parse(JSON.stringify(resp.model))
if (model) {
this.model = model
}
})
// }
}
@Input()
set id(platformId: string) {
this.platformId = platformId;
this.platformService
.getForm(platformId)
.pipe(takeUntil(this.destroy$))
.subscribe(resp => {
if (resp.fields !== undefined) {
// NOTE: We could map fields to mix in javascript functions. Refer to
// https://formly.dev/docs/examples/other/json-powered
this.fields = resp.fields.map(field => field.toJson() as FormlyFieldConfig)
}
if (resp.model !== undefined) {
this.model = resp.model.toJson()
}
})
}
public ngOnDestroy(): void {
this.destroy$.next(true);
this.destroy$.complete();
}
}

View File

@@ -0,0 +1,11 @@
<div class="grid-container">
<mat-nav-list>
<h3 mat-subheader>Platforms</h3>
<p>Select a platform to manage.</p>
@for (platform of (platforms$ | async); track platform.id) {
<a mat-list-item [routerLink]="['/platform', platform.id]">
{{ platform.displayName ? platform.displayName : platform.name }}
</a>
}
</mat-nav-list>
</div>

View File

@@ -0,0 +1,3 @@
.grid-container {
margin: 20px;
}

View File

@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PlatformsComponent } from './platforms.component';
describe('PlatformsComponent', () => {
let component: PlatformsComponent;
let fixture: ComponentFixture<PlatformsComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [PlatformsComponent]
})
.compileComponents();
fixture = TestBed.createComponent(PlatformsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,37 @@
import { Platform } from '../../gen/holos/v1alpha1/platform_pb';
import { Component, inject } from '@angular/core';
import { MatListItem, MatNavList } from '@angular/material/list';
import { Observable, filter } from 'rxjs';
import { Organization } from '../../gen/holos/v1alpha1/organization_pb';
import { OrganizationService } from '../../services/organization.service';
import { PlatformService } from '../../services/platform.service';
import { AsyncPipe, CommonModule } from '@angular/common';
import { RouterLink } from '@angular/router';
@Component({
selector: 'app-platforms',
standalone: true,
imports: [
MatNavList,
MatListItem,
AsyncPipe,
CommonModule,
RouterLink,
],
templateUrl: './platforms.component.html',
styleUrl: './platforms.component.scss'
})
export class PlatformsComponent {
private orgSvc = inject(OrganizationService);
private platformSvc = inject(PlatformService);
org$!: Observable<Organization | undefined>;
platforms$!: Observable<Platform[]>;
ngOnInit(): void {
this.org$ = this.orgSvc.activeOrg();
this.platforms$ = this.platformSvc.listPlatforms(this.org$.pipe(
filter((org): org is Organization => org !== undefined)
))
}
}

View File

@@ -0,0 +1,7 @@
<div class="card">
<h2 class="card-header">{{ props.label }}</h2>
<div class="card-body">
<p>{{ props.description }}</p>
<ng-container #fieldComponent></ng-container>
</div>
</div>

View File

@@ -0,0 +1,3 @@
.card {
margin-bottom: 20px;
}

View File

@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { HolosPanelWrapperComponent } from './holos-panel-wrapper.component';
describe('HolosPanelWrapperComponent', () => {
let component: HolosPanelWrapperComponent;
let fixture: ComponentFixture<HolosPanelWrapperComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [HolosPanelWrapperComponent]
})
.compileComponents();
fixture = TestBed.createComponent(HolosPanelWrapperComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,11 @@
import { Component } from '@angular/core';
import { FieldWrapper } from '@ngx-formly/core';
@Component({
selector: 'formly-wrapper-holos-panel',
standalone: true,
imports: [],
templateUrl: './holos-panel-wrapper.component.html',
styleUrl: './holos-panel-wrapper.component.scss'
})
export class HolosPanelWrapperComponent extends FieldWrapper { }

View File

@@ -0,0 +1,31 @@
package holos
import ( "encoding/yaml"
)
// The platform configmap is a simple component that manages a configmap named
// platform in the default namespace. The purpose is to exercise end to end
// validation of platform configuration values provided by the holos web ui to
// each cluster in the platform.
platform: #Platform & {metadata: name: "bare"}
let PLATFORM = platform
// spec represents the output provided to holos
spec: components: KubernetesObjectsList: [
#KubernetesObjects & {
metadata: name: "platform-configmap"
apiObjectMap: OBJECTS.apiObjectMap
},
]
// OBJECTS represents the kubernetes api objects to manage.
let OBJECTS = #APIObjects & {
apiObjects: ConfigMap: platform: {
metadata: {
name: "platform"
namespace: "default"
}
data: platform: yaml.Marshal(PLATFORM)
}
}

View File

@@ -0,0 +1,135 @@
package forms
import formsv1 "github.com/holos-run/forms/v1alpha1"
let Platform = formsv1.#Platform & {
name: "bare"
displayName: "Bare Platform"
sections: org: {
displayName: "Organization"
description: "Organization config values are used to derive more specific configuration values throughout the platform."
fieldConfigs: {
// platform.spec.config.user.sections.org.fields.name
name: {
type: "input"
props: {
label: "Name"
// placeholder: "example" placeholder cannot be used with validation?
description: "DNS label, e.g. 'example'"
pattern: "^[a-z]([0-9a-z]|-){1,28}[0-9a-z]$"
minLength: 3
maxLength: 30
required: true
}
validation: messages: {
pattern: "It must be 3 to 30 lowercase letters, digits, or hyphens. It must start with a letter. Trailing hyphens are prohibited."
}
}
// platform.spec.config.user.sections.org.fields.domain
domain: {
type: "input"
props: {
label: "Domain"
placeholder: "example.com"
minLength: 3
maxLength: 100
description: "DNS domain, e.g. 'example.com'"
required: true
}
}
// platform.spec.config.user.sections.org.fields.displayName
displayName: {
type: "input"
props: {
label: "Display Name"
placeholder: "Example Organization"
description: "Display name, e.g. 'Example Organization'"
maxLength: 100
required: true
}
}
// platform.spec.config.user.sections.org.fields.contactEmail
contactEmail: {
type: "input"
props: {
label: "Contact Email"
placeholder: "platform-team@example.com"
description: "Technical contact email address"
required: true
}
}
}
}
sections: privacy: {
displayName: "Data Privacy"
description: "Configure data privacy aspects of the platform."
fieldConfigs: {
country: {
// https://formly.dev/docs/api/ui/material/select/
type: "select"
props: {
label: "Select Planet"
description: "Juridiction of applicable data privacy laws."
options: [
{value: "mercury", label: "Mercury"},
{value: "venus", label: "Venus"},
{value: "earth", label: "Earth"},
{value: "mars", label: "Mars"},
{value: "jupiter", label: "Jupiter"},
{value: "saturn", label: "Saturn"},
{value: "uranus", label: "Uranus"},
{value: "neptune", label: "Neptune"},
]
}
}
regions: {
// https://formly.dev/docs/api/ui/material/select/
type: "select"
props: {
label: "Select Regions"
description: "Select the regions this platform operates in."
multiple: true
selectAllOption: "Select All"
options: [
{value: "us-east-2", label: "Ohio"},
{value: "us-west-2", label: "Oregon"},
{value: "eu-west-1", label: "Ireland"},
{value: "eu-west-2", label: "London", disabled: true},
]
}
}
}
}
// https://v5.formly.dev/ui/material
sections: terms: {
displayName: "Terms and Conditions"
description: "Example of a boolean checkbox."
fieldConfigs: {
// platform.spec.config.user.sections.terms.fields.didAgree
didAgree: {
type: "checkbox"
props: {
label: "Accept terms"
description: "In order to proceed, please accept terms"
pattern: "true"
required: true
}
validation: {
messages: {
pattern: "Please accept the terms"
}
}
}
}
}
}
// Provide the output form fields
Platform.Form

View File

@@ -0,0 +1,63 @@
package holos
import (
h "github.com/holos-run/holos/api/v1alpha1"
"encoding/yaml"
)
// CUE provides a #BuildPlan to the holos cli. Holos requires the output of CUE
// to conform to the #BuildPlan schema.
{} & h.#BuildPlan
// #HolosComponent defines struct fields common to all holos component types.
#HolosComponent: {
h.#HolosComponent
metadata: name: string
_NameLengthConstraint: len(metadata.name) & >=1
...
}
#KubernetesObjects: #HolosComponent & h.#KubernetesObjects
// #HolosTypeMeta is similar to kubernetes api TypeMeta, but for holos api
// objects such as the Platform config resource.
#HolosTypeMeta: {
kind: string @go(Kind)
apiVersion: string @go(APIVersion)
}
// #HolosObjectMeta is similar to kubernetes api ObjectMeta, but for holos api
// objects.
#HolosObjectMeta: {
name: string @go(Name)
labels: {[string]: string} @go(Labels,map[string]string)
annotations: {[string]: string} @go(Annotations,map[string]string)
}
// #APIObjects defines the output format for kubernetes api objects. The holos
// cli expects the yaml representation of each api object in the apiObjectMap
// field.
#APIObjects: {
// apiObjects represents the un-marshalled form of each kubernetes api object
// managed by a holos component.
apiObjects: {
[Kind=_]: {
[string]: {
kind: Kind
...
}
}
ConfigMap?: [Name=_]: #ConfigMap & {metadata: name: Name}
}
// apiObjectMap holds the marshalled representation of apiObjects
apiObjectMap: {
for kind, v in apiObjects {
"\(kind)": {
for name, obj in v {
"\(name)": yaml.Marshal(obj)
}
}
}
}
}

View File

@@ -0,0 +1,13 @@
package holos
import (
corev1 "k8s.io/api/core/v1"
)
_NamespaceObject: {
metadata: name: string
metadata: namespace: string
metadata: labels: "app.holos.run/managed": "true"
}
#ConfigMap: _NamespaceObject & corev1.#ConfigMap

View File

@@ -0,0 +1,39 @@
package holos
// #Platform represents the user supplied platform configuration.
#Platform: {
#HolosTypeMeta
kind: "Platform"
apiVersion: "app.holos.run/v1alpha1"
metadata: #HolosObjectMeta
spec: #PlatformSpec
holos: #Holos
}
// #Holos represents the holos reserved field in the #Platform schema defined by the holos development team.
#Holos: {
// flags represents config values provided by holos command line flags.
flags: {
// cluster represents the holos render --cluster-name flag.
cluster: string @tag(cluster, type=string)
}
}
// #PlatformSpec represents configuration values defined by the platform
// designer. Config values are organized by section, then simple strings for
// each section.
#PlatformSpec: {
config: [string]: _
config: user: #UserDefinedConfig
}
// #PlatformUserConfig represents configuration fields and values defined by the
// user.
#UserDefinedConfig: {
sections: [string]: fields: [string]: _
}
// #PlatformConfig represents the platform config data returned from the Holos API. Useful for cue vet.
#PlatformConfig: {
platform: spec: #PlatformSpec
}

View File

@@ -0,0 +1,20 @@
{
"platform": {
"spec": {
"config": {
"user": {
"sections": {
"org": {
"fields": {
"contactEmail": "jeff@openinfrastructure.co",
"displayName": "Open Infrastructure Services LLC",
"domain": "ois.run",
"name": "ois"
}
}
}
}
}
}
}
}

View File

@@ -0,0 +1 @@
package holos

View File

@@ -0,0 +1,26 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
// BuildPlan is the primary interface between CUE and the Holos cli.
#BuildPlan: {
#TypeMeta
// Metadata represents the holos component name
metadata?: #ObjectMeta @go(Metadata)
spec?: #BuildPlanSpec @go(Spec)
}
#BuildPlanSpec: {
disabled?: bool @go(Disabled)
components?: #BuildPlanComponents @go(Components)
}
#BuildPlanComponents: {
helmChartList?: [...#HelmChart] @go(HelmChartList,[]HelmChart)
kubernetesObjectsList?: [...#KubernetesObjects] @go(KubernetesObjectsList,[]KubernetesObjects)
kustomizeBuildList?: [...#KustomizeBuild] @go(KustomizeBuildList,[]KustomizeBuild)
resources?: {[string]: #KubernetesObjects} @go(Resources,map[string]KubernetesObjects)
}

View File

@@ -0,0 +1,24 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
// HolosComponent defines the fields common to all holos component kinds including the Render Result.
#HolosComponent: {
#TypeMeta
// Metadata represents the holos component name
metadata?: #ObjectMeta @go(Metadata)
// APIObjectMap holds the marshalled representation of api objects. Think of
// these as resources overlaid at the back of the render pipeline.
apiObjectMap?: #APIObjectMap @go(APIObjectMap)
#Kustomization
#Kustomize
// Skip causes holos to take no action regarding the component.
Skip: bool
}

View File

@@ -0,0 +1,15 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
#APIVersion: "holos.run/v1alpha1"
#BuildPlanKind: "BuildPlan"
#HelmChartKind: "HelmChart"
// ChartDir is the directory name created in the holos component directory to cache a chart.
#ChartDir: "vendor"
// ResourcesFile is the file name used to store component output when post-processing with kustomize.
#ResourcesFile: "resources.yaml"

View File

@@ -0,0 +1,6 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
// Package v1alpha1 defines the api boundary between CUE and Holos.
package v1alpha1

View File

@@ -0,0 +1,28 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
// A HelmChart represents a helm command to provide chart values in order to render kubernetes api objects.
#HelmChart: {
#HolosComponent
// Namespace is the namespace to install into. TODO: Use metadata.namespace instead.
namespace: string @go(Namespace)
chart: #Chart @go(Chart)
valuesContent: string @go(ValuesContent)
enableHooks: bool @go(EnableHooks)
}
#Chart: {
name: string @go(Name)
version: string @go(Version)
release: string @go(Release)
repository?: #Repository @go(Repository)
}
#Repository: {
name: string @go(Name)
url: string @go(URL)
}

View File

@@ -0,0 +1,12 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
#KubernetesObjectsKind: "KubernetesObjects"
// KubernetesObjects represents CUE output which directly provides Kubernetes api objects to holos.
#KubernetesObjects: {
#HolosComponent
}

View File

@@ -0,0 +1,11 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
// Kustomization holds the rendered flux kustomization api object content for git ops.
#Kustomization: {
// KsContent is the yaml representation of the flux kustomization for gitops.
ksContent?: string @go(KsContent)
}

View File

@@ -0,0 +1,25 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
#KustomizeBuildKind: "KustomizeBuild"
// Kustomize represents resources necessary to execute a kustomize build.
// Intended for at least two use cases:
//
// 1. Process raw yaml file resources in a holos component directory.
// 2. Post process a HelmChart to inject istio, add custom labels, etc...
#Kustomize: {
// KustomizeFiles holds file contents for kustomize, e.g. patch files.
kustomizeFiles?: #FileContentMap @go(KustomizeFiles)
// ResourcesFile is the file name used for api objects in kustomization.yaml
resourcesFile?: string @go(ResourcesFile)
}
// KustomizeBuild renders plain yaml files in the holos component directory using kubectl kustomize build.
#KustomizeBuild: {
#HolosComponent
}

View File

@@ -0,0 +1,12 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
#KustomizeBuildKind: "KustomizeBuild"
// KustomizeBuild
#KustomizeBuild: {
#HolosComponent
}

View File

@@ -0,0 +1,18 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
// Label is an arbitrary unique identifier. Defined as a type for clarity and type checking.
#Label: string
// Kind is a kubernetes api object kind. Defined as a type for clarity and type checking.
#Kind: string
// APIObjectMap is the shape of marshalled api objects returned from cue to the
// holos cli. A map is used to improve the clarity of error messages from cue.
#APIObjectMap: {[string]: [string]: string}
// FileContentMap is a map of file names to file contents.
#FileContentMap: {[string]: string}

View File

@@ -0,0 +1,22 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
// ObjectMeta represents metadata of a holos component object. The fields are a
// copy of upstream kubernetes api machinery but are by holos objects distinct
// from kubernetes api objects.
#ObjectMeta: {
// Name uniquely identifies the holos component instance and must be suitable as a file name.
name?: string @go(Name)
// Namespace confines a holos component to a single namespace via kustomize if set.
namespace?: string @go(Namespace)
// Labels are not used but are copied from api machinery ObjectMeta for completeness.
labels?: {[string]: string} @go(Labels,map[string]string)
// Annotations are not used but are copied from api machinery ObjectMeta for completeness.
annotations?: {[string]: string} @go(Annotations,map[string]string)
}

View File

@@ -0,0 +1,7 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
#Renderer: _

View File

@@ -0,0 +1,10 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
// Result is the build result for display or writing. Holos components Render the Result as a data pipeline.
#Result: {
HolosComponent: #HolosComponent
}

View File

@@ -0,0 +1,10 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go github.com/holos-run/holos/api/v1alpha1
package v1alpha1
#TypeMeta: {
kind?: string @go(Kind)
apiVersion?: string @go(APIVersion)
}

View File

@@ -0,0 +1,147 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/api/core/v1
package v1
// ImagePolicyFailedOpenKey is added to pods created by failing open when the image policy
// webhook backend fails.
#ImagePolicyFailedOpenKey: "alpha.image-policy.k8s.io/failed-open"
// MirrorAnnotationKey represents the annotation key set by kubelets when creating mirror pods
#MirrorPodAnnotationKey: "kubernetes.io/config.mirror"
// TolerationsAnnotationKey represents the key of tolerations data (json serialized)
// in the Annotations of a Pod.
#TolerationsAnnotationKey: "scheduler.alpha.kubernetes.io/tolerations"
// TaintsAnnotationKey represents the key of taints data (json serialized)
// in the Annotations of a Node.
#TaintsAnnotationKey: "scheduler.alpha.kubernetes.io/taints"
// SeccompPodAnnotationKey represents the key of a seccomp profile applied
// to all containers of a pod.
// Deprecated: set a pod security context `seccompProfile` field.
#SeccompPodAnnotationKey: "seccomp.security.alpha.kubernetes.io/pod"
// SeccompContainerAnnotationKeyPrefix represents the key of a seccomp profile applied
// to one container of a pod.
// Deprecated: set a container security context `seccompProfile` field.
#SeccompContainerAnnotationKeyPrefix: "container.seccomp.security.alpha.kubernetes.io/"
// SeccompProfileRuntimeDefault represents the default seccomp profile used by container runtime.
// Deprecated: set a pod or container security context `seccompProfile` of type "RuntimeDefault" instead.
#SeccompProfileRuntimeDefault: "runtime/default"
// SeccompProfileNameUnconfined is the unconfined seccomp profile.
#SeccompProfileNameUnconfined: "unconfined"
// SeccompLocalhostProfileNamePrefix is the prefix for specifying profiles loaded from the node's disk.
#SeccompLocalhostProfileNamePrefix: "localhost/"
// AppArmorBetaContainerAnnotationKeyPrefix is the prefix to an annotation key specifying a container's apparmor profile.
#AppArmorBetaContainerAnnotationKeyPrefix: "container.apparmor.security.beta.kubernetes.io/"
// AppArmorBetaDefaultProfileAnnotationKey is the annotation key specifying the default AppArmor profile.
#AppArmorBetaDefaultProfileAnnotationKey: "apparmor.security.beta.kubernetes.io/defaultProfileName"
// AppArmorBetaAllowedProfilesAnnotationKey is the annotation key specifying the allowed AppArmor profiles.
#AppArmorBetaAllowedProfilesAnnotationKey: "apparmor.security.beta.kubernetes.io/allowedProfileNames"
// AppArmorBetaProfileRuntimeDefault is the profile specifying the runtime default.
#AppArmorBetaProfileRuntimeDefault: "runtime/default"
// AppArmorBetaProfileNamePrefix is the prefix for specifying profiles loaded on the node.
#AppArmorBetaProfileNamePrefix: "localhost/"
// AppArmorBetaProfileNameUnconfined is the Unconfined AppArmor profile
#AppArmorBetaProfileNameUnconfined: "unconfined"
// DeprecatedSeccompProfileDockerDefault represents the default seccomp profile used by docker.
// Deprecated: set a pod or container security context `seccompProfile` of type "RuntimeDefault" instead.
#DeprecatedSeccompProfileDockerDefault: "docker/default"
// PreferAvoidPodsAnnotationKey represents the key of preferAvoidPods data (json serialized)
// in the Annotations of a Node.
#PreferAvoidPodsAnnotationKey: "scheduler.alpha.kubernetes.io/preferAvoidPods"
// ObjectTTLAnnotationKey represents a suggestion for kubelet for how long it can cache
// an object (e.g. secret, config map) before fetching it again from apiserver.
// This annotation can be attached to node.
#ObjectTTLAnnotationKey: "node.alpha.kubernetes.io/ttl"
// annotation key prefix used to identify non-convertible json paths.
#NonConvertibleAnnotationPrefix: "non-convertible.kubernetes.io"
_#kubectlPrefix: "kubectl.kubernetes.io/"
// LastAppliedConfigAnnotation is the annotation used to store the previous
// configuration of a resource for use in a three way diff by UpdateApplyAnnotation.
#LastAppliedConfigAnnotation: "kubectl.kubernetes.io/last-applied-configuration"
// AnnotationLoadBalancerSourceRangesKey is the key of the annotation on a service to set allowed ingress ranges on their LoadBalancers
//
// It should be a comma-separated list of CIDRs, e.g. `0.0.0.0/0` to
// allow full access (the default) or `18.0.0.0/8,56.0.0.0/8` to allow
// access only from the CIDRs currently allocated to MIT & the USPS.
//
// Not all cloud providers support this annotation, though AWS & GCE do.
#AnnotationLoadBalancerSourceRangesKey: "service.beta.kubernetes.io/load-balancer-source-ranges"
// EndpointsLastChangeTriggerTime is the annotation key, set for endpoints objects, that
// represents the timestamp (stored as RFC 3339 date-time string, e.g. '2018-10-22T19:32:52.1Z')
// of the last change, of some Pod or Service object, that triggered the endpoints object change.
// In other words, if a Pod / Service changed at time T0, that change was observed by endpoints
// controller at T1, and the Endpoints object was changed at T2, the
// EndpointsLastChangeTriggerTime would be set to T0.
//
// The "endpoints change trigger" here means any Pod or Service change that resulted in the
// Endpoints object change.
//
// Given the definition of the "endpoints change trigger", please note that this annotation will
// be set ONLY for endpoints object changes triggered by either Pod or Service change. If the
// Endpoints object changes due to other reasons, this annotation won't be set (or updated if it's
// already set).
//
// This annotation will be used to compute the in-cluster network programming latency SLI, see
// https://github.com/kubernetes/community/blob/master/sig-scalability/slos/network_programming_latency.md
#EndpointsLastChangeTriggerTime: "endpoints.kubernetes.io/last-change-trigger-time"
// EndpointsOverCapacity will be set on an Endpoints resource when it
// exceeds the maximum capacity of 1000 addresses. Initially the Endpoints
// controller will set this annotation with a value of "warning". In a
// future release, the controller may set this annotation with a value of
// "truncated" to indicate that any addresses exceeding the limit of 1000
// have been truncated from the Endpoints resource.
#EndpointsOverCapacity: "endpoints.kubernetes.io/over-capacity"
// MigratedPluginsAnnotationKey is the annotation key, set for CSINode objects, that is a comma-separated
// list of in-tree plugins that will be serviced by the CSI backend on the Node represented by CSINode.
// This annotation is used by the Attach Detach Controller to determine whether to use the in-tree or
// CSI Backend for a volume plugin on a specific node.
#MigratedPluginsAnnotationKey: "storage.alpha.kubernetes.io/migrated-plugins"
// PodDeletionCost can be used to set to an int32 that represent the cost of deleting
// a pod compared to other pods belonging to the same ReplicaSet. Pods with lower
// deletion cost are preferred to be deleted before pods with higher deletion cost.
// Note that this is honored on a best-effort basis, and so it does not offer guarantees on
// pod deletion order.
// The implicit deletion cost for pods that don't set the annotation is 0, negative values are permitted.
//
// This annotation is beta-level and is only honored when PodDeletionCost feature is enabled.
#PodDeletionCost: "controller.kubernetes.io/pod-deletion-cost"
// DeprecatedAnnotationTopologyAwareHints can be used to enable or disable
// Topology Aware Hints for a Service. This may be set to "Auto" or
// "Disabled". Any other value is treated as "Disabled". This annotation has
// been deprecated in favor of the "service.kubernetes.io/topology-mode"
// annotation.
#DeprecatedAnnotationTopologyAwareHints: "service.kubernetes.io/topology-aware-hints"
// AnnotationTopologyMode can be used to enable or disable Topology Aware
// Routing for a Service. Well known values are "Auto" and "Disabled".
// Implementations may choose to develop new topology approaches, exposing
// them with domain-prefixed values. For example, "example.com/lowest-rtt"
// could be a valid implementation-specific value for this annotation. These
// heuristics will often populate topology hints on EndpointSlices, but that
// is not a requirement.
#AnnotationTopologyMode: "service.kubernetes.io/topology-mode"

View File

@@ -0,0 +1,6 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/api/core/v1
// Package v1 is the v1 version of the core API.
package v1

View File

@@ -0,0 +1,7 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/api/core/v1
package v1
#GroupName: ""

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,59 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/api/core/v1
package v1
#LabelHostname: "kubernetes.io/hostname"
// Label value is the network location of kube-apiserver stored as <ip:port>
// Stored in APIServer Identity lease objects to view what address is used for peer proxy
#AnnotationPeerAdvertiseAddress: "kubernetes.io/peer-advertise-address"
#LabelTopologyZone: "topology.kubernetes.io/zone"
#LabelTopologyRegion: "topology.kubernetes.io/region"
// These label have been deprecated since 1.17, but will be supported for
// the foreseeable future, to accommodate things like long-lived PVs that
// use them. New users should prefer the "topology.kubernetes.io/*"
// equivalents.
#LabelFailureDomainBetaZone: "failure-domain.beta.kubernetes.io/zone"
#LabelFailureDomainBetaRegion: "failure-domain.beta.kubernetes.io/region"
// Retained for compat when vendored. Do not use these consts in new code.
#LabelZoneFailureDomain: "failure-domain.beta.kubernetes.io/zone"
#LabelZoneRegion: "failure-domain.beta.kubernetes.io/region"
#LabelZoneFailureDomainStable: "topology.kubernetes.io/zone"
#LabelZoneRegionStable: "topology.kubernetes.io/region"
#LabelInstanceType: "beta.kubernetes.io/instance-type"
#LabelInstanceTypeStable: "node.kubernetes.io/instance-type"
#LabelOSStable: "kubernetes.io/os"
#LabelArchStable: "kubernetes.io/arch"
// LabelWindowsBuild is used on Windows nodes to specify the Windows build number starting with v1.17.0.
// It's in the format MajorVersion.MinorVersion.BuildNumber (for ex: 10.0.17763)
#LabelWindowsBuild: "node.kubernetes.io/windows-build"
// LabelNamespaceSuffixKubelet is an allowed label namespace suffix kubelets can self-set ([*.]kubelet.kubernetes.io/*)
#LabelNamespaceSuffixKubelet: "kubelet.kubernetes.io"
// LabelNamespaceSuffixNode is an allowed label namespace suffix kubelets can self-set ([*.]node.kubernetes.io/*)
#LabelNamespaceSuffixNode: "node.kubernetes.io"
// LabelNamespaceNodeRestriction is a forbidden label namespace that kubelets may not self-set when the NodeRestriction admission plugin is enabled
#LabelNamespaceNodeRestriction: "node-restriction.kubernetes.io"
// IsHeadlessService is added by Controller to an Endpoint denoting if its parent
// Service is Headless. The existence of this label can be used further by other
// controllers and kube-proxy to check if the Endpoint objects should be replicated when
// using Headless Services
#IsHeadlessService: "service.kubernetes.io/headless"
// LabelNodeExcludeBalancers specifies that the node should not be considered as a target
// for external load-balancers which use nodes as a second hop (e.g. many cloud LBs which only
// understand nodes). For services that use externalTrafficPolicy=Local, this may mean that
// any backends on excluded nodes are not reachable by those external load-balancers.
// Implementations of this exclusion may vary based on provider.
#LabelNodeExcludeBalancers: "node.kubernetes.io/exclude-from-external-load-balancers"
// LabelMetadataName is the label name which, in-tree, is used to automatically label namespaces, so they can be selected easily by tools which require definitive labels
#LabelMetadataName: "kubernetes.io/metadata.name"

View File

@@ -0,0 +1,38 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/api/core/v1
package v1
// TaintNodeNotReady will be added when node is not ready
// and removed when node becomes ready.
#TaintNodeNotReady: "node.kubernetes.io/not-ready"
// TaintNodeUnreachable will be added when node becomes unreachable
// (corresponding to NodeReady status ConditionUnknown)
// and removed when node becomes reachable (NodeReady status ConditionTrue).
#TaintNodeUnreachable: "node.kubernetes.io/unreachable"
// TaintNodeUnschedulable will be added when node becomes unschedulable
// and removed when node becomes schedulable.
#TaintNodeUnschedulable: "node.kubernetes.io/unschedulable"
// TaintNodeMemoryPressure will be added when node has memory pressure
// and removed when node has enough memory.
#TaintNodeMemoryPressure: "node.kubernetes.io/memory-pressure"
// TaintNodeDiskPressure will be added when node has disk pressure
// and removed when node has enough disk.
#TaintNodeDiskPressure: "node.kubernetes.io/disk-pressure"
// TaintNodeNetworkUnavailable will be added when node's network is unavailable
// and removed when network becomes ready.
#TaintNodeNetworkUnavailable: "node.kubernetes.io/network-unavailable"
// TaintNodePIDPressure will be added when node has pid pressure
// and removed when node has enough pid.
#TaintNodePIDPressure: "node.kubernetes.io/pid-pressure"
// TaintNodeOutOfService can be added when node is out of service in case of
// a non-graceful shutdown
#TaintNodeOutOfService: "node.kubernetes.io/out-of-service"

View File

@@ -0,0 +1,47 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/apimachinery/pkg/api/resource
package resource
// Scale is used for getting and setting the base-10 scaled value.
// Base-2 scales are omitted for mathematical simplicity.
// See Quantity.ScaledValue for more details.
#Scale: int32 // #enumScale
#enumScale:
#Nano |
#Micro |
#Milli |
#Kilo |
#Mega |
#Giga |
#Tera |
#Peta |
#Exa
#values_Scale: {
Nano: #Nano
Micro: #Micro
Milli: #Milli
Kilo: #Kilo
Mega: #Mega
Giga: #Giga
Tera: #Tera
Peta: #Peta
Exa: #Exa
}
#Nano: #Scale & -9
#Micro: #Scale & -6
#Milli: #Scale & -3
#Kilo: #Scale & 3
#Mega: #Scale & 6
#Giga: #Scale & 9
#Tera: #Scale & 12
#Peta: #Scale & 15
#Exa: #Scale & 18
// infDecAmount implements common operations over an inf.Dec that are specific to the quantity
// representation.
_#infDecAmount: string

View File

@@ -0,0 +1,13 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/apimachinery/pkg/api/resource
package resource
// maxInt64Factors is the highest value that will be checked when removing factors of 10 from an int64.
// It is also the maximum decimal digits that can be represented with an int64.
_#maxInt64Factors: 18
_#mostNegative: -9223372036854775808
_#mostPositive: 9223372036854775807

View File

@@ -0,0 +1,107 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/apimachinery/pkg/api/resource
package resource
// Quantity is a fixed-point representation of a number.
// It provides convenient marshaling/unmarshaling in JSON and YAML,
// in addition to String() and AsInt64() accessors.
//
// The serialization format is:
//
// ```
// <quantity> ::= <signedNumber><suffix>
//
// (Note that <suffix> may be empty, from the "" case in <decimalSI>.)
//
// <digit> ::= 0 | 1 | ... | 9
// <digits> ::= <digit> | <digit><digits>
// <number> ::= <digits> | <digits>.<digits> | <digits>. | .<digits>
// <sign> ::= "+" | "-"
// <signedNumber> ::= <number> | <sign><number>
// <suffix> ::= <binarySI> | <decimalExponent> | <decimalSI>
// <binarySI> ::= Ki | Mi | Gi | Ti | Pi | Ei
//
// (International System of units; See: http://physics.nist.gov/cuu/Units/binary.html)
//
// <decimalSI> ::= m | "" | k | M | G | T | P | E
//
// (Note that 1024 = 1Ki but 1000 = 1k; I didn't choose the capitalization.)
//
// <decimalExponent> ::= "e" <signedNumber> | "E" <signedNumber>
// ```
//
// No matter which of the three exponent forms is used, no quantity may represent
// a number greater than 2^63-1 in magnitude, nor may it have more than 3 decimal
// places. Numbers larger or more precise will be capped or rounded up.
// (E.g.: 0.1m will rounded up to 1m.)
// This may be extended in the future if we require larger or smaller quantities.
//
// When a Quantity is parsed from a string, it will remember the type of suffix
// it had, and will use the same type again when it is serialized.
//
// Before serializing, Quantity will be put in "canonical form".
// This means that Exponent/suffix will be adjusted up or down (with a
// corresponding increase or decrease in Mantissa) such that:
//
// - No precision is lost
// - No fractional digits will be emitted
// - The exponent (or suffix) is as large as possible.
//
// The sign will be omitted unless the number is negative.
//
// Examples:
//
// - 1.5 will be serialized as "1500m"
// - 1.5Gi will be serialized as "1536Mi"
//
// Note that the quantity will NEVER be internally represented by a
// floating point number. That is the whole point of this exercise.
//
// Non-canonical values will still parse as long as they are well formed,
// but will be re-emitted in their canonical form. (So always use canonical
// form, or don't diff.)
//
// This format is intended to make it difficult to use these numbers without
// writing some sort of special handling code in the hopes that that will
// cause implementors to also use a fixed point implementation.
//
// +protobuf=true
// +protobuf.embed=string
// +protobuf.options.marshal=false
// +protobuf.options.(gogoproto.goproto_stringer)=false
// +k8s:deepcopy-gen=true
// +k8s:openapi-gen=true
#Quantity: _
// CanonicalValue allows a quantity amount to be converted to a string.
#CanonicalValue: _
// Format lists the three possible formattings of a quantity.
#Format: string // #enumFormat
#enumFormat:
#DecimalExponent |
#BinarySI |
#DecimalSI
#DecimalExponent: #Format & "DecimalExponent"
#BinarySI: #Format & "BinarySI"
#DecimalSI: #Format & "DecimalSI"
// splitREString is used to separate a number from its suffix; as such,
// this is overly permissive, but that's OK-- it will be checked later.
_#splitREString: "^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$"
_#int64QuantityExpectedBytes: 18
// QuantityValue makes it possible to use a Quantity as value for a command
// line parameter.
//
// +protobuf=true
// +protobuf.embed=string
// +protobuf.options.marshal=false
// +protobuf.options.(gogoproto.goproto_stringer)=false
// +k8s:deepcopy-gen=true
#QuantityValue: _

View File

@@ -0,0 +1,10 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/apimachinery/pkg/api/resource
package resource
_#suffix: string
// suffixer can interpret and construct suffixes.
_#suffixer: _

View File

@@ -0,0 +1,10 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/apimachinery/pkg/apis/meta/v1
package v1
// Duration is a wrapper around time.Duration which supports correct
// marshaling to YAML and JSON. In particular, it marshals into strings, which
// can be used as map keys in json.
#Duration: _

View File

@@ -0,0 +1,48 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/apimachinery/pkg/apis/meta/v1
package v1
// GroupResource specifies a Group and a Resource, but does not force a version. This is useful for identifying
// concepts during lookup stages without having partially valid types
//
// +protobuf.options.(gogoproto.goproto_stringer)=false
#GroupResource: {
group: string @go(Group) @protobuf(1,bytes,opt)
resource: string @go(Resource) @protobuf(2,bytes,opt)
}
// GroupVersionResource unambiguously identifies a resource. It doesn't anonymously include GroupVersion
// to avoid automatic coercion. It doesn't use a GroupVersion to avoid custom marshalling
//
// +protobuf.options.(gogoproto.goproto_stringer)=false
#GroupVersionResource: {
group: string @go(Group) @protobuf(1,bytes,opt)
version: string @go(Version) @protobuf(2,bytes,opt)
resource: string @go(Resource) @protobuf(3,bytes,opt)
}
// GroupKind specifies a Group and a Kind, but does not force a version. This is useful for identifying
// concepts during lookup stages without having partially valid types
//
// +protobuf.options.(gogoproto.goproto_stringer)=false
#GroupKind: {
group: string @go(Group) @protobuf(1,bytes,opt)
kind: string @go(Kind) @protobuf(2,bytes,opt)
}
// GroupVersionKind unambiguously identifies a kind. It doesn't anonymously include GroupVersion
// to avoid automatic coercion. It doesn't use a GroupVersion to avoid custom marshalling
//
// +protobuf.options.(gogoproto.goproto_stringer)=false
#GroupVersionKind: {
group: string @go(Group) @protobuf(1,bytes,opt)
version: string @go(Version) @protobuf(2,bytes,opt)
kind: string @go(Kind) @protobuf(3,bytes,opt)
}
// GroupVersion contains the "group" and the "version", which uniquely identifies the API.
//
// +protobuf.options.(gogoproto.goproto_stringer)=false
#GroupVersion: _

View File

@@ -0,0 +1,33 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/apimachinery/pkg/apis/meta/v1
package v1
// TODO: move this, Object, List, and Type to a different package
#ObjectMetaAccessor: _
// Object lets you work with object metadata from any of the versioned or
// internal API objects. Attempting to set or retrieve a field on an object that does
// not support that field (Name, UID, Namespace on lists) will be a no-op and return
// a default value.
#Object: _
// ListMetaAccessor retrieves the list interface from an object
#ListMetaAccessor: _
// Common lets you work with core metadata from any of the versioned or
// internal API objects. Attempting to set or retrieve a field on an object that does
// not support that field will be a no-op and return a default value.
// TODO: move this, and TypeMeta and ListMeta, to a different package
#Common: _
// ListInterface lets you work with list metadata from any of the versioned or
// internal API objects. Attempting to set or retrieve a field on an object that does
// not support that field will be a no-op and return a default value.
// TODO: move this, and TypeMeta and ListMeta, to a different package
#ListInterface: _
// Type exposes the type and APIVersion of versioned or internal API objects.
// TODO: move this, and TypeMeta and ListMeta, to a different package
#Type: _

View File

@@ -0,0 +1,14 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/apimachinery/pkg/apis/meta/v1
package v1
#RFC3339Micro: "2006-01-02T15:04:05.000000Z07:00"
// MicroTime is version of Time with microsecond level precision.
//
// +protobuf.options.marshal=false
// +protobuf.as=Timestamp
// +protobuf.options.(gogoproto.goproto_stringer)=false
#MicroTime: _

View File

@@ -0,0 +1,9 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/apimachinery/pkg/apis/meta/v1
package v1
#GroupName: "meta.k8s.io"
#WatchEventKind: "WatchEvent"

View File

@@ -0,0 +1,14 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/apimachinery/pkg/apis/meta/v1
package v1
// Time is a wrapper around time.Time which supports correct
// marshaling to YAML and JSON. Wrappers are provided for many
// of the factory methods that the time package offers.
//
// +protobuf.options.marshal=false
// +protobuf.as=Timestamp
// +protobuf.options.(gogoproto.goproto_stringer)=false
#Time: _

View File

@@ -0,0 +1,21 @@
// Code generated by cue get go. DO NOT EDIT.
//cue:generate cue get go k8s.io/apimachinery/pkg/apis/meta/v1
package v1
// Timestamp is a struct that is equivalent to Time, but intended for
// protobuf marshalling/unmarshalling. It is generated into a serialization
// that matches Time. Do not use in Go structs.
#Timestamp: {
// Represents seconds of UTC time since Unix epoch
// 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
// 9999-12-31T23:59:59Z inclusive.
seconds: int64 @go(Seconds) @protobuf(1,varint,opt)
// Non-negative fractions of a second at nanosecond resolution. Negative
// second values with fractions must still have non-negative nanos values
// that count forward in time. Must be from 0 to 999,999,999
// inclusive. This field may be limited in precision depending on context.
nanos: int32 @go(Nanos) @protobuf(2,varint,opt)
}

Some files were not shown because too many files have changed in this diff Show More