mirror of
https://github.com/holos-run/holos.git
synced 2026-03-19 08:44:58 +00:00
Compare commits
101 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bac7aec0ba | ||
|
|
42f916af41 | ||
|
|
47a5e237e0 | ||
|
|
1279e2351a | ||
|
|
adb8177026 | ||
|
|
4e8fa5abda | ||
|
|
6894f45b6c | ||
|
|
89d25be837 | ||
|
|
5b33e48552 | ||
|
|
79e8ab639a | ||
|
|
a0cc673736 | ||
|
|
d06ecfadc8 | ||
|
|
64a117b0c3 | ||
|
|
cf006be9cf | ||
|
|
45ad3d8e63 | ||
|
|
441c968c4f | ||
|
|
99f2763fdf | ||
|
|
1312395a11 | ||
|
|
615f147bcb | ||
|
|
d0ad3bfc69 | ||
|
|
fe58a33747 | ||
|
|
26e537e768 | ||
|
|
ad70a6c4fe | ||
|
|
22a04da6bb | ||
|
|
dc97fe0ff0 | ||
|
|
9ca97c6e01 | ||
|
|
924653e240 | ||
|
|
59d48f8599 | ||
|
|
90f8eab816 | ||
|
|
9ae45e260d | ||
|
|
aee15f95e2 | ||
|
|
1c540ac375 | ||
|
|
5b0e883ac9 | ||
|
|
9a2519af71 | ||
|
|
9b9ff601c0 | ||
|
|
2f798296dc | ||
|
|
2b2ff63cad | ||
|
|
3b135c09f3 | ||
|
|
28813eba5b | ||
|
|
02ff765f54 | ||
|
|
fe8a806132 | ||
|
|
6626d58301 | ||
|
|
cb0911e890 | ||
|
|
3745a68dc5 | ||
|
|
fd64830476 | ||
|
|
1ee0fa9c1f | ||
|
|
8fab325b0a | ||
|
|
858ffad913 | ||
|
|
62735b99e7 | ||
|
|
29ab9c6300 | ||
|
|
debc01c7de | ||
|
|
c07f35ecd6 | ||
|
|
c8f528700c | ||
|
|
896248c237 | ||
|
|
74a181db21 | ||
|
|
ba10113342 | ||
|
|
eb0207c92e | ||
|
|
0fbcee8119 | ||
|
|
ce8bc798f6 | ||
|
|
996195d651 | ||
|
|
f00b29d3a3 | ||
|
|
a6756ecf11 | ||
|
|
ef7ec30037 | ||
|
|
1642787825 | ||
|
|
f83781480f | ||
|
|
9b70205855 | ||
|
|
0e4bf3c144 | ||
|
|
1241c74b41 | ||
|
|
44fea098de | ||
|
|
52286efa25 | ||
|
|
a1b2179442 | ||
|
|
cffc430738 | ||
|
|
d76454272b | ||
|
|
9d1e77c00f | ||
|
|
2050abdc6c | ||
|
|
3ea013c503 | ||
|
|
309db96138 | ||
|
|
283b4be71c | ||
|
|
ab9bca0750 | ||
|
|
ac2be67c3c | ||
|
|
6ffafb8cca | ||
|
|
590e6b556c | ||
|
|
5dc5c6fbdf | ||
|
|
cd8c9f2c32 | ||
|
|
3490941d4c | ||
|
|
3f201df0c2 | ||
|
|
4c22d515bd | ||
|
|
ec0ef1c4b3 | ||
|
|
1e51e2d49a | ||
|
|
5186499b90 | ||
|
|
fc275e4164 | ||
|
|
9fa466f7cf | ||
|
|
efd6f256a5 | ||
|
|
f7f9d6b5f0 | ||
|
|
0526062ab2 | ||
|
|
a1ededa722 | ||
|
|
9b09a02912 | ||
|
|
657a5e82a5 | ||
|
|
1eece02254 | ||
|
|
c866b47dcb | ||
|
|
ff52ec750b |
1
.github/workflows/lint.yaml
vendored
1
.github/workflows/lint.yaml
vendored
@@ -46,3 +46,4 @@ jobs:
|
||||
uses: golangci/golangci-lint-action@v4
|
||||
with:
|
||||
version: latest
|
||||
skip-pkg-cache: true
|
||||
|
||||
6
Makefile
6
Makefile
@@ -68,7 +68,7 @@ generate: ## Generate code.
|
||||
go generate ./...
|
||||
|
||||
.PHONY: build
|
||||
build: generate ## Build holos executable.
|
||||
build: generate frontend ## Build holos executable.
|
||||
@echo "building ${BIN_NAME} ${VERSION}"
|
||||
@echo "GOPATH=${GOPATH}"
|
||||
go build -trimpath -o bin/$(BIN_NAME) -ldflags $(LD_FLAGS) $(REPO_PATH)/cmd/$(BIN_NAME)
|
||||
@@ -87,6 +87,8 @@ test: ## Run tests.
|
||||
|
||||
.PHONY: lint
|
||||
lint: ## Run linters.
|
||||
buf lint
|
||||
cd internal/frontend/holos && ng lint
|
||||
golangci-lint run
|
||||
|
||||
.PHONY: coverage
|
||||
@@ -126,8 +128,8 @@ frontend-deps: ## Setup npm and vite
|
||||
|
||||
.PHONY: frontend
|
||||
frontend: buf
|
||||
cd internal/frontend/holos && rm -rf dist
|
||||
mkdir -p internal/frontend/holos/dist
|
||||
cd internal/frontend/holos/dist && rm -rf app
|
||||
cd internal/frontend/holos && ng build
|
||||
touch internal/frontend/frontend.go
|
||||
|
||||
|
||||
8
Tiltfile
8
Tiltfile
@@ -99,6 +99,7 @@ docker_build_with_restart(
|
||||
'--listen-port={}'.format(listen_port),
|
||||
'--oidc-issuer=https://login.ois.run',
|
||||
'--oidc-audience=262096764402729854@holos_platform',
|
||||
'--log-level=debug',
|
||||
'--metrics-port={}'.format(metrics_port),
|
||||
],
|
||||
dockerfile='./hack/tilt/Dockerfile',
|
||||
@@ -190,7 +191,7 @@ k8s_resource(
|
||||
],
|
||||
resource_deps=[compile_id],
|
||||
links=[
|
||||
link('https://{}.holos.dev.k2.ois.run/app/'.format(developer), "Holos Web UI")
|
||||
link('https://{}.app.dev.k2.holos.run/ui/'.format(developer), "Holos Web UI")
|
||||
],
|
||||
)
|
||||
|
||||
@@ -200,11 +201,6 @@ k8s_resource(
|
||||
new_name=auth_id,
|
||||
objects=[
|
||||
'{}:virtualservice'.format(holos_server),
|
||||
'{}-allow-groups:authorizationpolicy'.format(holos_server),
|
||||
'{}-allow-nothing:authorizationpolicy'.format(holos_server),
|
||||
'{}-allow-well-known-paths:authorizationpolicy'.format(holos_server),
|
||||
'{}-auth:authorizationpolicy'.format(holos_server),
|
||||
'{}:requestauthentication'.format(holos_server),
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -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 {
|
||||
@@ -38,3 +39,14 @@ func (bp *BuildPlan) Validate() error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (bp *BuildPlan) ResultCapacity() (count int) {
|
||||
if bp == nil {
|
||||
return 0
|
||||
}
|
||||
count = len(bp.Spec.Components.HelmChartList) +
|
||||
len(bp.Spec.Components.KubernetesObjectsList) +
|
||||
len(bp.Spec.Components.KustomizeBuildList) +
|
||||
len(bp.Spec.Components.Resources)
|
||||
return count
|
||||
}
|
||||
|
||||
9
api/v1alpha1/platform.go
Normal file
9
api/v1alpha1/platform.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package v1alpha1
|
||||
|
||||
// Platform represents a platform to manage. A Platform resource tells holos
|
||||
// which components to build. The primary use case is to specify the cluster
|
||||
// names, cluster types, and holos components to build.
|
||||
type Platform struct {
|
||||
TypeMeta `json:",inline" yaml:",inline"`
|
||||
Metadata ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
|
||||
}
|
||||
@@ -19,6 +19,14 @@ type Result struct {
|
||||
accumulatedOutput string
|
||||
}
|
||||
|
||||
// Continue returns true if Skip is true indicating the result is to be skipped over.
|
||||
func (r *Result) Continue() bool {
|
||||
if r == nil {
|
||||
return false
|
||||
}
|
||||
return r.Skip
|
||||
}
|
||||
|
||||
func (r *Result) Name() string {
|
||||
return r.Metadata.Name
|
||||
}
|
||||
@@ -32,6 +40,11 @@ func (r *Result) KustomizationFilename(writeTo string, cluster string) string {
|
||||
return filepath.Join(writeTo, "clusters", cluster, "holos", "components", r.Metadata.Name+"-kustomization.gen.yaml")
|
||||
}
|
||||
|
||||
// KustomizationContent returns the kustomization file contents to write.
|
||||
func (r *Result) KustomizationContent() string {
|
||||
return r.KsContent
|
||||
}
|
||||
|
||||
// AccumulatedOutput returns the accumulated rendered output.
|
||||
func (r *Result) AccumulatedOutput() string {
|
||||
return r.accumulatedOutput
|
||||
|
||||
@@ -8,3 +8,13 @@ type TypeMeta struct {
|
||||
func (tm *TypeMeta) GetKind() string {
|
||||
return tm.Kind
|
||||
}
|
||||
|
||||
func (tm *TypeMeta) GetAPIVersion() string {
|
||||
return tm.Kind
|
||||
}
|
||||
|
||||
// Discriminator is an interface to discriminate the kind api object.
|
||||
type Discriminator interface {
|
||||
GetKind() string
|
||||
GetAPIVersion() string
|
||||
}
|
||||
|
||||
@@ -11,14 +11,10 @@ plugins:
|
||||
out: service/gen
|
||||
opt: paths=source_relative
|
||||
- plugin: es
|
||||
out: internal/frontend/holos/gen
|
||||
out: internal/frontend/holos/src/app/gen
|
||||
opt:
|
||||
- target=ts
|
||||
- plugin: connect-es
|
||||
out: internal/frontend/holos/gen
|
||||
opt:
|
||||
- target=ts
|
||||
- plugin: connect-query
|
||||
out: internal/frontend/holos/gen
|
||||
out: internal/frontend/holos/src/app/gen
|
||||
opt:
|
||||
- target=ts
|
||||
|
||||
@@ -2,7 +2,10 @@ package holos
|
||||
|
||||
import ap "security.istio.io/authorizationpolicy/v1"
|
||||
|
||||
// #AuthPolicyRules represents AuthorizationPolicy rules for hosts that need specialized treatment. Entries in this struct are exclused from the blank ingressauth AuthorizationPolicy governing the ingressgateway and included in a spcialized policy
|
||||
// #AuthPolicyRules represents AuthorizationPolicy rules for hosts that need
|
||||
// specialized treatment. Entries in this struct are excluded from
|
||||
// AuthorizationPolicy/authproxy-custom in the istio-ingress namespace. Entries
|
||||
// are added to their own AuthorizationPolicy.
|
||||
#AuthPolicyRules: {
|
||||
// AuthProxySpec represents the identity provider configuration
|
||||
AuthProxySpec: #AuthProxySpec & #Platform.authproxy
|
||||
@@ -14,6 +17,9 @@ import ap "security.istio.io/authorizationpolicy/v1"
|
||||
name: Name
|
||||
// slug is the resource name prefix
|
||||
slug: string
|
||||
// NoAuthorizationPolicy disables an AuthorizationPolicy for the host
|
||||
NoAuthorizationPolicy: true | *false
|
||||
|
||||
// Refer to https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule
|
||||
spec: ap.#AuthorizationPolicySpec & {
|
||||
action: "CUSTOM"
|
||||
@@ -25,11 +31,13 @@ import ap "security.istio.io/authorizationpolicy/v1"
|
||||
|
||||
objects: #APIObjects & {
|
||||
for Host in hosts {
|
||||
apiObjects: {
|
||||
AuthorizationPolicy: "\(Host.slug)-custom": {
|
||||
metadata: namespace: "istio-ingress"
|
||||
metadata: name: "\(Host.slug)-custom"
|
||||
spec: Host.spec
|
||||
if Host.NoAuthorizationPolicy == false {
|
||||
apiObjects: {
|
||||
AuthorizationPolicy: "\(Host.slug)-custom": {
|
||||
metadata: namespace: "istio-ingress"
|
||||
metadata: name: "\(Host.slug)-custom"
|
||||
spec: Host.spec
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,3 +4,8 @@ package v1
|
||||
apiVersion: "apps/v1"
|
||||
kind: "Deployment"
|
||||
}
|
||||
|
||||
#StatefulSet: {
|
||||
apiVersion: "apps/v1"
|
||||
kind: "StatefulSet"
|
||||
}
|
||||
|
||||
@@ -18,8 +18,10 @@ import "encoding/yaml"
|
||||
Issuer?: [Name=_]: #Issuer & {metadata: name: Name}
|
||||
Gateway?: [Name=_]: #Gateway & {metadata: name: Name}
|
||||
ConfigMap?: [Name=_]: #ConfigMap & {metadata: name: Name}
|
||||
ServiceAccount?: [Name=_]: #ServiceAccount & {metadata: name: Name}
|
||||
|
||||
Deployment?: [_]: #Deployment
|
||||
StatefulSet?: [_]: #StatefulSet
|
||||
RequestAuthentication?: [_]: #RequestAuthentication
|
||||
AuthorizationPolicy?: [_]: #AuthorizationPolicy
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package holos
|
||||
|
||||
let Namespace = "jeff-holos"
|
||||
let Broker = "choria-broker"
|
||||
|
||||
spec: components: KubernetesObjectsList: [
|
||||
#KubernetesObjects & {
|
||||
_dependsOn: "prod-platform-issuer": _
|
||||
|
||||
metadata: name: "\(Namespace)-\(Broker)"
|
||||
apiObjectMap: OBJECTS.apiObjectMap
|
||||
},
|
||||
]
|
||||
|
||||
let SelectorLabels = {
|
||||
"app.kubernetes.io/instance": Broker
|
||||
"app.kubernetes.io/name": Broker
|
||||
}
|
||||
|
||||
let OBJECTS = #APIObjects & {
|
||||
apiObjects: {
|
||||
Certificate: "\(Broker)-tls": #Certificate & {
|
||||
metadata: {
|
||||
name: "\(Broker)-tls"
|
||||
namespace: Namespace
|
||||
labels: SelectorLabels
|
||||
}
|
||||
spec: {
|
||||
commonName: "\(Broker).\(Namespace).svc.cluster.local"
|
||||
dnsNames: [
|
||||
Broker,
|
||||
"\(Broker).\(Namespace).svc",
|
||||
"\(Broker).\(Namespace).svc.cluster.local",
|
||||
"*.\(Broker)",
|
||||
"*.\(Broker).\(Namespace).svc",
|
||||
"*.\(Broker).\(Namespace).svc.cluster.local",
|
||||
]
|
||||
issuerRef: kind: "ClusterIssuer"
|
||||
issuerRef: name: "platform-issuer"
|
||||
secretName: metadata.name
|
||||
usages: ["signing", "key encipherment", "server auth", "client auth"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package holos
|
||||
|
||||
let Namespace = "jeff-holos"
|
||||
let Provisioner = "choria-provisioner"
|
||||
|
||||
spec: components: KubernetesObjectsList: [
|
||||
#KubernetesObjects & {
|
||||
_dependsOn: "prod-platform-issuer": _
|
||||
|
||||
metadata: name: "\(Namespace)-\(Provisioner)"
|
||||
apiObjectMap: OBJECTS.apiObjectMap
|
||||
},
|
||||
]
|
||||
|
||||
let SelectorLabels = {
|
||||
"app.kubernetes.io/instance": Provisioner
|
||||
"app.kubernetes.io/name": Provisioner
|
||||
}
|
||||
|
||||
let OBJECTS = #APIObjects & {
|
||||
apiObjects: {
|
||||
Certificate: "\(Provisioner)-tls": #Certificate & {
|
||||
metadata: {
|
||||
name: "\(Provisioner)-tls"
|
||||
namespace: Namespace
|
||||
labels: SelectorLabels
|
||||
}
|
||||
spec: {
|
||||
commonName: "\(Provisioner).\(Namespace).svc.cluster.local"
|
||||
dnsNames: [
|
||||
Provisioner,
|
||||
"\(Provisioner).\(Namespace).svc",
|
||||
"\(Provisioner).\(Namespace).svc.cluster.local",
|
||||
"*.\(Provisioner)",
|
||||
"*.\(Provisioner).\(Namespace).svc",
|
||||
"*.\(Provisioner).\(Namespace).svc.cluster.local",
|
||||
]
|
||||
issuerRef: kind: "ClusterIssuer"
|
||||
issuerRef: name: "platform-issuer"
|
||||
secretName: metadata.name
|
||||
usages: ["signing", "key encipherment", "server auth", "client auth"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
package holos
|
||||
|
||||
let Namespace = "jeff-holos"
|
||||
let Broker = "choria-broker"
|
||||
|
||||
spec: components: KubernetesObjectsList: [
|
||||
#KubernetesObjects & {
|
||||
_dependsOn: "prod-secrets-stores": _
|
||||
|
||||
metadata: name: "\(Namespace)-\(Broker)"
|
||||
apiObjectMap: OBJECTS.apiObjectMap
|
||||
},
|
||||
]
|
||||
|
||||
let SelectorLabels = {
|
||||
"app.kubernetes.io/part-of": "choria"
|
||||
"app.kubernetes.io/name": Broker
|
||||
}
|
||||
|
||||
let Metadata = {
|
||||
name: Broker
|
||||
namespace: Namespace
|
||||
labels: SelectorLabels
|
||||
}
|
||||
|
||||
let OBJECTS = #APIObjects & {
|
||||
apiObjects: {
|
||||
ExternalSecret: "\(Broker)-tls": #ExternalSecret & {
|
||||
metadata: name: "\(Broker)-tls"
|
||||
metadata: namespace: Namespace
|
||||
}
|
||||
ExternalSecret: "\(Broker)": #ExternalSecret & {
|
||||
metadata: name: Broker
|
||||
metadata: namespace: Namespace
|
||||
}
|
||||
StatefulSet: "\(Broker)": {
|
||||
metadata: Metadata
|
||||
spec: {
|
||||
selector: matchLabels: SelectorLabels
|
||||
serviceName: Broker
|
||||
template: metadata: labels: SelectorLabels
|
||||
template: spec: {
|
||||
containers: [
|
||||
{
|
||||
name: Broker
|
||||
command: ["choria", "broker", "run", "--config", "/etc/choria/broker.conf"]
|
||||
image: "registry.choria.io/choria/choria:0.28.0"
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
ports: [
|
||||
{
|
||||
containerPort: 4222
|
||||
name: "tcp-nats"
|
||||
protocol: "TCP"
|
||||
},
|
||||
{
|
||||
containerPort: 4333
|
||||
name: "https-wss"
|
||||
protocol: "TCP"
|
||||
},
|
||||
{
|
||||
containerPort: 5222
|
||||
name: "tcp-cluster"
|
||||
protocol: "TCP"
|
||||
},
|
||||
{
|
||||
containerPort: 8222
|
||||
name: "http-stats"
|
||||
protocol: "TCP"
|
||||
},
|
||||
]
|
||||
livenessProbe: httpGet: {
|
||||
path: "/healthz"
|
||||
port: "http-stats"
|
||||
}
|
||||
readinessProbe: livenessProbe
|
||||
resources: {}
|
||||
securityContext: {}
|
||||
volumeMounts: [
|
||||
{
|
||||
mountPath: "/etc/choria"
|
||||
name: Broker
|
||||
},
|
||||
{
|
||||
mountPath: "/etc/choria-tls"
|
||||
name: "\(Broker)-tls"
|
||||
},
|
||||
]
|
||||
},
|
||||
]
|
||||
securityContext: {}
|
||||
serviceAccountName: Broker
|
||||
volumes: [
|
||||
{
|
||||
name: Broker
|
||||
secret: secretName: Broker
|
||||
},
|
||||
{
|
||||
name: "\(Broker)-tls"
|
||||
secret: secretName: "\(Broker)-tls"
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
ServiceAccount: "\(Broker)": #ServiceAccount & {
|
||||
metadata: Metadata
|
||||
}
|
||||
Service: "\(Broker)": #Service & {
|
||||
metadata: Metadata
|
||||
spec: {
|
||||
type: "ClusterIP"
|
||||
clusterIP: "None"
|
||||
selector: SelectorLabels
|
||||
ports: [
|
||||
{
|
||||
name: "tcp-nats"
|
||||
appProtocol: "tcp"
|
||||
port: 4222
|
||||
protocol: "TCP"
|
||||
targetPort: "tcp-nats"
|
||||
},
|
||||
{
|
||||
name: "tcp-cluster"
|
||||
appProtocol: "tcp"
|
||||
port: 5222
|
||||
protocol: "TCP"
|
||||
targetPort: "tcp-cluster"
|
||||
},
|
||||
{
|
||||
name: "https-wss"
|
||||
appProtocol: "https"
|
||||
port: 443
|
||||
protocol: "TCP"
|
||||
targetPort: "https-wss"
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
DestinationRule: "\(Broker)-wss": #DestinationRule & {
|
||||
_decriptions: "Configures Istio to connect to Choria using a cert issued by the Platform Issuer"
|
||||
metadata: Metadata
|
||||
spec: host: "\(Broker).\(Namespace).svc.cluster.local"
|
||||
spec: trafficPolicy: tls: {
|
||||
credentialName: "istio-ingress-mtls-cert"
|
||||
mode: "MUTUAL"
|
||||
// subjectAltNames is important, otherwise istio will fail to verify the
|
||||
// choria broker upstream server. make sure this matches a value
|
||||
// present in the choria broker's cert.
|
||||
//
|
||||
// kubectl get secret choria-broker-tls -o json | jq --exit-status
|
||||
// '.data | map_values(@base64d)' | jq .\"tls.crt\" -r | openssl x509
|
||||
// -text -noout -in -
|
||||
subjectAltNames: [spec.host]
|
||||
}
|
||||
}
|
||||
VirtualService: "\(Broker)-wss": #VirtualService & {
|
||||
metadata: name: "\(Broker)-wss"
|
||||
metadata: namespace: Namespace
|
||||
spec: {
|
||||
gateways: ["istio-ingress/default"]
|
||||
hosts: ["jeff.provision.dev.\(#ClusterName).holos.run"]
|
||||
http: [
|
||||
{
|
||||
route: [
|
||||
{
|
||||
destination: {
|
||||
host: "\(Broker).\(Namespace).svc.cluster.local"
|
||||
port: "number": 443
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
FROM registry.choria.io/choria/provisioner:latest
|
||||
|
||||
RUN curl -Lo nsc.zip https://github.com/nats-io/nsc/releases/download/v2.8.6/nsc-linux-amd64.zip &&\
|
||||
unzip nsc.zip && \
|
||||
mv nsc /usr/local/bin/nsc && \
|
||||
chmod 755 /usr/local/bin/nsc && \
|
||||
rm -f nsc.zip
|
||||
|
||||
# TODO: Add jwt executable
|
||||
# TODO: Add helper executable
|
||||
|
||||
USER choria
|
||||
ENV USER=choria
|
||||
|
||||
ENTRYPOINT ["/usr/sbin/choria-provisioner"]
|
||||
|
||||
# These two files are expected to be in the provisioner secret.
|
||||
CMD ["--config=/etc/provisioner/provisioner.yaml", "--choria-config=/etc/provisioner/choria.cfg"]
|
||||
@@ -0,0 +1,82 @@
|
||||
package holos
|
||||
|
||||
let Namespace = "jeff-holos"
|
||||
let Provisioner = "choria-provisioner"
|
||||
|
||||
spec: components: KubernetesObjectsList: [
|
||||
#KubernetesObjects & {
|
||||
_dependsOn: "prod-secrets-stores": _
|
||||
|
||||
metadata: name: "\(Namespace)-\(Provisioner)"
|
||||
apiObjectMap: OBJECTS.apiObjectMap
|
||||
},
|
||||
]
|
||||
|
||||
let SelectorLabels = {
|
||||
"app.kubernetes.io/instance": Provisioner
|
||||
"app.kubernetes.io/name": Provisioner
|
||||
}
|
||||
|
||||
let Metadata = {
|
||||
name: Provisioner
|
||||
namespace: Namespace
|
||||
labels: SelectorLabels
|
||||
}
|
||||
|
||||
let OBJECTS = #APIObjects & {
|
||||
apiObjects: {
|
||||
ExternalSecret: "\(Provisioner)-tls": #ExternalSecret & {
|
||||
metadata: name: "\(Provisioner)-tls"
|
||||
metadata: namespace: Namespace
|
||||
}
|
||||
ExternalSecret: "\(Provisioner)": #ExternalSecret & {
|
||||
metadata: name: Provisioner
|
||||
metadata: namespace: Namespace
|
||||
}
|
||||
ServiceAccount: "\(Provisioner)": #ServiceAccount & {
|
||||
metadata: Metadata
|
||||
}
|
||||
Deployment: "\(Provisioner)": {
|
||||
metadata: Metadata
|
||||
spec: {
|
||||
selector: matchLabels: SelectorLabels
|
||||
template: metadata: labels: SelectorLabels
|
||||
template: spec: {
|
||||
containers: [
|
||||
{
|
||||
name: Provisioner
|
||||
command: ["bash", "/etc/provisioner/entrypoint"]
|
||||
// skopeo inspect docker://registry.choria.io/choria/provisioner | jq .RepoTags
|
||||
image: "registry.choria.io/choria/provisioner:0.15.1"
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
resources: {}
|
||||
securityContext: {}
|
||||
volumeMounts: [
|
||||
{
|
||||
mountPath: "/etc/provisioner"
|
||||
name: Provisioner
|
||||
},
|
||||
{
|
||||
mountPath: "/etc/provisioner-tls"
|
||||
name: "\(Provisioner)-tls"
|
||||
},
|
||||
]
|
||||
},
|
||||
]
|
||||
securityContext: {}
|
||||
serviceAccountName: Provisioner
|
||||
volumes: [
|
||||
{
|
||||
name: Provisioner
|
||||
secret: secretName: name
|
||||
},
|
||||
{
|
||||
name: "\(Provisioner)-tls"
|
||||
secret: secretName: name
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
# Machine Room Provisioner
|
||||
|
||||
This sub-tree contains Holos Components to manage a [Choria Provisioner][1]
|
||||
system for the use case of provisioning `holos controller` instances. These
|
||||
instances are implementations of Machine Room which are in turn implementations
|
||||
of Choria Server, hence why we use Choria Provisioner.
|
||||
|
||||
[1]: https://choria-io.github.io/provisioner/
|
||||
@@ -0,0 +1,62 @@
|
||||
package holos
|
||||
|
||||
// for Project in _Projects {
|
||||
// spec: components: resources: (#ProjectTemplate & {project: Project}).workload.resources
|
||||
// }
|
||||
|
||||
let Namespace = "jeff-holos"
|
||||
|
||||
#Kustomization: spec: targetNamespace: Namespace
|
||||
|
||||
spec: components: HelmChartList: [
|
||||
#HelmChart & {
|
||||
metadata: name: "jeff-holos-nats"
|
||||
namespace: Namespace
|
||||
_dependsOn: "prod-secrets-stores": _
|
||||
chart: {
|
||||
name: "nats"
|
||||
version: "1.1.10"
|
||||
repository: NatsRepository
|
||||
}
|
||||
_values: #NatsValues & {
|
||||
config: {
|
||||
// https://github.com/nats-io/k8s/tree/main/helm/charts/nats#operator-mode-with-nats-resolver
|
||||
resolver: enabled: true
|
||||
resolver: merge: {
|
||||
type: "full"
|
||||
interval: "2m"
|
||||
timeout: "1.9s"
|
||||
}
|
||||
merge: {
|
||||
operator: "eyJ0eXAiOiJKV1QiLCJhbGciOiJlZDI1NTE5LW5rZXkifQ.eyJqdGkiOiJUSElBTDM2NUtOS0lVVVJDMzNLNFJGQkJVRlFBSTRLS0NQTDJGVDZYVjdNQVhWU1dFNElRIiwiaWF0IjoxNzEzMjIxMzE1LCJpc3MiOiJPREtQM0RZTzc3T1NBRU5IU0FFR0s3WUNFTFBYT1FFWUI3RVFSTVBLWlBNQUxINE5BRUVLSjZDRyIsIm5hbWUiOiJIb2xvcyIsInN1YiI6Ik9ES1AzRFlPNzdPU0FFTkhTQUVHSzdZQ0VMUFhPUUVZQjdFUVJNUEtaUE1BTEg0TkFFRUtKNkNHIiwibmF0cyI6eyJ0eXBlIjoib3BlcmF0b3IiLCJ2ZXJzaW9uIjoyfX0.dQURTb-zIQMc-OYd9328oY887AEnvog6gOXY1-VCsDG3L89nq5x_ks4ME7dJ4Pn-Pvm2eyBi1Jx6ubgkthHgCQ"
|
||||
system_account: "ADIQCYK4K3OKTPODGCLI4PDQ6XBO52MISBPTAIDESEJMLZCMNULDKCCY"
|
||||
resolver_preload: {
|
||||
// NOTEL: Make sure you do not include the trailing , in the SYS_ACCOUNT_JWT
|
||||
"ADIQCYK4K3OKTPODGCLI4PDQ6XBO52MISBPTAIDESEJMLZCMNULDKCCY": "eyJ0eXAiOiJKV1QiLCJhbGciOiJlZDI1NTE5LW5rZXkifQ.eyJqdGkiOiI2SEVMNlhKSUdWUElMNFBURVI1MkUzTkFITjZLWkVUUUdFTlFVS0JWRzNUWlNLRzVLT09RIiwiaWF0IjoxNzEzMjIxMzE1LCJpc3MiOiJPREtQM0RZTzc3T1NBRU5IU0FFR0s3WUNFTFBYT1FFWUI3RVFSTVBLWlBNQUxINE5BRUVLSjZDRyIsIm5hbWUiOiJTWVMiLCJzdWIiOiJBRElRQ1lLNEszT0tUUE9ER0NMSTRQRFE2WEJPNTJNSVNCUFRBSURFU0VKTUxaQ01OVUxES0NDWSIsIm5hdHMiOnsibGltaXRzIjp7InN1YnMiOi0xLCJkYXRhIjotMSwicGF5bG9hZCI6LTEsImltcG9ydHMiOi0xLCJleHBvcnRzIjotMSwid2lsZGNhcmRzIjp0cnVlLCJjb25uIjotMSwibGVhZiI6LTF9LCJkZWZhdWx0X3Blcm1pc3Npb25zIjp7InB1YiI6e30sInN1YiI6e319LCJhdXRob3JpemF0aW9uIjp7fSwidHlwZSI6ImFjY291bnQiLCJ2ZXJzaW9uIjoyfX0.TiGIk8XON394D9SBEowGHY_nTeOyHiM-ihyw6HZs8AngOnYPFXH9OVjsaAf8Poa2k_V84VtH7yVNgNdjBgduDA"
|
||||
}
|
||||
}
|
||||
cluster: enabled: true
|
||||
jetstream: enabled: true
|
||||
websocket: enabled: true
|
||||
monitor: enabled: true
|
||||
}
|
||||
promExporter: enabled: true
|
||||
promExporter: podMonitor: enabled: true
|
||||
}
|
||||
},
|
||||
#HelmChart & {
|
||||
metadata: name: "jeff-holos-nack"
|
||||
namespace: Namespace
|
||||
_dependsOn: "jeff-holos-nats": _
|
||||
chart: {
|
||||
name: "nack"
|
||||
version: "0.25.2"
|
||||
repository: NatsRepository
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
let NatsRepository = {
|
||||
name: "nats"
|
||||
url: "https://nats-io.github.io/k8s/helm/charts/"
|
||||
}
|
||||
@@ -0,0 +1,722 @@
|
||||
package holos
|
||||
|
||||
#NatsValues: {
|
||||
//###############################################################################
|
||||
// Global options
|
||||
//###############################################################################
|
||||
global: {
|
||||
image: {
|
||||
// global image pull policy to use for all container images in the chart
|
||||
// can be overridden by individual image pullPolicy
|
||||
pullPolicy: null
|
||||
// global list of secret names to use as image pull secrets for all pod specs in the chart
|
||||
// secrets must exist in the same namespace
|
||||
// https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
|
||||
pullSecretNames: []
|
||||
// global registry to use for all container images in the chart
|
||||
// can be overridden by individual image registry
|
||||
registry: null
|
||||
}
|
||||
|
||||
// global labels will be applied to all resources deployed by the chart
|
||||
labels: {}
|
||||
}
|
||||
|
||||
//###############################################################################
|
||||
// Common options
|
||||
//###############################################################################
|
||||
// override name of the chart
|
||||
nameOverride: null
|
||||
// override full name of the chart+release
|
||||
fullnameOverride: null
|
||||
// override the namespace that resources are installed into
|
||||
namespaceOverride: null
|
||||
|
||||
// reference a common CA Certificate or Bundle in all nats config `tls` blocks and nats-box contexts
|
||||
// note: `tls.verify` still must be set in the appropriate nats config `tls` blocks to require mTLS
|
||||
tlsCA: {
|
||||
enabled: false
|
||||
// set configMapName in order to mount an existing configMap to dir
|
||||
configMapName: null
|
||||
// set secretName in order to mount an existing secretName to dir
|
||||
secretName: null
|
||||
// directory to mount the configMap or secret to
|
||||
dir: "/etc/nats-ca-cert"
|
||||
// key in the configMap or secret that contains the CA Certificate or Bundle
|
||||
key: "ca.crt"
|
||||
}
|
||||
|
||||
//###############################################################################
|
||||
// NATS Stateful Set and associated resources
|
||||
//###############################################################################
|
||||
//###########################################################
|
||||
// NATS config
|
||||
//###########################################################
|
||||
config: {
|
||||
cluster: {
|
||||
enabled: true | *false
|
||||
port: 6222
|
||||
// must be 2 or higher when jetstream is enabled
|
||||
replicas: 3
|
||||
|
||||
// apply to generated route URLs that connect to other pods in the StatefulSet
|
||||
routeURLs: {
|
||||
// if both user and password are set, they will be added to route URLs
|
||||
// and the cluster authorization block
|
||||
user: null
|
||||
password: null
|
||||
// set to true to use FQDN in route URLs
|
||||
useFQDN: false
|
||||
k8sClusterDomain: "cluster.local"
|
||||
}
|
||||
|
||||
tls: {
|
||||
enabled: true | *false
|
||||
// set secretName in order to mount an existing secret to dir
|
||||
secretName: null
|
||||
dir: "/etc/nats-certs/cluster"
|
||||
cert: "tls.crt"
|
||||
key: "tls.key"
|
||||
// merge or patch the tls config
|
||||
// https://docs.nats.io/running-a-nats-service/configuration/securing_nats/tls
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
// merge or patch the cluster config
|
||||
// https://docs.nats.io/running-a-nats-service/configuration/clustering/cluster_config
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
jetstream: {
|
||||
enabled: true | *false
|
||||
|
||||
fileStore: {
|
||||
enabled: true
|
||||
dir: "/data"
|
||||
|
||||
//###########################################################
|
||||
// stateful set -> volume claim templates -> jetstream pvc
|
||||
//###########################################################
|
||||
pvc: {
|
||||
enabled: true
|
||||
size: "10Gi"
|
||||
storageClassName: null
|
||||
|
||||
// merge or patch the jetstream pvc
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#persistentvolumeclaim-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}-js"
|
||||
name: null
|
||||
}
|
||||
|
||||
// defaults to the PVC size
|
||||
maxSize: null
|
||||
}
|
||||
|
||||
memoryStore: {
|
||||
enabled: false
|
||||
// ensure that container has a sufficient memory limit greater than maxSize
|
||||
maxSize: "1Gi"
|
||||
}
|
||||
|
||||
// merge or patch the jetstream config
|
||||
// https://docs.nats.io/running-a-nats-service/configuration#jetstream
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
nats: {
|
||||
port: 4222
|
||||
tls: {
|
||||
enabled: false
|
||||
// set secretName in order to mount an existing secret to dir
|
||||
secretName: null
|
||||
dir: "/etc/nats-certs/nats"
|
||||
cert: "tls.crt"
|
||||
key: "tls.key"
|
||||
// merge or patch the tls config
|
||||
// https://docs.nats.io/running-a-nats-service/configuration/securing_nats/tls
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
}
|
||||
|
||||
leafnodes: {
|
||||
enabled: false
|
||||
port: 7422
|
||||
tls: {
|
||||
enabled: false
|
||||
// set secretName in order to mount an existing secret to dir
|
||||
secretName: null
|
||||
dir: "/etc/nats-certs/leafnodes"
|
||||
cert: "tls.crt"
|
||||
key: "tls.key"
|
||||
// merge or patch the tls config
|
||||
// https://docs.nats.io/running-a-nats-service/configuration/securing_nats/tls
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
// merge or patch the leafnodes config
|
||||
// https://docs.nats.io/running-a-nats-service/configuration/leafnodes/leafnode_conf
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
websocket: {
|
||||
enabled: true | *false
|
||||
port: 8080
|
||||
tls: {
|
||||
enabled: false
|
||||
// set secretName in order to mount an existing secret to dir
|
||||
secretName: null
|
||||
dir: "/etc/nats-certs/websocket"
|
||||
cert: "tls.crt"
|
||||
key: "tls.key"
|
||||
// merge or patch the tls config
|
||||
// https://docs.nats.io/running-a-nats-service/configuration/securing_nats/tls
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
//###########################################################
|
||||
// ingress
|
||||
//###########################################################
|
||||
// service must be enabled also
|
||||
ingress: {
|
||||
enabled: false
|
||||
// must contain at least 1 host otherwise ingress will not be created
|
||||
hosts: []
|
||||
path: "/"
|
||||
pathType: "Exact"
|
||||
// sets to the ingress class name
|
||||
className: null
|
||||
// set to an existing secret name to enable TLS on the ingress; applies to all hosts
|
||||
tlsSecretName: null
|
||||
|
||||
// merge or patch the ingress
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#ingress-v1-networking-k8s-io
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}-ws"
|
||||
name: null
|
||||
}
|
||||
|
||||
// merge or patch the websocket config
|
||||
// https://docs.nats.io/running-a-nats-service/configuration/websocket/websocket_conf
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
mqtt: {
|
||||
enabled: false
|
||||
port: 1883
|
||||
tls: {
|
||||
enabled: false
|
||||
// set secretName in order to mount an existing secret to dir
|
||||
secretName: null
|
||||
dir: "/etc/nats-certs/mqtt"
|
||||
cert: "tls.crt"
|
||||
key: "tls.key"
|
||||
// merge or patch the tls config
|
||||
// https://docs.nats.io/running-a-nats-service/configuration/securing_nats/tls
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
// merge or patch the mqtt config
|
||||
// https://docs.nats.io/running-a-nats-service/configuration/mqtt/mqtt_config
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
gateway: {
|
||||
enabled: false
|
||||
port: 7222
|
||||
tls: {
|
||||
enabled: false
|
||||
// set secretName in order to mount an existing secret to dir
|
||||
secretName: null
|
||||
dir: "/etc/nats-certs/gateway"
|
||||
cert: "tls.crt"
|
||||
key: "tls.key"
|
||||
// merge or patch the tls config
|
||||
// https://docs.nats.io/running-a-nats-service/configuration/securing_nats/tls
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
// merge or patch the gateway config
|
||||
// https://docs.nats.io/running-a-nats-service/configuration/gateways/gateway#gateway-configuration-block
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
monitor: {
|
||||
enabled: true
|
||||
port: 8222
|
||||
tls: {
|
||||
// config.nats.tls must be enabled also
|
||||
// when enabled, monitoring port will use HTTPS with the options from config.nats.tls
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
|
||||
profiling: {
|
||||
enabled: false
|
||||
port: 65432
|
||||
}
|
||||
|
||||
resolver: {
|
||||
enabled: true | *false
|
||||
dir: "/data/resolver"
|
||||
|
||||
//###########################################################
|
||||
// stateful set -> volume claim templates -> resolver pvc
|
||||
//###########################################################
|
||||
pvc: {
|
||||
enabled: true
|
||||
size: "1Gi"
|
||||
storageClassName: null
|
||||
|
||||
// merge or patch the pvc
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#persistentvolumeclaim-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}-resolver"
|
||||
name: null
|
||||
}
|
||||
|
||||
// merge or patch the resolver
|
||||
// https://docs.nats.io/running-a-nats-service/configuration/securing_nats/auth_intro/jwt/resolver
|
||||
merge: {
|
||||
type?: string
|
||||
interval?: string
|
||||
timeout?: string
|
||||
}
|
||||
patch: []
|
||||
}
|
||||
|
||||
// adds a prefix to the server name, which defaults to the pod name
|
||||
// helpful for ensuring server name is unique in a super cluster
|
||||
serverNamePrefix: ""
|
||||
|
||||
// merge or patch the nats config
|
||||
// https://docs.nats.io/running-a-nats-service/configuration
|
||||
// following special rules apply
|
||||
// 1. strings that start with << and end with >> will be unquoted
|
||||
// use this for variables and numbers with units
|
||||
// 2. keys ending in $include will be switched to include directives
|
||||
// keys are sorted alphabetically, use prefix before $includes to control includes ordering
|
||||
// paths should be relative to /etc/nats-config/nats.conf
|
||||
// example:
|
||||
//
|
||||
// merge:
|
||||
// $include: ./my-config.conf
|
||||
// zzz$include: ./my-config-last.conf
|
||||
// server_name: nats
|
||||
// authorization:
|
||||
// token: << $TOKEN >>
|
||||
// jetstream:
|
||||
// max_memory_store: << 1GB >>
|
||||
//
|
||||
// will yield the config:
|
||||
// {
|
||||
// include ./my-config.conf;
|
||||
// "authorization": {
|
||||
// "token": $TOKEN
|
||||
// },
|
||||
// "jetstream": {
|
||||
// "max_memory_store": 1GB
|
||||
// },
|
||||
// "server_name": "nats",
|
||||
// include ./my-config-last.conf;
|
||||
// }
|
||||
merge: {
|
||||
operator?: string
|
||||
system_account?: string
|
||||
resolver_preload?: [string]: string
|
||||
}
|
||||
patch: []
|
||||
}
|
||||
|
||||
//###########################################################
|
||||
// stateful set -> pod template -> nats container
|
||||
//###########################################################
|
||||
container: {
|
||||
image: {
|
||||
repository: "nats"
|
||||
tag: "2.10.12-alpine"
|
||||
pullPolicy: null
|
||||
registry: null
|
||||
}
|
||||
|
||||
// container port options
|
||||
// must be enabled in the config section also
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#containerport-v1-core
|
||||
ports: {
|
||||
nats: {}
|
||||
leafnodes: {}
|
||||
websocket: {}
|
||||
mqtt: {}
|
||||
cluster: {}
|
||||
gateway: {}
|
||||
monitor: {}
|
||||
profiling: {}
|
||||
}
|
||||
|
||||
// map with key as env var name, value can be string or map
|
||||
// example:
|
||||
//
|
||||
// env:
|
||||
// GOMEMLIMIT: 7GiB
|
||||
// TOKEN:
|
||||
// valueFrom:
|
||||
// secretKeyRef:
|
||||
// name: nats-auth
|
||||
// key: token
|
||||
env: {}
|
||||
|
||||
// merge or patch the container
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#container-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
//###########################################################
|
||||
// stateful set -> pod template -> reloader container
|
||||
//###########################################################
|
||||
reloader: {
|
||||
enabled: true
|
||||
image: {
|
||||
repository: "natsio/nats-server-config-reloader"
|
||||
tag: "0.14.1"
|
||||
pullPolicy: null
|
||||
registry: null
|
||||
}
|
||||
|
||||
// env var map, see nats.env for an example
|
||||
env: {}
|
||||
|
||||
// all nats container volume mounts with the following prefixes
|
||||
// will be mounted into the reloader container
|
||||
natsVolumeMountPrefixes: ["/etc/"]
|
||||
|
||||
// merge or patch the container
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#container-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
//###########################################################
|
||||
// stateful set -> pod template -> prom-exporter container
|
||||
//###########################################################
|
||||
// config.monitor must be enabled
|
||||
promExporter: {
|
||||
enabled: true | *false
|
||||
image: {
|
||||
repository: "natsio/prometheus-nats-exporter"
|
||||
tag: "0.14.0"
|
||||
pullPolicy: null
|
||||
registry: null
|
||||
}
|
||||
|
||||
port: 7777
|
||||
// env var map, see nats.env for an example
|
||||
env: {}
|
||||
|
||||
// merge or patch the container
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#container-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
|
||||
//###########################################################
|
||||
// prometheus pod monitor
|
||||
//###########################################################
|
||||
podMonitor: {
|
||||
enabled: true | *false
|
||||
|
||||
// merge or patch the pod monitor
|
||||
// https://prometheus-operator.dev/docs/operator/api/#monitoring.coreos.com/v1.PodMonitor
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}"
|
||||
name: null
|
||||
}
|
||||
}
|
||||
|
||||
//###########################################################
|
||||
// service
|
||||
//###########################################################
|
||||
service: {
|
||||
enabled: true
|
||||
|
||||
// service port options
|
||||
// additional boolean field enable to control whether port is exposed in the service
|
||||
// must be enabled in the config section also
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#serviceport-v1-core
|
||||
ports: {
|
||||
nats: enabled: true
|
||||
leafnodes: enabled: true
|
||||
websocket: enabled: true
|
||||
mqtt: enabled: true
|
||||
cluster: enabled: false
|
||||
gateway: enabled: false
|
||||
monitor: enabled: false
|
||||
profiling: enabled: false
|
||||
}
|
||||
|
||||
// merge or patch the service
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#service-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}"
|
||||
name: null
|
||||
}
|
||||
|
||||
//###########################################################
|
||||
// other nats extension points
|
||||
//###########################################################
|
||||
// stateful set
|
||||
statefulSet: {
|
||||
// merge or patch the stateful set
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#statefulset-v1-apps
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}"
|
||||
name: null
|
||||
}
|
||||
|
||||
// stateful set -> pod template
|
||||
podTemplate: {
|
||||
// adds a hash of the ConfigMap as a pod annotation
|
||||
// this will cause the StatefulSet to roll when the ConfigMap is updated
|
||||
configChecksumAnnotation: true
|
||||
|
||||
// map of topologyKey: topologySpreadConstraint
|
||||
// labelSelector will be added to match StatefulSet pods
|
||||
//
|
||||
// topologySpreadConstraints:
|
||||
// kubernetes.io/hostname:
|
||||
// maxSkew: 1
|
||||
//
|
||||
topologySpreadConstraints: {}
|
||||
|
||||
// merge or patch the pod template
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#pod-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
// headless service
|
||||
headlessService: {
|
||||
// merge or patch the headless service
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#service-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}-headless"
|
||||
name: null
|
||||
}
|
||||
|
||||
// config map
|
||||
configMap: {
|
||||
// merge or patch the config map
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#configmap-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}-config"
|
||||
name: null
|
||||
}
|
||||
|
||||
// pod disruption budget
|
||||
podDisruptionBudget: {
|
||||
enabled: true
|
||||
// merge or patch the pod disruption budget
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#poddisruptionbudget-v1-policy
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}"
|
||||
name: null
|
||||
}
|
||||
|
||||
// service account
|
||||
serviceAccount: {
|
||||
enabled: false
|
||||
// merge or patch the service account
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#serviceaccount-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}"
|
||||
name: null
|
||||
}
|
||||
|
||||
//###########################################################
|
||||
// natsBox
|
||||
//
|
||||
// NATS Box Deployment and associated resources
|
||||
//###########################################################
|
||||
natsBox: {
|
||||
enabled: true
|
||||
|
||||
//###########################################################
|
||||
// NATS contexts
|
||||
//###########################################################
|
||||
contexts: {
|
||||
default: {
|
||||
creds: {
|
||||
// set contents in order to create a secret with the creds file contents
|
||||
contents: null
|
||||
// set secretName in order to mount an existing secret to dir
|
||||
secretName: null
|
||||
// defaults to /etc/nats-creds/<context-name>
|
||||
dir: null
|
||||
key: "nats.creds"
|
||||
}
|
||||
nkey: {
|
||||
// set contents in order to create a secret with the nkey file contents
|
||||
contents: null
|
||||
// set secretName in order to mount an existing secret to dir
|
||||
secretName: null
|
||||
// defaults to /etc/nats-nkeys/<context-name>
|
||||
dir: null
|
||||
key: "nats.nk"
|
||||
}
|
||||
// used to connect with client certificates
|
||||
tls: {
|
||||
// set secretName in order to mount an existing secret to dir
|
||||
secretName: null
|
||||
// defaults to /etc/nats-certs/<context-name>
|
||||
dir: null
|
||||
cert: "tls.crt"
|
||||
key: "tls.key"
|
||||
}
|
||||
|
||||
// merge or patch the context
|
||||
// https://docs.nats.io/using-nats/nats-tools/nats_cli#nats-contexts
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
}
|
||||
|
||||
// name of context to select by default
|
||||
defaultContextName: "default"
|
||||
|
||||
//###########################################################
|
||||
// deployment -> pod template -> nats-box container
|
||||
//###########################################################
|
||||
container: {
|
||||
image: {
|
||||
repository: "natsio/nats-box"
|
||||
tag: "0.14.2"
|
||||
pullPolicy: null
|
||||
registry: null
|
||||
}
|
||||
|
||||
// env var map, see nats.env for an example
|
||||
env: {}
|
||||
|
||||
// merge or patch the container
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#container-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
//###########################################################
|
||||
// other nats-box extension points
|
||||
//###########################################################
|
||||
// deployment
|
||||
deployment: {
|
||||
// merge or patch the deployment
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#deployment-v1-apps
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}-box"
|
||||
name: null
|
||||
}
|
||||
|
||||
// deployment -> pod template
|
||||
podTemplate: {
|
||||
// merge or patch the pod template
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#pod-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
}
|
||||
|
||||
// contexts secret
|
||||
contextsSecret: {
|
||||
// merge or patch the context secret
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#secret-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}-box-contexts"
|
||||
name: null
|
||||
}
|
||||
|
||||
// contents secret
|
||||
contentsSecret: {
|
||||
// merge or patch the contents secret
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#secret-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}-box-contents"
|
||||
name: null
|
||||
}
|
||||
|
||||
// service account
|
||||
serviceAccount: {
|
||||
enabled: false
|
||||
// merge or patch the service account
|
||||
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#serviceaccount-v1-core
|
||||
merge: {}
|
||||
patch: []
|
||||
// defaults to "{{ include "nats.fullname" $ }}-box"
|
||||
name: null
|
||||
}
|
||||
}
|
||||
|
||||
//###############################################################################
|
||||
// Extra user-defined resources
|
||||
//###############################################################################
|
||||
//
|
||||
// add arbitrary user-generated resources
|
||||
// example:
|
||||
//
|
||||
// config:
|
||||
// websocket:
|
||||
// enabled: true
|
||||
// extraResources:
|
||||
// - apiVersion: networking.istio.io/v1beta1
|
||||
// kind: VirtualService
|
||||
// metadata:
|
||||
// name:
|
||||
// $tplYaml: >
|
||||
// {{ include "nats.fullname" $ | quote }}
|
||||
// labels:
|
||||
// $tplYaml: |
|
||||
// {{ include "nats.labels" $ }}
|
||||
// spec:
|
||||
// hosts:
|
||||
// - demo.nats.io
|
||||
// gateways:
|
||||
// - my-gateway
|
||||
// http:
|
||||
// - name: default
|
||||
// match:
|
||||
// - name: root
|
||||
// uri:
|
||||
// exact: /
|
||||
// route:
|
||||
// - destination:
|
||||
// host:
|
||||
// $tplYaml: >
|
||||
// {{ .Values.service.name | quote }}
|
||||
// port:
|
||||
// number:
|
||||
// $tplYaml: >
|
||||
// {{ .Values.config.websocket.port }}
|
||||
//
|
||||
extraResources: []
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# This script initializes authorization for a nats cluster. The process is:
|
||||
#
|
||||
# Locally:
|
||||
# 1. Generate the nats operator jwt.
|
||||
# 2. Generate a SYS account jwt issued by the operator.
|
||||
# 3. Store both into vault
|
||||
#
|
||||
# When nats is deployed an ExternalSecret populates auth.conf which is included
|
||||
# into nats.conf. This approach allows helm values to be used for most things
|
||||
# except for secrets.
|
||||
#
|
||||
# Clean up by removing the nsc directory.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
tmpdir="$(mktemp -d)"
|
||||
finish() {
|
||||
[[ -d "$tmpdir" ]] && rm -rf "$tmpdir"
|
||||
}
|
||||
trap finish EXIT
|
||||
|
||||
PARENT="$(cd "$(dirname $0)" && pwd)"
|
||||
: "${OPERATOR_NAME:="Holos"}"
|
||||
|
||||
: "${OIX_NAMESPACE:=$(kubectl config view --minify --flatten -ojsonpath='{.contexts[0].context.namespace}')}"
|
||||
nsc="${HOME}/.bin/nsc"
|
||||
|
||||
ROOT="${PARENT}/${OIX_NAMESPACE}/nsc"
|
||||
export NKEYS_PATH="${ROOT}/nkeys"
|
||||
export NSC_HOME="${ROOT}/accounts"
|
||||
|
||||
mkdir -p "$NKEYS_PATH"
|
||||
mkdir -p "$NSC_HOME"
|
||||
|
||||
# Install nsc if not already installed
|
||||
if ! [[ -x $nsc ]]; then
|
||||
platform="$(kubectl version --output=json | jq .clientVersion.platform -r)"
|
||||
platform="${platform//\//-}"
|
||||
curl -fSLo "${tmpdir}/nsc.zip" "https://github.com/nats-io/nsc/releases/download/v2.8.6/nsc-${platform}.zip"
|
||||
(cd "${tmpdir}" && unzip nsc.zip)
|
||||
sudo install -o 0 -g 0 -m 0755 "${tmpdir}/nsc" $nsc
|
||||
fi
|
||||
|
||||
echo "export NKEYS_PATH='${NKEYS_PATH}'" > "${ROOT}/nsc.env"
|
||||
echo "export NSC_HOME='${NSC_HOME}'" >> "${ROOT}/nsc.env"
|
||||
# use kubectl port-forward nats-headless 4222
|
||||
echo "export NATS_URL='nats://localhost:4222'" >> "${ROOT}/nsc.env"
|
||||
echo "export NATS_CREDS='${ROOT}/nkeys/creds/${OPERATOR_NAME}/SYS/sys.creds'" >> "${ROOT}/nsc.env"
|
||||
|
||||
echo "export NATS_CA='${ROOT}/ca.crt'" >> "${ROOT}/nsc.env"
|
||||
echo "export NATS_CERT='${ROOT}/tls.crt'" >> "${ROOT}/nsc.env"
|
||||
echo "export NATS_KEY='${ROOT}/tls.key'" >> "${ROOT}/nsc.env"
|
||||
|
||||
$nsc --data-dir="${ROOT}/stores" list operators
|
||||
|
||||
# Create operator
|
||||
$nsc add operator --name "${OPERATOR_NAME}"
|
||||
# Create system account
|
||||
$nsc add account --name SYS
|
||||
$nsc add user --name sys
|
||||
# Create account for STAN purposes.
|
||||
$nsc add account --name STAN
|
||||
$nsc add user --name stan
|
||||
|
||||
# Generate an auth config compatible with the StatefulSet mounting the
|
||||
# nats-jwt-pvc PersistentVolumeClaim at path /data/accounts
|
||||
$nsc generate config --sys-account SYS --nats-resolver \
|
||||
| sed "s,dir.*jwt',dir: '/data/accounts'" \
|
||||
> "${ROOT}/auth.conf"
|
||||
|
||||
# Store the auth config in vault.
|
||||
# vault kv put kv/${OIX_CLUSTER_NAME}/kube-namespace/holos-dev/nats-auth-config "auth.conf=@${tmpdir}/auth.conf"
|
||||
# Store the SYS creds in vault for use by the nack controller.
|
||||
# vault kv put kv/${OIX_CLUSTER_NAME}/kube-namespace/holos-dev/nats-sys-creds "sys.creds=@${OIX_CLUSTER_NAME}/nsc/nkeys/creds/${OPERATOR_NAME}/SYS/sys.creds"
|
||||
|
||||
echo "After deploying the nats component, use the get-cert command to fetch the client cert."
|
||||
|
||||
echo "Use kubectl port-forward svc/nats-headless 4222" >&2
|
||||
echo "source ${ROOT}/nsc.env to make it all work." >&2
|
||||
@@ -71,14 +71,15 @@ let IstioInject = [{op: "add", path: "/spec/template/metadata/labels/sidecar.ist
|
||||
}
|
||||
}
|
||||
|
||||
// Probably shouldn't use the authproxy struct and should instead define an identity provider struct.
|
||||
let AuthProxySpec = #AuthProxySpec & #Platform.authproxy
|
||||
let OAuthClient = #Platform.oauthClients.argocd.spec
|
||||
|
||||
let OIDCConfig = {
|
||||
name: "Holos Platform"
|
||||
issuer: AuthProxySpec.issuer
|
||||
clientID: #Platform.argocd.clientID
|
||||
requestedIDTokenClaims: groups: essential: true
|
||||
requestedScopes: ["openid", "profile", "email", "groups", "urn:zitadel:iam:org:domain:primary:\(AuthProxySpec.orgDomain)"]
|
||||
name: "Holos Platform"
|
||||
issuer: OAuthClient.issuer
|
||||
clientID: OAuthClient.clientID
|
||||
requestedScopes: OAuthClient.scopesList
|
||||
// Set redirect uri to https://argocd.example.com/pkce/verify
|
||||
enablePKCEAuthentication: true
|
||||
|
||||
requestedIDTokenClaims: groups: essential: true
|
||||
}
|
||||
|
||||
@@ -21,12 +21,12 @@ spec: components: KubernetesObjectsList: [
|
||||
// GatewayServers represents all hosts for all VirtualServices in the cluster attached to Gateway/default
|
||||
// NOTE: This is a critical structure because the default Gateway should be used in most cases.
|
||||
let GatewayServers = {
|
||||
// Critical Feature: Map all Project hosts to the default Gateway.
|
||||
for Project in _Projects {
|
||||
for server in (#ProjectTemplate & {project: Project}).ClusterGatewayServers {
|
||||
(server.port.name): server
|
||||
}
|
||||
(#ProjectTemplate & {project: Project}).ClusterDefaultGatewayServers
|
||||
}
|
||||
|
||||
// TODO: Refactor to use FQDN as key
|
||||
for k, svc in #OptionalServices {
|
||||
if svc.enabled && list.Contains(svc.clusterNames, #ClusterName) {
|
||||
for server in svc.servers {
|
||||
@@ -35,6 +35,7 @@ let GatewayServers = {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Remove? Why aren't these part of the platform project?
|
||||
if #PlatformServers[#ClusterName] != _|_ {
|
||||
for server in #PlatformServers[#ClusterName] {
|
||||
(server.port.name): server
|
||||
@@ -52,6 +53,11 @@ let OBJECTS = #APIObjects & {
|
||||
spec: servers: [for x in GatewayServers {x}]
|
||||
}
|
||||
|
||||
// Manage an ExternalSecret for each server defined in the default Gateway to sync the cert.
|
||||
for Server in Gateway.default.spec.servers {
|
||||
ExternalSecret: "\(Server.tls.credentialName)": metadata: namespace: "istio-ingress"
|
||||
}
|
||||
|
||||
for k, svc in #OptionalServices {
|
||||
if svc.enabled && list.Contains(svc.clusterNames, #ClusterName) {
|
||||
for k, s in svc.servers {
|
||||
|
||||
@@ -8,7 +8,7 @@ let ComponentName = "\(#InstancePrefix)-ingress"
|
||||
|
||||
spec: components: HelmChartList: [
|
||||
#HelmChart & {
|
||||
_dependsOn: "prod-secrets-namespaces": _
|
||||
_dependsOn: "prod-secrets-stores": _
|
||||
_dependsOn: "\(#InstancePrefix)-istio-base": _
|
||||
_dependsOn: "\(#InstancePrefix)-istiod": _
|
||||
|
||||
@@ -76,6 +76,10 @@ let RedirectMetaName = {
|
||||
|
||||
let OBJECTS = #APIObjects & {
|
||||
apiObjects: {
|
||||
ExternalSecret: "istio-ingress-mtls-cert": #ExternalSecret & {
|
||||
metadata: name: "istio-ingress-mtls-cert"
|
||||
metadata: namespace: #TargetNamespace
|
||||
}
|
||||
Gateway: {
|
||||
"\(RedirectMetaName.name)": #Gateway & {
|
||||
metadata: RedirectMetaName
|
||||
|
||||
@@ -18,6 +18,10 @@ _IngressAuthProxy: {
|
||||
Domains: (#Platform.org.domain): _
|
||||
Domains: "\(#ClusterName).\(#Platform.org.domain)": _
|
||||
|
||||
// TODO: This should be generated from ProjectHosts
|
||||
Domains: "holos.run": _
|
||||
Domains: "\(#ClusterName).holos.run": _
|
||||
|
||||
let Metadata = {
|
||||
name: string
|
||||
namespace: Namespace
|
||||
@@ -85,7 +89,8 @@ _IngressAuthProxy: {
|
||||
spec: {
|
||||
securityContext: seccompProfile: type: "RuntimeDefault"
|
||||
containers: [{
|
||||
image: "quay.io/oauth2-proxy/oauth2-proxy:v7.6.0"
|
||||
// image: "quay.io/oauth3-proxy/oauth2-proxy:v7.6.0"
|
||||
image: "quay.io/holos/oauth2-proxy:v7.6.0-1-g77a03ae2"
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
name: "oauth2-proxy"
|
||||
volumeMounts: [{
|
||||
@@ -271,11 +276,14 @@ _IngressAuthProxy: {
|
||||
rules: [
|
||||
{
|
||||
to: [{
|
||||
// Refer to https://istio.io/latest/docs/ops/best-practices/security/#writing-host-match-policies
|
||||
operation: notHosts: [
|
||||
// Never send requests for the login service through the authorizer, would block login.
|
||||
AuthProxySpec.issuerHost,
|
||||
"\(AuthProxySpec.issuerHost):*",
|
||||
// Exclude hosts with specialized rules from the catch-all.
|
||||
for x in _AuthPolicyRules.hosts {x.name},
|
||||
for x in _AuthPolicyRules.hosts {"\(x.name):*"},
|
||||
]
|
||||
}]
|
||||
when: [
|
||||
@@ -298,7 +306,7 @@ _IngressAuthProxy: {
|
||||
_AuthPolicyRules: #AuthPolicyRules & {
|
||||
hosts: {
|
||||
let Vault = "vault.core.ois.run"
|
||||
(Vault): {
|
||||
"\(Vault)": {
|
||||
slug: "vault"
|
||||
// Rules for when to route requests through the auth proxy
|
||||
spec: rules: [
|
||||
@@ -321,3 +329,20 @@ _AuthPolicyRules: #AuthPolicyRules & {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Exclude project hosts from the auth proxy if configured to do so. The
|
||||
// intended effect is to exclude the host from the blanket `authproxy-custom`
|
||||
// AuthorizationPolicy rule _without_ adding a specialized AuthorizationPolicy
|
||||
// for the same host. This has the effect of completely excluding the host from
|
||||
// authorization policy.
|
||||
for Project in _Projects {
|
||||
let ProjectHosts = (#ProjectHosts & {project: Project}).Hosts
|
||||
|
||||
for FQDN, Host in ProjectHosts {
|
||||
if Host.NoAuthorizationPolicy {
|
||||
if Host.clusters[#ClusterName] != _|_ {
|
||||
_AuthPolicyRules: hosts: "\(Host.fqdn)": NoAuthorizationPolicy: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ package holos
|
||||
|
||||
let Namespace = "prod-platform"
|
||||
|
||||
// FYI: kube-prometheus-stack is a large umbrella chart what brings in other large charts like
|
||||
// FYI: kube-prometheus-stack is a large umbrella chart that brings in other large charts like
|
||||
// [grafana](https://github.com/grafana/helm-charts/tree/main/charts/grafana).
|
||||
// This may make affect maintainability. Consider breaking the integration down into
|
||||
// constituent charts represented as holos component instances.
|
||||
@@ -77,7 +77,7 @@ spec: components: HelmChartList: [
|
||||
token_url: OIDC.token_endpoint
|
||||
api_url: OIDC.userinfo_endpoint
|
||||
use_pkce: true
|
||||
name_attribute_path: name
|
||||
name_attribute_path: "name"
|
||||
// TODO: Lift the admin, editor, and viewer group names up to the plaform config struct.
|
||||
role_attribute_path: "contains(groups[*], 'prod-cluster-admin') && 'Admin' || contains(groups[*], 'prod-cluster-editor') && 'Editor' || 'Viewer'"
|
||||
}
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
package holos
|
||||
|
||||
// for Project in _Projects {
|
||||
// spec: components: resources: (#ProjectTemplate & {project: Project}).workload.resources
|
||||
// }
|
||||
|
||||
let Namespace = "jeff-holos"
|
||||
|
||||
#Kustomization: spec: targetNamespace: Namespace
|
||||
|
||||
spec: components: HelmChartList: [
|
||||
#HelmChart & {
|
||||
metadata: name: "jeff-holos-nats"
|
||||
namespace: Namespace
|
||||
_dependsOn: "prod-secrets-stores": _
|
||||
chart: {
|
||||
name: "nats"
|
||||
version: "1.1.10"
|
||||
repository: NatsRepository
|
||||
}
|
||||
},
|
||||
#HelmChart & {
|
||||
metadata: name: "jeff-holos-nack"
|
||||
namespace: Namespace
|
||||
_dependsOn: "jeff-holos-nats": _
|
||||
chart: {
|
||||
name: "nack"
|
||||
version: "0.25.2"
|
||||
repository: NatsRepository
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
let NatsRepository = {
|
||||
name: "nats"
|
||||
url: "https://nats-io.github.io/k8s/helm/charts/"
|
||||
}
|
||||
@@ -4,15 +4,23 @@ package holos
|
||||
|
||||
let ZitadelProjectID = 257713952794870157
|
||||
|
||||
let AllClusters = {
|
||||
// platform level services typically run in the core cluster pair.
|
||||
core1: _
|
||||
core2: _
|
||||
// for development, probably wouldn't run these services in the workload clusters.
|
||||
k1: _
|
||||
k2: _
|
||||
k3: _
|
||||
k4: _
|
||||
k5: _
|
||||
}
|
||||
|
||||
_Projects: #Projects & {
|
||||
// The platform project is required and where platform services reside. ArgoCD, Grafana, Prometheus, etc...
|
||||
platform: {
|
||||
resourceId: ZitadelProjectID
|
||||
// platform level services typically run in the core cluster pair.
|
||||
clusters: core1: _
|
||||
clusters: core2: _
|
||||
// for development, probably wouldn't run these services in the workload clusters.
|
||||
clusters: k2: _
|
||||
clusters: AllClusters
|
||||
// Services hosted in the platform project
|
||||
hosts: argocd: _
|
||||
hosts: grafana: _
|
||||
@@ -21,8 +29,9 @@ _Projects: #Projects & {
|
||||
|
||||
holos: {
|
||||
resourceId: ZitadelProjectID
|
||||
clusters: k1: _
|
||||
clusters: k2: _
|
||||
domain: "holos.run"
|
||||
clusters: AllClusters
|
||||
|
||||
environments: {
|
||||
prod: stage: "prod"
|
||||
dev: stage: "dev"
|
||||
@@ -30,6 +39,13 @@ _Projects: #Projects & {
|
||||
gary: stage: dev.stage
|
||||
nate: stage: dev.stage
|
||||
}
|
||||
|
||||
// app is the holos web app and grpc api.
|
||||
hosts: app: _
|
||||
// provision is the choria broker provisioning system.
|
||||
hosts: provision: NoAuthorizationPolicy: true
|
||||
// nats is the nats service holos controller machine room agents connect after provisioning.
|
||||
hosts: nats: NoAuthorizationPolicy: true
|
||||
}
|
||||
|
||||
iam: {
|
||||
@@ -0,0 +1,40 @@
|
||||
package holos
|
||||
|
||||
// Certificate used by the ingress to connect to services using a platform
|
||||
// issued certificate but which are not using istio sidecar injection.
|
||||
// Examples are keycloak, vault, nats, choria, etc...
|
||||
|
||||
let Namespace = "istio-ingress"
|
||||
let CertName = "istio-ingress-mtls-cert"
|
||||
|
||||
spec: components: KubernetesObjectsList: [
|
||||
#KubernetesObjects & {
|
||||
_dependsOn: "prod-platform-issuer": _
|
||||
|
||||
metadata: name: CertName
|
||||
apiObjectMap: OBJECTS.apiObjectMap
|
||||
},
|
||||
]
|
||||
|
||||
let OBJECTS = #APIObjects & {
|
||||
apiObjects: {
|
||||
Certificate: "\(CertName)": #Certificate & {
|
||||
metadata: {
|
||||
name: CertName
|
||||
namespace: Namespace
|
||||
}
|
||||
spec: {
|
||||
secretName: metadata.name
|
||||
issuerRef: kind: "ClusterIssuer"
|
||||
issuerRef: name: "platform-issuer"
|
||||
commonName: "istio-ingress"
|
||||
dnsNames: [
|
||||
"istio-ingress",
|
||||
"istio-ingress.\(Namespace)",
|
||||
"istio-ingress.\(Namespace).svc",
|
||||
"istio-ingress.\(Namespace).svc.cluster.local",
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package holos
|
||||
|
||||
// Refer to https://cert-manager.io/docs/configuration/selfsigned/#bootstrapping-ca-issuers
|
||||
|
||||
let Namespace = "cert-manager"
|
||||
|
||||
spec: components: KubernetesObjectsList: [
|
||||
#KubernetesObjects & {
|
||||
metadata: name: "prod-platform-issuer"
|
||||
|
||||
_dependsOn: "prod-mesh-certmanager": _
|
||||
apiObjectMap: OBJECTS.apiObjectMap
|
||||
},
|
||||
]
|
||||
|
||||
let SelfSigned = "platform-selfsigned"
|
||||
let PlatformIssuer = "platform-issuer"
|
||||
|
||||
let OBJECTS = #APIObjects & {
|
||||
apiObjects: {
|
||||
ClusterIssuer: {
|
||||
"\(SelfSigned)": #ClusterIssuer & {
|
||||
metadata: name: SelfSigned
|
||||
spec: selfSigned: {}
|
||||
}
|
||||
}
|
||||
Certificate: {
|
||||
"\(PlatformIssuer)": #Certificate & {
|
||||
metadata: name: PlatformIssuer
|
||||
metadata: namespace: Namespace
|
||||
spec: {
|
||||
duration: "999999h"
|
||||
isCA: true
|
||||
commonName: PlatformIssuer
|
||||
secretName: PlatformIssuer
|
||||
privateKey: algorithm: "ECDSA"
|
||||
privateKey: size: 256
|
||||
issuerRef: {
|
||||
name: SelfSigned
|
||||
kind: "ClusterIssuer"
|
||||
group: "cert-manager.io"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ClusterIssuer: {
|
||||
"\(PlatformIssuer)": #ClusterIssuer & {
|
||||
metadata: name: PlatformIssuer
|
||||
spec: ca: secretName: PlatformIssuer
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
# Platform Issuer
|
||||
|
||||
The platform issuer is a self signed root certificate authority which acts as a private pki for the platform. Used to issue certificates for use internally within the platform in a way that supports multi-cluster communication.
|
||||
|
||||
Refer to [Bootstrapping CA Issuers](https://cert-manager.io/docs/configuration/selfsigned/#bootstrapping-ca-issuers)
|
||||
@@ -1,5 +1,11 @@
|
||||
package holos
|
||||
|
||||
for Project in _Projects {
|
||||
spec: components: resources: (#ProjectTemplate & {project: Project}).provisioner.resources
|
||||
|
||||
// Debugging variable to enable inspecting the project host data:
|
||||
// cue eval --out json -t cluster=provisioner ./platforms/reference/clusters/provisioner/projects/... -e _ProjectHosts.holos > hosts.json
|
||||
let ProjectData = (#ProjectTemplate & {project: Project})
|
||||
_ProjectHosts: "\(Project.name)": ProjectData.ProjectHosts
|
||||
|
||||
spec: components: resources: ProjectData.provisioner.resources
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
package holos
|
||||
|
||||
let Namespace = "dev-holos"
|
||||
let Holos = "holos"
|
||||
|
||||
// spec represents the output provided to holos
|
||||
spec: components: KubernetesObjectsList: [
|
||||
#KubernetesObjects & {
|
||||
metadata: name: "dev-holos-app"
|
||||
apiObjectMap: OBJECTS.apiObjectMap
|
||||
},
|
||||
]
|
||||
|
||||
// OBJECTS represents the kubernetes api objects to manage.
|
||||
let OBJECTS = #APIObjects & {
|
||||
apiObjects: Deployment: holos: {
|
||||
metadata: {
|
||||
name: Holos
|
||||
namespace: Namespace
|
||||
labels: app: Holos
|
||||
}
|
||||
spec: {
|
||||
selector: matchLabels: app: Holos
|
||||
template: metadata: labels: {
|
||||
app: Holos
|
||||
"sidecar.istio.io/inject": "true"
|
||||
}
|
||||
strategy: rollingUpdate: maxSurge: 1
|
||||
strategy: rollingUpdate: maxUnavailable: 0
|
||||
template: {
|
||||
spec: {
|
||||
serviceAccountName: Holos
|
||||
securityContext: seccompProfile: type: "RuntimeDefault"
|
||||
containers: [
|
||||
{
|
||||
name: Holos
|
||||
image: "271053619184.dkr.ecr.us-east-2.amazonaws.com/holos-run/holos-server/holos:0.73.1"
|
||||
imagePullPolicy: "Always"
|
||||
env: [
|
||||
{
|
||||
name: "TZ"
|
||||
value: "America/Los_Angeles"
|
||||
},
|
||||
{
|
||||
name: "DATABASE_URL"
|
||||
valueFrom: secretKeyRef: {
|
||||
key: "uri"
|
||||
name: "holos-pguser-holos"
|
||||
}
|
||||
},
|
||||
]
|
||||
ports: [
|
||||
{
|
||||
containerPort: 3000
|
||||
name: "http"
|
||||
protocol: "TCP"
|
||||
},
|
||||
]
|
||||
securityContext: capabilities: drop: ["ALL"]
|
||||
securityContext: allowPrivilegeEscalation: false
|
||||
securityContext: runAsNonRoot: true
|
||||
resources: limits: {
|
||||
cpu: "0.25"
|
||||
memory: "256Mi"
|
||||
}
|
||||
resources: requests: resources.limits
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
package holos
|
||||
|
||||
let Namespace = "dev-holos"
|
||||
let Holos = "holos"
|
||||
|
||||
// spec represents the output provided to holos
|
||||
spec: components: KubernetesObjectsList: [
|
||||
#KubernetesObjects & {
|
||||
metadata: name: "dev-holos-infra"
|
||||
apiObjectMap: OBJECTS.apiObjectMap
|
||||
},
|
||||
]
|
||||
|
||||
let Metadata = {
|
||||
name: Holos
|
||||
namespace: Namespace
|
||||
labels: app: Holos
|
||||
}
|
||||
|
||||
// OBJECTS represents the kubernetes api objects to manage.
|
||||
let OBJECTS = #APIObjects & {
|
||||
// Postgres
|
||||
// Deployment
|
||||
// VirtualService
|
||||
|
||||
apiObjects: ServiceAccount: holos: {
|
||||
metadata: Metadata
|
||||
imagePullSecrets: [{name: "kube-system-ecr-image-pull-creds"}]
|
||||
}
|
||||
|
||||
apiObjects: PostgresCluster: holos: {
|
||||
apiVersion: "postgres-operator.crunchydata.com/v1beta1"
|
||||
metadata: Metadata
|
||||
spec: {
|
||||
image: "registry.developers.crunchydata.com/crunchydata/crunchy-postgres:ubi8-16.1-0"
|
||||
instances: [{
|
||||
affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: [{
|
||||
podAffinityTerm: {
|
||||
labelSelector: matchLabels: "postgres-operator.crunchydata.com/cluster": "holos"
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
}
|
||||
weight: 1
|
||||
}]
|
||||
dataVolumeClaimSpec: {
|
||||
accessModes: ["ReadWriteOnce"]
|
||||
resources: requests: storage: "1Gi"
|
||||
}
|
||||
name: "db"
|
||||
replicas: 1
|
||||
}]
|
||||
port: 5432
|
||||
postgresVersion: 16
|
||||
users: [{
|
||||
databases: ["holos"]
|
||||
name: "holos"
|
||||
options: "SUPERUSER"
|
||||
}]
|
||||
backups: pgbackrest: {
|
||||
global: {
|
||||
"archive-async": "y"
|
||||
"archive-push-queue-max": "100MiB"
|
||||
"spool-path": "/pgdata/backups"
|
||||
}
|
||||
image: "registry.developers.crunchydata.com/crunchydata/crunchy-pgbackrest:ubi8-2.47-2"
|
||||
repos: [{
|
||||
name: "repo1"
|
||||
volume: volumeClaimSpec: {
|
||||
accessModes: ["ReadWriteOnce"]
|
||||
resources: requests: storage: "1Gi"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
apiObjects: Service: holos: {
|
||||
apiVersion: "v1"
|
||||
metadata: Metadata
|
||||
spec: {
|
||||
type: "ClusterIP"
|
||||
selector: app: "holos"
|
||||
ports: [{
|
||||
appProtocol: "http2"
|
||||
name: "http"
|
||||
port: 3000
|
||||
protocol: "TCP"
|
||||
targetPort: 3000
|
||||
}, {
|
||||
appProtocol: "http"
|
||||
name: "metrics"
|
||||
port: 9090
|
||||
protocol: "TCP"
|
||||
targetPort: 9090
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
apiObjects: VirtualService: holos: {
|
||||
apiVersion: "networking.istio.io/v1beta1"
|
||||
metadata: Metadata
|
||||
spec: {
|
||||
gateways: ["istio-ingress/default"]
|
||||
hosts: [
|
||||
"app.dev.holos.run",
|
||||
"app.dev.\(#ClusterName).holos.run",
|
||||
]
|
||||
http: [{
|
||||
match: [{
|
||||
uri: prefix: "/ui"
|
||||
}]
|
||||
name: "ui"
|
||||
route: [{
|
||||
destination: {
|
||||
host: "holos"
|
||||
port: number: 3000
|
||||
}
|
||||
}]
|
||||
}, {
|
||||
name: "api"
|
||||
route: [{
|
||||
destination: {
|
||||
host: "holos"
|
||||
port: number: 3000
|
||||
}
|
||||
}]
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package holos
|
||||
|
||||
// Platform level definition of a project.
|
||||
#Project: {
|
||||
name: string
|
||||
|
||||
// All projects have at least a prod and dev environment and stage.
|
||||
|
||||
// Omit the prod stage segment from hostnames. foo.holos.run not foo.prod.holos.run
|
||||
stages: prod: stageSegments: []
|
||||
environments: prod: stage: "prod"
|
||||
// Omit the prod env segment from hostnames. foo.holos.run not prod.foo.holos.run
|
||||
environments: prod: envSegments: []
|
||||
|
||||
stages: dev: _
|
||||
environments: dev: stage: "dev"
|
||||
// Omit the dev env segment from hostnames. foo.dev.holos.run not dev.foo.dev.holos.run
|
||||
environments: dev: envSegments: []
|
||||
|
||||
// environments share the stage segments of their stage.
|
||||
environments: [_]: {
|
||||
stage: string
|
||||
stageSegments: stages[stage].stageSegments
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
package holos
|
||||
143
docs/examples/project-hosts.cue
Normal file
143
docs/examples/project-hosts.cue
Normal file
@@ -0,0 +1,143 @@
|
||||
package holos
|
||||
|
||||
import "strings"
|
||||
|
||||
// #ProjectHosts represents all of the hosts associated with the project
|
||||
// organized for use in Certificates, Gateways, VirtualServices.
|
||||
#ProjectHosts: {
|
||||
project: #Project
|
||||
|
||||
// Hosts map key fqdn to host to reduce into structs organized by stage,
|
||||
// canonical name, etc... The flat nature and long list of properties is
|
||||
// intended to make it straight forward to derive another struct for Gateways,
|
||||
// VirtualServices, Certificates, AuthProxy cookie domains, etc...
|
||||
Hosts: {
|
||||
for Env in project.environments {
|
||||
for Host in project.hosts {
|
||||
// Global hostname, e.g. app.holos.run
|
||||
let CertInfo = (#MakeCertInfo & {
|
||||
host: Host
|
||||
env: Env
|
||||
domain: project.domain
|
||||
clusterMap: project.clusters
|
||||
}).CertInfo
|
||||
|
||||
"\(CertInfo.fqdn)": CertInfo
|
||||
|
||||
// Cluster hostname, e.g. app.east1.holos.run, app.west1.holos.run
|
||||
for Cluster in project.clusters {
|
||||
let CertInfo = (#MakeCertInfo & {
|
||||
host: Host
|
||||
env: Env
|
||||
domain: project.domain
|
||||
cluster: Cluster.name
|
||||
clusterMap: project.clusters
|
||||
}).CertInfo
|
||||
|
||||
"\(CertInfo.fqdn)": CertInfo
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// #MakeCertInfo provides dns info for a certificate
|
||||
// Refer to: https://github.com/holos-run/holos/issues/66#issuecomment-2027562626
|
||||
#MakeCertInfo: {
|
||||
host: #Host
|
||||
env: #Environment
|
||||
domain: string
|
||||
cluster: string
|
||||
clusterMap: #ClusterMap
|
||||
|
||||
let Stage = #StageInfo & {name: env.stage, project: env.project}
|
||||
let Env = env
|
||||
|
||||
// DNS segments from left to right.
|
||||
let EnvSegments = env.envSegments
|
||||
|
||||
WildcardSegments: [...string]
|
||||
if len(env.envSegments) > 0 {
|
||||
WildcardSegments: ["*"]
|
||||
}
|
||||
|
||||
let HostSegments = [host.name]
|
||||
|
||||
let StageSegments = env.stageSegments
|
||||
|
||||
ClusterSegments: [...string]
|
||||
if cluster != _|_ {
|
||||
ClusterSegments: [cluster]
|
||||
}
|
||||
|
||||
let DomainSegments = [domain]
|
||||
|
||||
// Assemble the segments
|
||||
|
||||
let FQDN = EnvSegments + HostSegments + StageSegments + ClusterSegments + DomainSegments
|
||||
let WILDCARD = WildcardSegments + HostSegments + StageSegments + ClusterSegments + DomainSegments
|
||||
let CANONICAL = HostSegments + StageSegments + DomainSegments
|
||||
|
||||
CertInfo: #CertInfo & {
|
||||
fqdn: strings.Join(FQDN, ".")
|
||||
wildcard: strings.Join(WILDCARD, ".")
|
||||
canonical: strings.Join(CANONICAL, ".")
|
||||
|
||||
project: name: Env.project
|
||||
stage: #StageOrEnvRef & {
|
||||
name: Stage.name
|
||||
slug: Stage.slug
|
||||
namespace: Stage.namespace
|
||||
}
|
||||
env: #StageOrEnvRef & {
|
||||
name: Env.name
|
||||
slug: Env.slug
|
||||
namespace: Env.namespace
|
||||
}
|
||||
|
||||
if cluster != _|_ {
|
||||
// Host is valid on a single cluster.
|
||||
clusters: "\(cluster)": _
|
||||
}
|
||||
|
||||
if cluster == _|_ {
|
||||
// Host is valid on all project clusters.
|
||||
clusters: clusterMap
|
||||
}
|
||||
|
||||
NoAuthorizationPolicy: host.NoAuthorizationPolicy
|
||||
}
|
||||
}
|
||||
|
||||
// #CertInfo defines the attributes associated with a fully qualfied domain name
|
||||
#CertInfo: {
|
||||
// fqdn is the fully qualified domain name, never a wildcard.
|
||||
fqdn: string
|
||||
// canonical is the canonical name this name may be an alternate name for.
|
||||
canonical: string
|
||||
// wildcard may replace the left most segment fqdn with a wildcard to consolidate cert dnsNames. If not a wildcad, must be fqdn
|
||||
wildcard: string
|
||||
|
||||
// Project, stage and env attributes for mapping and collecting.
|
||||
project: name: string
|
||||
|
||||
stage: #StageOrEnvRef
|
||||
env: #StageOrEnvRef
|
||||
|
||||
// clusters represents the cluster names the fqdn is valid on.
|
||||
clusters: #ClusterMap
|
||||
// hosts are always valid on the provisioner cluster
|
||||
clusters: provisioner: _
|
||||
|
||||
// NoAuthorizationPolicy excludes the host from the auth proxy integrated with
|
||||
// the default ingress Gateway.
|
||||
NoAuthorizationPolicy: true | *false
|
||||
}
|
||||
|
||||
#ClusterMap: [Name=string]: #Cluster & {name: Name}
|
||||
|
||||
#StageOrEnvRef: {
|
||||
name: string
|
||||
slug: string
|
||||
namespace: string
|
||||
}
|
||||
45
docs/examples/project-template-provisioner-certs.cue
Normal file
45
docs/examples/project-template-provisioner-certs.cue
Normal file
@@ -0,0 +1,45 @@
|
||||
package holos
|
||||
|
||||
#ProjectTemplate: {
|
||||
project: _
|
||||
GatewayServers: _
|
||||
|
||||
// Sort GatewayServers by the tls credentialName to issue wildcards
|
||||
let GatewayCerts = {
|
||||
for FQDN, Server in GatewayServers {
|
||||
let CertInfo = Server._CertInfo
|
||||
|
||||
// Sort into stage for the holos components, e.g. prod-iam-certs, dev-iam-certs
|
||||
"\(CertInfo.stage.slug)": {
|
||||
"\(Server.tls.credentialName)": #Certificate & {
|
||||
|
||||
// Store the dnsNames in a struct so they can be collected into a list
|
||||
_dnsNames: "\(CertInfo.wildcard)": CertInfo.wildcard
|
||||
|
||||
metadata: name: CertInfo.canonical & Server.tls.credentialName
|
||||
metadata: namespace: "istio-ingress"
|
||||
spec: {
|
||||
commonName: CertInfo.canonical
|
||||
secretName: CertInfo.canonical & Server.tls.credentialName
|
||||
dnsNames: [for x in _dnsNames {x}]
|
||||
issuerRef: {
|
||||
kind: "ClusterIssuer"
|
||||
name: "letsencrypt"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Resources to be managed on the provisioner cluster.
|
||||
provisioner: resources: {
|
||||
for stage in project.stages {
|
||||
"\(stage.slug)-certs": #KubernetesObjects & {
|
||||
apiObjectMap: (#APIObjects & {
|
||||
apiObjects: Certificate: GatewayCerts[stage.slug]
|
||||
}).apiObjectMap
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,87 +1,77 @@
|
||||
package holos
|
||||
|
||||
import "encoding/yaml"
|
||||
import (
|
||||
h "github.com/holos-run/holos/api/v1alpha1"
|
||||
"encoding/yaml"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Platform level definition of a project.
|
||||
#Project: {
|
||||
name: string
|
||||
// let SourceLoc = "project-template.cue"
|
||||
|
||||
// All projects have at least a prod environment and stage.
|
||||
stages: prod: stageSegments: []
|
||||
environments: prod: stage: "prod"
|
||||
environments: prod: envSegments: []
|
||||
stages: dev: _
|
||||
environments: dev: stage: "dev"
|
||||
environments: dev: envSegments: []
|
||||
// Ensure at least the project name is a short hostname. Additional may be added.
|
||||
hosts: (name): _
|
||||
#ProjectTemplate: {
|
||||
project: #Project
|
||||
|
||||
// environments share the stage segments of their stage.
|
||||
environments: [_]: {
|
||||
stage: string
|
||||
stageSegments: stages[stage].stageSegments
|
||||
// workload cluster resources
|
||||
workload: resources: [Name=_]: h.#KubernetesObjects & {
|
||||
metadata: name: Name
|
||||
}
|
||||
|
||||
// provisioner cluster resources
|
||||
provisioner: resources: [Name=_]: h.#KubernetesObjects & {
|
||||
metadata: name: Name
|
||||
}
|
||||
}
|
||||
|
||||
// Reference Platform Project Template
|
||||
#ProjectTemplate: {
|
||||
project: #Project
|
||||
let Project = project
|
||||
|
||||
// GatewayServers maps Gateway spec.servers #GatewayServer values indexed by stage then name.
|
||||
let GatewayServers = {
|
||||
// Initialize all stages, even if they have no environments.
|
||||
for stage in project.stages {
|
||||
(stage.name): {}
|
||||
}
|
||||
// ProjectHosts represents all of the hosts associated with a project indexed
|
||||
// by FQDN with #CertInfo values. Slice and dice this struct as needed to
|
||||
// work with hosts in the platform.
|
||||
ProjectHosts: (#ProjectHosts & {project: Project}).Hosts
|
||||
|
||||
// For each stage, construct entries for the Gateway spec.servers.hosts field.
|
||||
for env in project.environments {
|
||||
(env.stage): {
|
||||
let Env = env
|
||||
let Stage = project.stages[env.stage]
|
||||
for host in (#EnvHosts & {project: Project, env: Env}).hosts {
|
||||
(host.name): #GatewayServer & {
|
||||
hosts: [
|
||||
"\(env.namespace)/\(host.name)",
|
||||
// Allow the authproxy VirtualService to match the project.authProxyPrefix path.
|
||||
"\(Stage.namespace)/\(host.name)",
|
||||
]
|
||||
port: host.port
|
||||
tls: credentialName: host.name
|
||||
tls: mode: "SIMPLE"
|
||||
// GatewayServers maps Gateway spec.servers #GatewayServer values indexed by stage then name.
|
||||
GatewayServers: {
|
||||
for FQDN, Host in ProjectHosts {
|
||||
// If the host is valid on the cluster being rendered
|
||||
if Host.clusters[#ClusterName] != _|_ {
|
||||
"\(FQDN)": #GatewayServer & {
|
||||
_CertInfo: Host
|
||||
hosts: [
|
||||
"\(Host.env.namespace)/\(FQDN)",
|
||||
// Allow the authproxy VirtualService to match the project.authProxyPrefix path.
|
||||
"\(Host.stage.namespace)/\(FQDN)",
|
||||
]
|
||||
port: {
|
||||
// NOTE: port names in servers must be unique: duplicate name https
|
||||
name: "https-" + strings.Replace(FQDN, ".", "-", -1)
|
||||
number: 443
|
||||
protocol: "HTTPS"
|
||||
}
|
||||
tls: credentialName: Host.canonical
|
||||
tls: mode: "SIMPLE"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ClusterGatewayServers provides a struct of Gateway servers for the current cluster.
|
||||
// ClusterDefaultGatewayServers provides a struct of Gateway servers for the current cluster.
|
||||
// This is intended for Gateway/default to add all servers to the default gateway.
|
||||
ClusterGatewayServers: {
|
||||
ClusterDefaultGatewayServers: {
|
||||
if project.clusters[#ClusterName] != _|_ {
|
||||
for Stage in project.stages {
|
||||
for server in GatewayServers[Stage.name] {
|
||||
(server.port.name): server
|
||||
}
|
||||
}
|
||||
GatewayServers
|
||||
}
|
||||
}
|
||||
|
||||
workload: resources: {
|
||||
// Provide resources only if the project is managed on --cluster-name
|
||||
// Provide resources only if the project is managed on the cluster specified
|
||||
// by --cluster-name
|
||||
if project.clusters[#ClusterName] != _|_ {
|
||||
for stage in project.stages {
|
||||
let Stage = stage
|
||||
|
||||
// Istio Gateway
|
||||
"\(stage.slug)-gateway": #KubernetesObjects & {
|
||||
apiObjectMap: (#APIObjects & {
|
||||
for host in GatewayServers[stage.name] {
|
||||
apiObjects: ExternalSecret: (host.tls.credentialName): metadata: namespace: "istio-ingress"
|
||||
}
|
||||
}).apiObjectMap
|
||||
}
|
||||
|
||||
// Manage auth-proxy in each stage
|
||||
if project.features.authproxy.enabled {
|
||||
"\(stage.slug)-authproxy": #KubernetesObjects & {
|
||||
@@ -114,90 +104,6 @@ import "encoding/yaml"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provisioner: resources: {
|
||||
for stage in project.stages {
|
||||
"\(stage.slug)-certs": #KubernetesObjects & {
|
||||
apiObjectMap: (#APIObjects & {
|
||||
for host in GatewayServers[stage.name] {
|
||||
let CN = host.tls.credentialName
|
||||
apiObjects: Certificate: (CN): #Certificate & {
|
||||
metadata: name: CN
|
||||
metadata: namespace: "istio-ingress"
|
||||
spec: {
|
||||
commonName: CN
|
||||
dnsNames: [CN]
|
||||
secretName: CN
|
||||
issuerRef: {
|
||||
kind: "ClusterIssuer"
|
||||
name: "letsencrypt"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}).apiObjectMap
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let HTTPBIN = {
|
||||
name: string | *"httpbin"
|
||||
project: #Project
|
||||
env: #Environment
|
||||
let Name = name
|
||||
let Stage = project.stages[env.stage]
|
||||
|
||||
let Metadata = {
|
||||
name: Name
|
||||
namespace: env.namespace
|
||||
labels: app: name
|
||||
}
|
||||
let Labels = {
|
||||
"app.kubernetes.io/name": Name
|
||||
"app.kubernetes.io/instance": env.slug
|
||||
"app.kubernetes.io/part-of": env.project
|
||||
"security.holos.run/authproxy": Stage.extAuthzProviderName
|
||||
}
|
||||
|
||||
apiObjects: {
|
||||
Deployment: (Name): #Deployment & {
|
||||
metadata: Metadata
|
||||
|
||||
spec: selector: matchLabels: Metadata.labels
|
||||
spec: template: {
|
||||
metadata: labels: Metadata.labels & #IstioSidecar & Labels
|
||||
spec: securityContext: seccompProfile: type: "RuntimeDefault"
|
||||
spec: containers: [{
|
||||
name: Name
|
||||
image: "quay.io/holos/mccutchen/go-httpbin"
|
||||
ports: [{containerPort: 8080}]
|
||||
securityContext: {
|
||||
seccompProfile: type: "RuntimeDefault"
|
||||
allowPrivilegeEscalation: false
|
||||
runAsNonRoot: true
|
||||
runAsUser: 8192
|
||||
runAsGroup: 8192
|
||||
capabilities: drop: ["ALL"]
|
||||
}}]
|
||||
}
|
||||
}
|
||||
Service: (Name): #Service & {
|
||||
metadata: Metadata
|
||||
spec: selector: Metadata.labels
|
||||
spec: ports: [
|
||||
{port: 80, targetPort: 8080, protocol: "TCP", name: "http"},
|
||||
]
|
||||
}
|
||||
VirtualService: (Name): #VirtualService & {
|
||||
metadata: Metadata
|
||||
let Project = project
|
||||
let Env = env
|
||||
spec: hosts: [for host in (#EnvHosts & {project: Project, env: Env}).hosts {host.name}]
|
||||
spec: gateways: ["istio-ingress/default"]
|
||||
spec: http: [{route: [{destination: host: Name}]}]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AUTHPROXY configures one oauth2-proxy deployment for each host in each stage of a project. Multiple deployments per stage are used to narrow down the cookie domain.
|
||||
@@ -462,6 +368,65 @@ let AUTHPROXY = {
|
||||
}
|
||||
}
|
||||
|
||||
let HTTPBIN = {
|
||||
name: string | *"httpbin"
|
||||
project: #Project
|
||||
env: #Environment
|
||||
let Name = name
|
||||
let Stage = project.stages[env.stage]
|
||||
|
||||
let Metadata = {
|
||||
name: Name
|
||||
namespace: env.namespace
|
||||
labels: app: name
|
||||
}
|
||||
let Labels = {
|
||||
"app.kubernetes.io/name": Name
|
||||
"app.kubernetes.io/instance": env.slug
|
||||
"app.kubernetes.io/part-of": env.project
|
||||
"security.holos.run/authproxy": Stage.extAuthzProviderName
|
||||
}
|
||||
|
||||
apiObjects: {
|
||||
Deployment: (Name): #Deployment & {
|
||||
metadata: Metadata
|
||||
|
||||
spec: selector: matchLabels: Metadata.labels
|
||||
spec: template: {
|
||||
metadata: labels: Metadata.labels & #IstioSidecar & Labels
|
||||
spec: securityContext: seccompProfile: type: "RuntimeDefault"
|
||||
spec: containers: [{
|
||||
name: Name
|
||||
image: "quay.io/holos/mccutchen/go-httpbin"
|
||||
ports: [{containerPort: 8080}]
|
||||
securityContext: {
|
||||
seccompProfile: type: "RuntimeDefault"
|
||||
allowPrivilegeEscalation: false
|
||||
runAsNonRoot: true
|
||||
runAsUser: 8192
|
||||
runAsGroup: 8192
|
||||
capabilities: drop: ["ALL"]
|
||||
}}]
|
||||
}
|
||||
}
|
||||
Service: (Name): #Service & {
|
||||
metadata: Metadata
|
||||
spec: selector: Metadata.labels
|
||||
spec: ports: [
|
||||
{port: 80, targetPort: 8080, protocol: "TCP", name: "http"},
|
||||
]
|
||||
}
|
||||
VirtualService: (Name): #VirtualService & {
|
||||
metadata: Metadata
|
||||
let Project = project
|
||||
let Env = env
|
||||
spec: hosts: [for host in (#EnvHosts & {project: Project, env: Env}).hosts {host.name}]
|
||||
spec: gateways: ["istio-ingress/default"]
|
||||
spec: http: [{route: [{destination: host: Name}]}]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AUTHPOLICY configures the baseline AuthorizationPolicy and RequestAuthentication policy for each stage of each project.
|
||||
let AUTHPOLICY = {
|
||||
project: #Project
|
||||
@@ -1,12 +1,12 @@
|
||||
package holos
|
||||
|
||||
import h "github.com/holos-run/holos/api/v1alpha1"
|
||||
|
||||
import "strings"
|
||||
|
||||
// #Projects is a map of all the projects in the platform.
|
||||
#Projects: [Name=_]: #Project & {name: Name}
|
||||
|
||||
_Projects: #Projects
|
||||
|
||||
// The platform project is required and where platform services reside. ArgoCD, Grafana, Prometheus, etc...
|
||||
#Projects: platform: _
|
||||
|
||||
@@ -59,7 +59,7 @@ import "strings"
|
||||
}
|
||||
}
|
||||
|
||||
// features is YAGNI maybe?
|
||||
// Thes are useful to enable / disable.
|
||||
features: [Name=string]: #Feature & {name: Name}
|
||||
features: authproxy: _
|
||||
features: httpbin: _
|
||||
@@ -68,8 +68,13 @@ import "strings"
|
||||
// #Cluster defines a cluster
|
||||
#Cluster: name: string
|
||||
|
||||
// #Host defines a short hostname
|
||||
#Host: name: string
|
||||
#Host: {
|
||||
// #Host defines a short hostname
|
||||
name: string
|
||||
// NoAuthorizationPolicy excludes the host from the auth proxy integrated with
|
||||
// the default ingress Gateway.
|
||||
NoAuthorizationPolicy: true | *false
|
||||
}
|
||||
|
||||
#Environment: {
|
||||
// name uniquely identifies the environment within the scope of the project.
|
||||
@@ -91,15 +96,25 @@ import "strings"
|
||||
name: string
|
||||
cluster?: string
|
||||
clusterSegments: [...string]
|
||||
wildcard: true | *false
|
||||
if cluster != _|_ {
|
||||
clusterSegments: [cluster]
|
||||
}
|
||||
let SEGMENTS = envSegments + [name] + stageSegments + clusterSegments + [#Platform.org.domain]
|
||||
_EnvSegments: [...string]
|
||||
if wildcard {
|
||||
if len(envSegments) > 0 {
|
||||
_EnvSegments: ["*"]
|
||||
}
|
||||
}
|
||||
if !wildcard {
|
||||
_EnvSegments: envSegments
|
||||
}
|
||||
let SEGMENTS = _EnvSegments + [name] + stageSegments + clusterSegments + [_Projects[project].domain]
|
||||
let NAMESEGMENTS = ["https"] + SEGMENTS
|
||||
host: {
|
||||
name: strings.Join(SEGMENTS, ".")
|
||||
port: {
|
||||
name: strings.Replace(strings.Join(NAMESEGMENTS, "-"), ".", "-", -1)
|
||||
name: strings.Replace(strings.Replace(strings.Join(NAMESEGMENTS, "-"), ".", "-", -1), "*", "wildcard", -1)
|
||||
number: 443
|
||||
protocol: "HTTPS"
|
||||
}
|
||||
@@ -107,17 +122,26 @@ import "strings"
|
||||
}
|
||||
}
|
||||
|
||||
#Stage: {
|
||||
#StageInfo: {
|
||||
name: string
|
||||
project: string
|
||||
slug: "\(name)-\(project)"
|
||||
// namespace is the system namespace for the project stage
|
||||
namespace: "\(name)-\(project)-system"
|
||||
}
|
||||
|
||||
#Stage: {
|
||||
#StageInfo
|
||||
name: string
|
||||
project: string
|
||||
namespace: string
|
||||
slug: string
|
||||
|
||||
// Manage a system namespace for each stage
|
||||
namespaces: [Name=_]: name: Name
|
||||
namespaces: (namespace): _
|
||||
namespaces: "\(namespace)": _
|
||||
// stageSegments are the stage portion of the dns segments
|
||||
stageSegments: [...string] | *[name]
|
||||
stageSegments: [] | *[name]
|
||||
// authProxyClientID is the ClientID registered with the oidc issuer.
|
||||
authProxyClientID: string
|
||||
// extAuthzProviderName is the provider name in the mesh config
|
||||
@@ -130,20 +154,6 @@ import "strings"
|
||||
enabled: true | *false
|
||||
}
|
||||
|
||||
#ProjectTemplate: {
|
||||
project: #Project
|
||||
|
||||
// workload cluster resources
|
||||
workload: resources: [Name=_]: h.#KubernetesObjects & {
|
||||
metadata: name: Name
|
||||
}
|
||||
|
||||
// provisioner cluster resources
|
||||
provisioner: resources: [Name=_]: h.#KubernetesObjects & {
|
||||
metadata: name: Name
|
||||
}
|
||||
}
|
||||
|
||||
// #EnvHosts provides hostnames given a project and environment.
|
||||
// Refer to https://github.com/holos-run/holos/issues/66#issuecomment-2027562626
|
||||
#EnvHosts: {
|
||||
@@ -166,7 +176,7 @@ import "strings"
|
||||
}
|
||||
|
||||
// #StageDomains provides hostnames given a project and stage. Primarily for the
|
||||
// auth proxy.
|
||||
// auth proxy cookie domains.
|
||||
// Refer to https://github.com/holos-run/holos/issues/66#issuecomment-2027562626
|
||||
#StageDomains: {
|
||||
// names are the leading prefix names to create hostnames for.
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
crt "cert-manager.io/certificate/v1"
|
||||
gw "networking.istio.io/gateway/v1beta1"
|
||||
vs "networking.istio.io/virtualservice/v1beta1"
|
||||
dr "networking.istio.io/destinationrule/v1beta1"
|
||||
ra "security.istio.io/requestauthentication/v1"
|
||||
ap "security.istio.io/authorizationpolicy/v1"
|
||||
pg "postgres-operator.crunchydata.com/postgrescluster/v1beta1"
|
||||
@@ -77,7 +78,9 @@ _apiVersion: "holos.run/v1alpha1"
|
||||
#Job: #NamespaceObject & batchv1.#Job
|
||||
#CronJob: #NamespaceObject & batchv1.#CronJob
|
||||
#Deployment: #NamespaceObject & appsv1.#Deployment
|
||||
#StatefulSet: #NamespaceObject & appsv1.#StatefulSet
|
||||
#VirtualService: #NamespaceObject & vs.#VirtualService
|
||||
#DestinationRule: #NamespaceObject & dr.#DestinationRule
|
||||
#RequestAuthentication: #NamespaceObject & ra.#RequestAuthentication
|
||||
#AuthorizationPolicy: #NamespaceObject & ap.#AuthorizationPolicy
|
||||
#Certificate: #NamespaceObject & crt.#Certificate
|
||||
|
||||
123
go.mod
123
go.mod
@@ -5,10 +5,12 @@ go 1.21.5
|
||||
require (
|
||||
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.33.0-20240401165935-b983156c5e99.1
|
||||
connectrpc.com/connect v1.16.0
|
||||
connectrpc.com/grpcreflect v1.2.0
|
||||
connectrpc.com/validate v0.1.0
|
||||
cuelang.org/go v0.8.0
|
||||
entgo.io/ent v0.13.1
|
||||
github.com/bufbuild/buf v1.30.1
|
||||
github.com/choria-io/machine-room v0.0.0-20240417064836-c604da2f005e
|
||||
github.com/coreos/go-oidc/v3 v3.10.0
|
||||
github.com/fullstorydev/grpcurl v1.9.1
|
||||
github.com/go-jose/go-jose/v3 v3.0.3
|
||||
@@ -17,7 +19,7 @@ require (
|
||||
github.com/jackc/pgx/v5 v5.5.5
|
||||
github.com/lmittmann/tint v1.0.4
|
||||
github.com/mattn/go-isatty v0.0.20
|
||||
github.com/mattn/go-runewidth v0.0.9
|
||||
github.com/mattn/go-runewidth v0.0.15
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
github.com/prometheus/client_golang v1.19.0
|
||||
github.com/rogpeppe/go-internal v1.12.0
|
||||
@@ -25,8 +27,8 @@ require (
|
||||
github.com/spf13/cobra v1.8.0
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/stretchr/testify v1.9.0
|
||||
golang.org/x/net v0.22.0
|
||||
golang.org/x/tools v0.19.0
|
||||
golang.org/x/net v0.24.0
|
||||
golang.org/x/tools v0.20.0
|
||||
google.golang.org/protobuf v1.33.1-0.20240408130810-98873a205002
|
||||
honnef.co/go/tools v0.4.7
|
||||
k8s.io/api v0.29.2
|
||||
@@ -43,25 +45,42 @@ require (
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
connectrpc.com/otelconnect v0.7.0 // indirect
|
||||
cuelabs.dev/go/oci/ociregistry v0.0.0-20240314152124-224736b49f2e // indirect
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
|
||||
github.com/BurntSushi/toml v1.2.1 // indirect
|
||||
github.com/BurntSushi/toml v1.3.2 // indirect
|
||||
github.com/Freman/eventloghook v0.0.0-20191003051739-e4d803b6b48b // indirect
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Masterminds/semver v1.5.0 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.2.1 // indirect
|
||||
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||
github.com/OneOfOne/xxhash v1.2.8 // indirect
|
||||
github.com/achanda/go-sysctl v0.0.0-20160222034550-6be7678c45d2 // indirect
|
||||
github.com/agext/levenshtein v1.2.1 // indirect
|
||||
github.com/agnivade/levenshtein v1.1.1 // indirect
|
||||
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/blang/semver/v4 v4.0.0 // indirect
|
||||
github.com/bufbuild/protocompile v0.10.0 // indirect
|
||||
github.com/bufbuild/protovalidate-go v0.6.0 // indirect
|
||||
github.com/bufbuild/protoyaml-go v0.1.8 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/cheekybits/genny v1.0.0 // indirect
|
||||
github.com/choria-io/fisk v0.6.2 // indirect
|
||||
github.com/choria-io/go-choria v0.28.1-0.20240416190746-b3bf9c7d5a45 // indirect
|
||||
github.com/choria-io/go-updater v0.1.0 // indirect
|
||||
github.com/choria-io/stream-replicator v0.8.3-0.20230503130504-86152f798aec // indirect
|
||||
github.com/choria-io/tokens v0.0.4-0.20240316144214-a929d9325d48 // indirect
|
||||
github.com/cloudevents/sdk-go/v2 v2.15.2 // indirect
|
||||
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa // indirect
|
||||
github.com/cockroachdb/apd/v3 v3.2.1 // indirect
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/distribution/reference v0.6.0 // indirect
|
||||
github.com/docker/cli v26.0.0+incompatible // indirect
|
||||
github.com/docker/distribution v2.8.3+incompatible // indirect
|
||||
@@ -75,29 +94,49 @@ require (
|
||||
github.com/envoyproxy/go-control-plane v0.12.0 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.0.4 // indirect
|
||||
github.com/evanphx/json-patch v5.7.0+incompatible // indirect
|
||||
github.com/expr-lang/expr v1.16.4 // indirect
|
||||
github.com/fatih/color v1.16.0 // indirect
|
||||
github.com/felixge/fgprof v0.9.4 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/ghodss/yaml v1.0.0 // indirect
|
||||
github.com/go-chi/chi/v5 v5.0.12 // indirect
|
||||
github.com/go-ini/ini v1.67.0 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.0.1 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
github.com/go-openapi/inflect v0.19.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.20.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
||||
github.com/go-openapi/swag v0.22.4 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||
github.com/gobwas/glob v0.2.3 // indirect
|
||||
github.com/gofrs/uuid/v5 v5.0.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/cel-go v0.20.1 // indirect
|
||||
github.com/google/gnostic-models v0.6.8 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/go-containerregistry v0.19.1 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20240327155427-868f304927ed // indirect
|
||||
github.com/google/pprof v0.0.0-20240416155748-26353dc0451f // indirect
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/google/wire v0.5.0 // indirect
|
||||
github.com/gorilla/mux v1.8.1 // indirect
|
||||
github.com/goss-org/GOnetstat v0.0.0-20230101144325-22be0bd9e64d // indirect
|
||||
github.com/goss-org/go-ps v0.0.0-20230609005227-7b318e6a56e5 // indirect
|
||||
github.com/goss-org/goss v0.4.6 // indirect
|
||||
github.com/gosuri/uilive v0.0.4 // indirect
|
||||
github.com/gosuri/uiprogress v0.0.1 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect
|
||||
github.com/guptarohit/asciigraph v0.7.1 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.13.0 // indirect
|
||||
github.com/hashicorp/logutils v1.0.0 // indirect
|
||||
github.com/huandu/xstrings v1.4.0 // indirect
|
||||
github.com/imdario/mergo v0.3.16 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/int128/listener v1.1.0 // indirect
|
||||
@@ -110,38 +149,81 @@ require (
|
||||
github.com/jhump/protoreflect v1.16.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.17.7 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/klauspost/compress v1.17.8 // indirect
|
||||
github.com/klauspost/pgzip v1.2.6 // indirect
|
||||
github.com/lib/pq v1.10.9 // indirect
|
||||
github.com/looplab/fsm v1.0.1 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20240408141607-282e7b5d6b74 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
|
||||
github.com/miekg/dns v1.1.58 // indirect
|
||||
github.com/miekg/pkcs11 v1.1.1 // indirect
|
||||
github.com/minio/highwayhash v1.0.2 // indirect
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
github.com/moby/sys/mountinfo v0.7.1 // indirect
|
||||
github.com/moby/term v0.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/nats-io/jsm.go v0.1.1 // indirect
|
||||
github.com/nats-io/jwt/v2 v2.5.5 // indirect
|
||||
github.com/nats-io/nats-server/v2 v2.10.14 // indirect
|
||||
github.com/nats-io/nats.go v1.34.1 // indirect
|
||||
github.com/nats-io/nkeys v0.4.7 // indirect
|
||||
github.com/nats-io/nuid v1.0.1 // indirect
|
||||
github.com/ncruces/go-strftime v0.1.9 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.15.0 // indirect
|
||||
github.com/onsi/gomega v1.31.1 // indirect
|
||||
github.com/oleiade/reflections v1.0.1 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.17.1 // indirect
|
||||
github.com/onsi/gomega v1.32.0 // indirect
|
||||
github.com/open-policy-agent/opa v0.63.0 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.0 // indirect
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pkg/profile v1.7.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_model v0.5.0 // indirect
|
||||
github.com/prometheus/common v0.48.0 // indirect
|
||||
github.com/prometheus/procfs v0.12.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.52.3 // indirect
|
||||
github.com/prometheus/procfs v0.13.0 // indirect
|
||||
github.com/protocolbuffers/txtpbfmt v0.0.0-20230328191034-3462fbc510c0 // indirect
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/robfig/cron v1.2.0 // indirect
|
||||
github.com/rs/cors v1.10.1 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/samber/lo v1.39.0 // indirect
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect
|
||||
github.com/segmentio/ksuid v1.0.4 // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.24.3 // indirect
|
||||
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
||||
github.com/shopspring/decimal v1.4.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/spf13/cast v1.6.0 // indirect
|
||||
github.com/stoewer/go-strcase v1.3.0 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/tchap/go-patricia/v2 v2.3.1 // indirect
|
||||
github.com/tidwall/gjson v1.17.1 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.1 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.13 // indirect
|
||||
github.com/tklauser/numcpus v0.7.0 // indirect
|
||||
github.com/vbatts/tar-split v0.11.5 // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
github.com/xlab/tablewriter v0.0.0-20160610135559-80b567a11ad5 // indirect
|
||||
github.com/yashtewari/glob-intersection v0.2.0 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
github.com/zclconf/go-cty v1.8.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
|
||||
go.opentelemetry.io/otel v1.25.0 // indirect
|
||||
@@ -149,18 +231,17 @@ require (
|
||||
go.opentelemetry.io/otel/metric v1.25.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.25.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.25.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.1.0 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/crypto v0.21.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect
|
||||
golang.org/x/crypto v0.22.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect
|
||||
golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a // indirect
|
||||
golang.org/x/mod v0.16.0 // indirect
|
||||
golang.org/x/mod v0.17.0 // indirect
|
||||
golang.org/x/oauth2 v0.18.0 // indirect
|
||||
golang.org/x/sync v0.6.0 // indirect
|
||||
golang.org/x/sys v0.18.0 // indirect
|
||||
golang.org/x/term v0.18.0 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/sys v0.19.0 // indirect
|
||||
golang.org/x/term v0.19.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
google.golang.org/appengine v1.6.8 // indirect
|
||||
|
||||
328
go.sum
328
go.sum
@@ -40,6 +40,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
connectrpc.com/connect v1.16.0 h1:rdtfQjZ0OyFkWPTegBNcH7cwquGAN1WzyJy80oFNibg=
|
||||
connectrpc.com/connect v1.16.0/go.mod h1:XpZAduBQUySsb4/KO5JffORVkDI4B6/EYPi7N8xpNZw=
|
||||
connectrpc.com/grpcreflect v1.2.0 h1:Q6og1S7HinmtbEuBvARLNwYmTbhEGRpHDhqrPNlmK+U=
|
||||
connectrpc.com/grpcreflect v1.2.0/go.mod h1:nwSOKmE8nU5u/CidgHtPYk1PFI3U9ignz7iDMxOYkSY=
|
||||
connectrpc.com/otelconnect v0.7.0 h1:ZH55ZZtcJOTKWWLy3qmL4Pam4RzRWBJFOqTPyAqCXkY=
|
||||
connectrpc.com/otelconnect v0.7.0/go.mod h1:Bt2ivBymHZHqxvo4HkJ0EwHuUzQN6k2l0oH+mp/8nwc=
|
||||
connectrpc.com/validate v0.1.0 h1:r55jirxMK7HO/xZwVHj3w2XkVFarsUM77ZDy367NtH4=
|
||||
@@ -51,24 +53,51 @@ cuelang.org/go v0.8.0/go.mod h1:CoDbYolfMms4BhWUlhD+t5ORnihR7wvjcfgyO9lL5FI=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
entgo.io/ent v0.13.1 h1:uD8QwN1h6SNphdCCzmkMN3feSUzNnVvV/WIkHKMbzOE=
|
||||
entgo.io/ent v0.13.1/go.mod h1:qCEmo+biw3ccBn9OyL4ZK5dfpwg++l1Gxwac5B1206A=
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ=
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
|
||||
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
|
||||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/Freman/eventloghook v0.0.0-20191003051739-e4d803b6b48b h1:IltY1fRcdIshI/c8KOdmaO8P4lBwDXHJYPymMisvvDs=
|
||||
github.com/Freman/eventloghook v0.0.0-20191003051739-e4d803b6b48b/go.mod h1:VGwG8f2pQ8SAFjTSH3PEDmLdlvi0XTd7a4C4AZn+pVw=
|
||||
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
|
||||
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
|
||||
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
||||
github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
|
||||
github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
||||
github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
|
||||
github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
|
||||
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
|
||||
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
|
||||
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s=
|
||||
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w=
|
||||
github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8=
|
||||
github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
|
||||
github.com/achanda/go-sysctl v0.0.0-20160222034550-6be7678c45d2 h1:NYoPVh1XuUB5VBWLXRKoqzQhl4bajIxh+XuURbJ0uwc=
|
||||
github.com/achanda/go-sysctl v0.0.0-20160222034550-6be7678c45d2/go.mod h1:DCNKSpXhum14Y258jSbRmJvcesbzEdBPincz7yJUx3k=
|
||||
github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8=
|
||||
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
||||
github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8=
|
||||
github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
|
||||
github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
|
||||
github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw=
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
|
||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
|
||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
|
||||
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
|
||||
github.com/brutella/hc v1.2.5 h1:P1tHqJtrGngob6Lv5E7RVGlLcdo54X/03Gseo5+soVw=
|
||||
github.com/brutella/hc v1.2.5/go.mod h1:kluioDmG4z8OweN0boeTf08696sH8odlhPDdq3gwuZw=
|
||||
github.com/bufbuild/buf v1.30.1 h1:QFtanwsXodoGFAwzXFXGXpzBkb7N2u8ZDyA3jWB4Pbs=
|
||||
github.com/bufbuild/buf v1.30.1/go.mod h1:7W8DJnj76wQa55EA3z2CmDxS0/nsHh8FqtE00dyDAdA=
|
||||
github.com/bufbuild/protocompile v0.10.0 h1:+jW/wnLMLxaCEG8AX9lD0bQ5v9h1RUiMKOBOT5ll9dM=
|
||||
@@ -77,13 +106,31 @@ github.com/bufbuild/protovalidate-go v0.6.0 h1:Jgs1kFuZ2LHvvdj8SpCLA1W/+pXS8QSM3
|
||||
github.com/bufbuild/protovalidate-go v0.6.0/go.mod h1:1LamgoYHZ2NdIQH0XGczGTc6Z8YrTHjcJVmiBaar4t4=
|
||||
github.com/bufbuild/protoyaml-go v0.1.8 h1:X9QDLfl9uEllh4gsXUGqPanZYCOKzd92uniRtW2OnAQ=
|
||||
github.com/bufbuild/protoyaml-go v0.1.8/go.mod h1:R8vE2+l49bSiIExP4VJpxOXleHE+FDzZ6HVxr3cYunw=
|
||||
github.com/bytecodealliance/wasmtime-go/v3 v3.0.2 h1:3uZCA/BLTIu+DqCfguByNMJa2HVHpXvjfy0Dy7g6fuA=
|
||||
github.com/bytecodealliance/wasmtime-go/v3 v3.0.2/go.mod h1:RnUjnIXxEJcL6BgCvNyzCCRzZcxCgsZCi+RNlvYor5Q=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=
|
||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE=
|
||||
github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ=
|
||||
github.com/choria-io/fisk v0.6.2 h1:Vfvpcv8SD53FHW5cT4u7LStpz/wThwRPQHU7mzv1kMI=
|
||||
github.com/choria-io/fisk v0.6.2/go.mod h1:PajiUZTAotE5zO18eU6UexuPLLv565WOma4dB0ObxRM=
|
||||
github.com/choria-io/go-choria v0.28.1-0.20240416190746-b3bf9c7d5a45 h1:B76eu8PMXr3mAhQl8y7NSsb1/4KCKX4bEDTsKWh7/CQ=
|
||||
github.com/choria-io/go-choria v0.28.1-0.20240416190746-b3bf9c7d5a45/go.mod h1:XLEKGqo1Xmvj69DrSdI0neDGveWJDDQTeHdZgf1zxsI=
|
||||
github.com/choria-io/go-updater v0.1.0 h1:+Pt2ifsDh478T/ldA8fnDwavvH3RTQNn1mkrabVZ5eg=
|
||||
github.com/choria-io/go-updater v0.1.0/go.mod h1:8qj3lwYUC6c0zqsvaKP4pNu8GMHbIr5WGrd5YUWByWw=
|
||||
github.com/choria-io/machine-room v0.0.0-20240417064836-c604da2f005e h1:Kt9CeGRjW/mKQTams+aCUvIAucw3VzEZbKFJvM3pFeE=
|
||||
github.com/choria-io/machine-room v0.0.0-20240417064836-c604da2f005e/go.mod h1:3zCpMS5R2/xOd6Wsep2o0vvAy0eJnfU/ngEptEuJArs=
|
||||
github.com/choria-io/stream-replicator v0.8.3-0.20230503130504-86152f798aec h1:jGTkaDf2kDAlho4Oi6r2x51kzjXpxqhECFTHzTZ/a3w=
|
||||
github.com/choria-io/stream-replicator v0.8.3-0.20230503130504-86152f798aec/go.mod h1:QVvT5tjYSYmvqx585herBk0aK13DS1j/wJVDDWuLFww=
|
||||
github.com/choria-io/tokens v0.0.4-0.20240316144214-a929d9325d48 h1:KyL4w+dxAOfqi4Wds6Fh0632sxBw0YvRqL9fqMziGBI=
|
||||
github.com/choria-io/tokens v0.0.4-0.20240316144214-a929d9325d48/go.mod h1:dEyJo/309e8n141nzx1u82QuXVt6mt42V1Jn9CkJJPs=
|
||||
github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs=
|
||||
github.com/chromedp/chromedp v0.9.2/go.mod h1:LkSXJKONWTCHAfQasKFUZI+mxqS4tZqhmtGzzhLsnLs=
|
||||
github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww=
|
||||
@@ -94,6 +141,8 @@ github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObk
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudevents/sdk-go/v2 v2.15.2 h1:54+I5xQEnI73RBhWHxbI1XJcqOFOVJN85vb41+8mHUc=
|
||||
github.com/cloudevents/sdk-go/v2 v2.15.2/go.mod h1:lL7kSWAE/V8VI4Wh0jbL2v/jvqsm6tjmaQBSvxcv4uE=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe h1:QQ3GSy+MqSHxm/d8nCtnAiZdYFd45cYZPs8vOOIYKfk=
|
||||
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
|
||||
@@ -112,11 +161,20 @@ github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgraph-io/badger/v3 v3.2103.5 h1:ylPa6qzbjYRQMU6jokoj4wzcaweHylt//CH0AKt0akg=
|
||||
github.com/dgraph-io/badger/v3 v3.2103.5/go.mod h1:4MPiseMeDQ3FNCYwRbbcBOGJLf5jsE0PPFzRiKjtcdw=
|
||||
github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8=
|
||||
github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA=
|
||||
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
|
||||
github.com/dgryski/trifles v0.0.0-20220729183022-231ecf6ed548 h1:acdRTG6Vp8kMaN3lVkI49O/BuHjg+GH5i/MJjYZV+BM=
|
||||
github.com/dgryski/trifles v0.0.0-20220729183022-231ecf6ed548/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
|
||||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/docker/cli v26.0.0+incompatible h1:90BKrx1a1HKYpSnnBFR6AgDq/FqkHxwlUyzJVPxD30I=
|
||||
@@ -147,18 +205,32 @@ github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU
|
||||
github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew=
|
||||
github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI=
|
||||
github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/expr-lang/expr v1.16.4 h1:1Mq5RHw5T5jxXMUvyb+eT546mJREm1yFyNHkybYQ81c=
|
||||
github.com/expr-lang/expr v1.16.4/go.mod h1:uCkhfG+x7fcZ5A5sXHKuQ07jGZRl6J0FCAaf2k4PtVQ=
|
||||
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||
github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw=
|
||||
github.com/felixge/fgprof v0.9.4 h1:ocDNwMFlnA0NU0zSB3I52xkO4sFXk80VK9lXjLClu88=
|
||||
github.com/felixge/fgprof v0.9.4/go.mod h1:yKl+ERSa++RYOs32d8K6WEXCB4uXdLls4ZaZPpayhMM=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
|
||||
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
|
||||
github.com/foxcpp/go-mockdns v1.1.0 h1:jI0rD8M0wuYAxL7r/ynTrCQQq0BVqfB99Vgk7DlmewI=
|
||||
github.com/foxcpp/go-mockdns v1.1.0/go.mod h1:IhLeSFGed3mJIAXPH2aiRQB+kqz7oqu8ld2qVbOu7Wk=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fullstorydev/grpcurl v1.9.1 h1:YxX1aCcCc4SDBQfj9uoWcTLe8t4NWrZe1y+mk83BQgo=
|
||||
github.com/fullstorydev/grpcurl v1.9.1/go.mod h1:i8gKLIC6s93WdU3LSmkE5vtsCxyRmihUj5FK1cNW5EM=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s=
|
||||
github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
|
||||
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||
github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k=
|
||||
github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
|
||||
github.com/go-jose/go-jose/v4 v4.0.1 h1:QVEPDE3OluqXBQZDcnNvQrInro2h0e4eqNbnZSWqS6U=
|
||||
@@ -169,6 +241,9 @@ github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
|
||||
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
|
||||
github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4=
|
||||
github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4=
|
||||
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
|
||||
@@ -185,6 +260,8 @@ github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEe
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
||||
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
||||
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
|
||||
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||
github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY=
|
||||
@@ -196,12 +273,18 @@ github.com/gofrs/uuid/v5 v5.0.0 h1:p544++a97kEL+svbcFbCQVM9KFu0Yo25UoISXGNNH9M=
|
||||
github.com/gofrs/uuid/v5 v5.0.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68=
|
||||
github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
@@ -209,6 +292,8 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
@@ -226,10 +311,14 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/cel-go v0.20.1 h1:nDx9r8S3L4pE61eDdt8igGj8rf5kjYR3ILxWIpWNi84=
|
||||
github.com/google/cel-go v0.20.1/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg=
|
||||
github.com/google/flatbuffers v23.3.3+incompatible h1:5PJI/WbJkaMTvpGxsHVKG/LurN/KnWXNyGpwSCDgen0=
|
||||
github.com/google/flatbuffers v23.3.3+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
|
||||
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
|
||||
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
@@ -260,27 +349,53 @@ github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hf
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
|
||||
github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
|
||||
github.com/google/pprof v0.0.0-20240327155427-868f304927ed h1:n8QtJTrwsv3P7dNxPaMeNkMcxvUpqocsHLr8iDLGlQI=
|
||||
github.com/google/pprof v0.0.0-20240327155427-868f304927ed/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
|
||||
github.com/google/pprof v0.0.0-20240416155748-26353dc0451f h1:WpZiq8iqvGjJ3m3wzAVKL6+0vz7VkE79iSy9GII00II=
|
||||
github.com/google/pprof v0.0.0-20240416155748-26353dc0451f/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8=
|
||||
github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/goss-org/GOnetstat v0.0.0-20230101144325-22be0bd9e64d h1:50mlZKtg8BUvBtFs0ioVpSgMMwcKaJefg/2pZ+lQf98=
|
||||
github.com/goss-org/GOnetstat v0.0.0-20230101144325-22be0bd9e64d/go.mod h1:MBdRlloGIbpQVDuH5Gxg3hjqwZBCZsmFqbYPaeR6r0M=
|
||||
github.com/goss-org/go-ps v0.0.0-20230609005227-7b318e6a56e5 h1:NW0Jo4leMIrQxNOyOkBu4yBnygI37m0Ey0EUUgvzr+8=
|
||||
github.com/goss-org/go-ps v0.0.0-20230609005227-7b318e6a56e5/go.mod h1:FYj70SLmogHdTTDGnIVaaK0iczROlsxmoMCwfAUuIE8=
|
||||
github.com/goss-org/goss v0.4.6 h1:WPFGMjlgTBeZqfr4LaGIQCgKf+hX5h0pbNOK3ZuipEA=
|
||||
github.com/goss-org/goss v0.4.6/go.mod h1:VfZhk3KLI6fk4jk5kbrto7iuJMh62wyYp2CLiXZZDXc=
|
||||
github.com/gosuri/uilive v0.0.4 h1:hUEBpQDj8D8jXgtCdBu7sWsy5sbW/5GhuO8KBwJ2jyY=
|
||||
github.com/gosuri/uilive v0.0.4/go.mod h1:V/epo5LjjlDE5RJUcqx8dbw+zc93y5Ya3yg8tfZ74VI=
|
||||
github.com/gosuri/uiprogress v0.0.1 h1:0kpv/XY/qTmFWl/SkaJykZXrBBzwwadmW8fRb7RJSxw=
|
||||
github.com/gosuri/uiprogress v0.0.1/go.mod h1:C1RTYn4Sc7iEyf6j8ft5dyoZ4212h8G1ol9QQluh5+0=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0/go.mod h1:qmOFXW2epJhM0qSnUUYpldc7gVz2KMQwJ/QYCDIa7XU=
|
||||
github.com/guptarohit/asciigraph v0.7.1 h1:K+JWbRc04XEfv8BSZgNuvhCmpbvX4+9NYd/UxXVnAuk=
|
||||
github.com/guptarohit/asciigraph v0.7.1/go.mod h1:dYl5wwK4gNsnFf9Zp+l06rFiDZ5YtXM6x7SRWZ3KGag=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/hashicorp/hcl/v2 v2.13.0 h1:0Apadu1w6M11dyGFxWnmhhcMjkbAiKCv7G1r/2QgCNc=
|
||||
github.com/hashicorp/hcl/v2 v2.13.0/go.mod h1:e4z5nxYlWNPdDSNYX+ph14EvWYMFm3eP0zIUqPc2jr0=
|
||||
github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y=
|
||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=
|
||||
github.com/hinshun/vt10x v0.0.0-20220301184237-5011da428d02 h1:AgcIVYPa6XJnU3phs104wLj8l5GEththEw6+F79YsIY=
|
||||
github.com/hinshun/vt10x v0.0.0-20220301184237-5011da428d02/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=
|
||||
github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU=
|
||||
github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20230524184225-eabc099b10ab/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw=
|
||||
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
|
||||
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
@@ -311,10 +426,12 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg=
|
||||
github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=
|
||||
github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
|
||||
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
@@ -332,20 +449,50 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lmittmann/tint v1.0.4 h1:LeYihpJ9hyGvE0w+K2okPTGUdVLfng1+nDNVR4vWISc=
|
||||
github.com/lmittmann/tint v1.0.4/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE=
|
||||
github.com/looplab/fsm v1.0.1 h1:OEW0ORrIx095N/6lgoGkFkotqH6s7vaFPsgjLAaF5QU=
|
||||
github.com/looplab/fsm v1.0.1/go.mod h1:PmD3fFvQEIsjMEfvZdrCDZ6y8VwKTwWNjlpEr6IKPO4=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/lufia/plan9stats v0.0.0-20240408141607-282e7b5d6b74 h1:1KuuSOy4ZNgW0KA2oYIngXVFhQcXxhLqCVK7cBcldkk=
|
||||
github.com/lufia/plan9stats v0.0.0-20240408141607-282e7b5d6b74/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
|
||||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4=
|
||||
github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY=
|
||||
github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU=
|
||||
github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||
github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g=
|
||||
github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
|
||||
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
|
||||
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
|
||||
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||
github.com/moby/sys/mountinfo v0.7.1 h1:/tTvQaSJRr2FshkhXiIpux6fQ2Zvc4j7tAhMTStAG2g=
|
||||
github.com/moby/sys/mountinfo v0.7.1/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI=
|
||||
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
||||
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@@ -357,19 +504,37 @@ github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/nats-io/jsm.go v0.1.1 h1:6vjllz276SdC+3Fb3XI71p9B6toxkCruuB1K6unQEr0=
|
||||
github.com/nats-io/jsm.go v0.1.1/go.mod h1:cFz5wR1pW0zLFotntS4HA7V8Wm+sf8zpF+iQJHbsS6M=
|
||||
github.com/nats-io/jwt/v2 v2.5.5 h1:ROfXb50elFq5c9+1ztaUbdlrArNFl2+fQWP6B8HGEq4=
|
||||
github.com/nats-io/jwt/v2 v2.5.5/go.mod h1:ZdWS1nZa6WMZfFwwgpEaqBV8EPGVgOTDHN/wTbz0Y5A=
|
||||
github.com/nats-io/nats-server/v2 v2.10.14 h1:98gPJFOAO2vLdM0gogh8GAiHghwErrSLhugIqzRC+tk=
|
||||
github.com/nats-io/nats-server/v2 v2.10.14/go.mod h1:a0TwOVBJZz6Hwv7JH2E4ONdpyFk9do0C18TEwxnHdRk=
|
||||
github.com/nats-io/nats.go v1.34.1 h1:syWey5xaNHZgicYBemv0nohUPPmaLteiBEUT6Q5+F/4=
|
||||
github.com/nats-io/nats.go v1.34.1/go.mod h1:Ubdu4Nh9exXdSz0RVWRFBbRfrbSxOYd26oF0wkWclB8=
|
||||
github.com/nats-io/nkeys v0.4.7 h1:RwNJbbIdYCoClSDNY7QVKZlyb/wfT6ugvFCiKy6vDvI=
|
||||
github.com/nats-io/nkeys v0.4.7/go.mod h1:kqXRgRDPlGy7nGaEDMuYzmiJCIAAWDK0IMBtDmGD0nc=
|
||||
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
|
||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
|
||||
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
||||
github.com/oleiade/reflections v1.0.1 h1:D1XO3LVEYroYskEsoSiGItp9RUxG6jWnCVvrqH0HHQM=
|
||||
github.com/oleiade/reflections v1.0.1/go.mod h1:rdFxbxq4QXVZWj0F+e9jqjDkc7dbp97vkRixKo2JR60=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY=
|
||||
github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM=
|
||||
github.com/onsi/gomega v1.31.1 h1:KYppCUK+bUgAZwHOu7EXVBKyQA6ILvOESHkn/tgoqvo=
|
||||
github.com/onsi/gomega v1.31.1/go.mod h1:y40C95dwAD1Nz36SsEnxvfFe8FFfNxzI5eJ0EYGyAy0=
|
||||
github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8=
|
||||
github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
|
||||
github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk=
|
||||
github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg=
|
||||
github.com/open-policy-agent/opa v0.63.0 h1:ztNNste1v8kH0/vJMJNquE45lRvqwrM5mY9Ctr9xIXw=
|
||||
github.com/open-policy-agent/opa v0.63.0/go.mod h1:9VQPqEfoB2N//AToTxzZ1pVTVPUoF2Mhd64szzjWPpU=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
|
||||
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
|
||||
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
|
||||
@@ -377,21 +542,32 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/profile v1.7.0 h1:hnbDkaNWPCLMO9wGLdBFTIZvzDrDfBM2072E1S9gJkA=
|
||||
github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDjvNo=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU=
|
||||
github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
|
||||
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
|
||||
github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE=
|
||||
github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=
|
||||
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
|
||||
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/common v0.52.3 h1:5f8uj6ZwHSscOGNdIQg6OiZv/ybiK2CO2q2drVZAQSA=
|
||||
github.com/prometheus/common v0.52.3/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U=
|
||||
github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o=
|
||||
github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g=
|
||||
github.com/protocolbuffers/txtpbfmt v0.0.0-20230328191034-3462fbc510c0 h1:sadMIsgmHpEOGbUs6VtHBXRR1OHevnj7hLx9ZcdNGW4=
|
||||
github.com/protocolbuffers/txtpbfmt v0.0.0-20230328191034-3462fbc510c0/go.mod h1:jgxiZysxFPM+iWKwQwPR+y+Jvo54ARd4EisXxKYpB5c=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ=
|
||||
github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
||||
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
||||
@@ -399,12 +575,30 @@ github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo=
|
||||
github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA=
|
||||
github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4=
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=
|
||||
github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c=
|
||||
github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE=
|
||||
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
|
||||
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
|
||||
github.com/sethvargo/go-retry v0.2.4 h1:T+jHEQy/zKJf5s95UkguisicE0zuF9y7+/vgz08Ocec=
|
||||
github.com/sethvargo/go-retry v0.2.4/go.mod h1:1afjQuvh7s4gflMObvjLPaWgluLLyhA1wmVZ6KLpICw=
|
||||
github.com/shirou/gopsutil/v3 v3.24.3 h1:eoUGJSmdfLzJ3mxIhmOAhgKEKgQkeOwKpz1NbhVnuPE=
|
||||
github.com/shirou/gopsutil/v3 v3.24.3/go.mod h1:JpND7O217xa72ewWz9zN2eIIkPWsDN/3pl0H8Qt0uwg=
|
||||
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
||||
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
||||
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
|
||||
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
|
||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
|
||||
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
|
||||
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
|
||||
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
@@ -416,23 +610,55 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes=
|
||||
github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k=
|
||||
github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U=
|
||||
github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
|
||||
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
|
||||
github.com/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4=
|
||||
github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0=
|
||||
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
|
||||
github.com/tklauser/numcpus v0.7.0 h1:yjuerZP127QG9m5Zh/mSO4wqurYil27tHrqwRoRjpr4=
|
||||
github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/vbatts/tar-split v0.11.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts=
|
||||
github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk=
|
||||
github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
|
||||
github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xlab/tablewriter v0.0.0-20160610135559-80b567a11ad5 h1:gmD7q6cCJfBbcuobWQe/KzLsd9Cd3amS1Mq5f3uU1qo=
|
||||
github.com/xlab/tablewriter v0.0.0-20160610135559-80b567a11ad5/go.mod h1:fVwOndYN3s5IaGlMucfgxwMhqwcaJtlGejBU6zX6Yxw=
|
||||
github.com/yashtewari/glob-intersection v0.2.0 h1:8iuHdN88yYuCzCdjt0gDe+6bAhUwBeEWqThExu54RFg=
|
||||
github.com/yashtewari/glob-intersection v0.2.0/go.mod h1:LK7pIC3piUjovexikBbJ26Yml7g8xa5bsjfx2v1fwok=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
github.com/zclconf/go-cty v1.8.0 h1:s4AvqaeQzJIu3ndv4gVIhplVD0krU+bgrcLSVUnaWuA=
|
||||
github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
@@ -440,12 +666,16 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
|
||||
go.opentelemetry.io/otel v1.25.0 h1:gldB5FfhRl7OJQbUHt/8s0a7cE8fbsPAtdpRaApKy4k=
|
||||
go.opentelemetry.io/otel v1.25.0/go.mod h1:Wa2ds5NOXEMkCmUou1WA7ZBfLTHWIsp034OVD7AO+Vg=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0 h1:dT33yIHtmsqpixFsSQPwNeY5drM9wTcoL8h0FWF4oGM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0/go.mod h1:h95q0LBGh7hlAC08X2DhSeyIG02YQ0UyioTCVAqRPmc=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0/go.mod h1:nUeKExfxAQVbiVFn32YXpXZZHZ61Cc3s3Rn1pDBGAb0=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0 h1:Xw8U6u2f8DK2XAkGRFV7BBLENgnTGX9i4rQRxJf+/vs=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0/go.mod h1:6KW1Fm6R/s6Z3PGXwSJN2K4eT6wQB3vXX6CVnYX9NmM=
|
||||
go.opentelemetry.io/otel/metric v1.25.0 h1:LUKbS7ArpFL/I2jJHdJcqMGxkRdxpPHE0VU/D4NuEwA=
|
||||
@@ -472,9 +702,10 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
|
||||
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@@ -485,8 +716,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 h1:aAcj0Da7eBAtrTp03QXWvm88pSyOt+UgdZw2BFZ+lEw=
|
||||
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ=
|
||||
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY=
|
||||
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI=
|
||||
golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a h1:Jw5wfR+h9mnIYH+OtGT2im5wV1YGGDora5vTv/aa5bE=
|
||||
golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
@@ -509,10 +740,11 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic=
|
||||
golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -541,11 +773,13 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
|
||||
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
|
||||
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -566,10 +800,12 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -577,6 +813,7 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -595,6 +832,9 @@ golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -603,20 +843,25 @@ golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
|
||||
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||
golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
|
||||
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -625,6 +870,7 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
@@ -677,10 +923,11 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw=
|
||||
golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
|
||||
golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY=
|
||||
golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -780,13 +1027,14 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
|
||||
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
||||
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
|
||||
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
||||
22
hack/choria/gen-machine-signer
Executable file
22
hack/choria/gen-machine-signer
Executable file
@@ -0,0 +1,22 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# build github.com/choria-io/go-choria with go build -trimpath -o choria -ldflags "-w" ./
|
||||
# Refer to https://github.com/ripienaar/choria-compose/blob/main/setup.sh#L41
|
||||
# Refer to https://github.com/holos-run/holos-infra/blob/v0.60.4/experiments/components/holos-saas/initialize/setup
|
||||
# choria jwt keys machine-signer.seed machine-signer.public
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
PARENT="$(cd "$(dirname "$0")" && pwd)"
|
||||
|
||||
tmpdir="$(mktemp -d)"
|
||||
finish() {
|
||||
[[ -d "$tmpdir" ]] && rm -rf "$tmpdir"
|
||||
}
|
||||
trap finish EXIT
|
||||
cd "$tmpdir"
|
||||
|
||||
mkdir machine-signer
|
||||
cd machine-signer
|
||||
choria jwt keys machine-signer.seed machine-signer.public
|
||||
holos create secret machine-signer --from-file .
|
||||
5
hack/choria/initialize/.gitignore
vendored
Normal file
5
hack/choria/initialize/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
/issuer/
|
||||
/provisioner/
|
||||
/broker/
|
||||
/customers/
|
||||
/agents/
|
||||
20
hack/choria/initialize/README.md
Normal file
20
hack/choria/initialize/README.md
Normal file
@@ -0,0 +1,20 @@
|
||||
Initialize machine room provisioning credentials
|
||||
|
||||
When you want the holos controller to provision while operating in the current
|
||||
working directory, run:
|
||||
|
||||
1. `init-choria-provisioner-creds` to populate secrets in the Holos
|
||||
Provisioner Cluster (not to be confused with the Choria Provisioner).
|
||||
2. `make-provisioning-jwt` to issue a `provisioning.jwt` file for `holos
|
||||
controller` to use.
|
||||
3. `holos controller --config=agent.cfg` to read `provisioning.jwt` and write
|
||||
the provisioned config file and credentials to the current directory.
|
||||
|
||||
Expect the controller to provision.
|
||||
|
||||
Setup Notes:
|
||||
|
||||
The holos server flag `--provisioner-seed` must match the issuer.seed value.
|
||||
To get the correct value to configure for holos server:
|
||||
|
||||
holos get secret choria-issuer --print-key=issuer.seed --namespace $NAMESPACE
|
||||
64
hack/choria/initialize/init-choria-provisioner-creds
Executable file
64
hack/choria/initialize/init-choria-provisioner-creds
Executable file
@@ -0,0 +1,64 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
|
||||
export BROKER_PASSWORD="$(LC_ALL=C tr -dc "[:alpha:]" </dev/random | tr '[:upper:]' '[:lower:]' | head -c 32)"
|
||||
export PROVISIONER_TOKEN="$(LC_ALL=C tr -dc "[:alpha:]" </dev/random | tr '[:upper:]' '[:lower:]' | head -c 32)"
|
||||
|
||||
set -xeuo pipefail
|
||||
|
||||
# Make sure gomplate is available
|
||||
gomplate --version
|
||||
|
||||
PARENT="$(cd $(dirname "$0") && pwd)"
|
||||
TOPLEVEL="$(cd "${PARENT}" && git rev-parse --show-toplevel)"
|
||||
: "${NAMESPACE:=jeff-holos}"
|
||||
export NAMESPACE
|
||||
|
||||
tmpdir="$(mktemp -d)"
|
||||
finish() {
|
||||
[[ -d "$tmpdir" ]] && rm -rf "$tmpdir"
|
||||
}
|
||||
trap finish EXIT
|
||||
cd "$tmpdir"
|
||||
|
||||
# Generate Secrets
|
||||
|
||||
# Create organization issuer
|
||||
mkdir issuer
|
||||
choria jwt keys "./issuer/issuer.seed" "./issuer/issuer.public"
|
||||
ISSUER="$(<issuer/issuer.public)"
|
||||
export ISSUER
|
||||
|
||||
# Provisioner token used for ???
|
||||
mkdir provisioner
|
||||
echo -n "${PROVISIONER_TOKEN}" > ./provisioner/token
|
||||
|
||||
# Provisioner signer
|
||||
choria jwt keys ./provisioner/signer.seed ./provisioner/signer.public
|
||||
choria jwt client ./provisioner/signer.jwt provisioner_signer ./issuer/issuer.seed \
|
||||
--public-key "$(<provisioner/signer.public)" --server-provisioner --validity $((100*365))d --issuer
|
||||
|
||||
# Provisioner Secret
|
||||
mkdir -p provisioner/secret
|
||||
gomplate --input-dir "${PARENT}/templates/provisioner" --output-dir ./provisioner/secret/
|
||||
cp ./provisioner/signer.seed ./provisioner/secret/signer.seed
|
||||
cp ./provisioner/signer.jwt ./provisioner/secret/signer.jwt
|
||||
|
||||
# Provisioner Broker
|
||||
mkdir broker
|
||||
choria jwt keys ./broker/broker.seed ./broker/broker.public
|
||||
choria jwt server ./broker/broker.jwt broker.holos.local "$(<broker/broker.public)" ./issuer/issuer.seed \
|
||||
--org choria \
|
||||
--collectives choria \
|
||||
--subjects 'choria.node_metadata.>'
|
||||
gomplate --input-dir "${PARENT}/templates/broker/" --output-dir ./broker/
|
||||
echo -n "${BROKER_PASSWORD}" > ./broker/password
|
||||
|
||||
mkdir agents
|
||||
choria jwt keys ./agents/signer.seed ./agents/signer.public
|
||||
|
||||
# Now save the secrets
|
||||
holos create secret --append-hash=false --namespace $NAMESPACE choria-issuer --from-file=issuer
|
||||
holos create secret --append-hash=false --namespace $NAMESPACE choria-broker --from-file=broker
|
||||
holos create secret --append-hash=false --namespace $NAMESPACE choria-provisioner --from-file=provisioner/secret
|
||||
holos create secret --append-hash=false --namespace $NAMESPACE choria-agents --from-file=agents
|
||||
50
hack/choria/initialize/make-provisioning-jwt
Executable file
50
hack/choria/initialize/make-provisioning-jwt
Executable file
@@ -0,0 +1,50 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# Make a provisioner.jwt and put it in the current directory.
|
||||
#
|
||||
# Use the provisioner.jwt with `holos controller --config=controller.cfg` which
|
||||
# will read the jwt from the same directory as the config file.
|
||||
#
|
||||
# Refer to Arri's
|
||||
# [setup.sh](https://github.com/ripienaar/machine-room-mvp/blob/main/example/setup/setup.sh#L41)
|
||||
# And our own nites at https://github.com/holos-run/holos/issues/142
|
||||
|
||||
PARENT="$(cd $(dirname "$0") && pwd)"
|
||||
OUTDIR="$(pwd)"
|
||||
|
||||
: "${NAMESPACE:=jeff-holos}"
|
||||
|
||||
tmpdir="$(mktemp -d)"
|
||||
finish() {
|
||||
[[ -d "$tmpdir" ]] && rm -rvf "$tmpdir"
|
||||
}
|
||||
trap finish EXIT
|
||||
cd "$tmpdir"
|
||||
|
||||
set -xeuo pipefail
|
||||
|
||||
# e.g. jeff.provision.dev.k2.holos.run
|
||||
#
|
||||
kubectl -n $NAMESPACE get virtualservice choria-broker-wss -o json > vs.json
|
||||
jq --exit-status -r '.spec.hosts[0]' vs.json > host
|
||||
|
||||
# Get the issuer.seed
|
||||
holos -n $NAMESPACE get secret choria-issuer --to-file issuer.seed
|
||||
|
||||
# Get the provisioner token to embed in the provisioning.jwt file.
|
||||
holos -n $NAMESPACE get secret choria-provisioner --to-file token
|
||||
|
||||
# The --token flag value must be the same value set in the token field of provisioner.yaml
|
||||
# Refer to https://github.com/ripienaar/machine-room-mvp/blob/main/example/setup/setup.sh#L41
|
||||
# Refer to https://github.com/ripienaar/machine-room-mvp/blob/main/example/setup/templates/provisioner/provisioner.yaml#L6
|
||||
choria jwt prov provisioning.jwt "issuer.seed" \
|
||||
--token "$(<token)" \
|
||||
--urls wss://$(<host):443 \
|
||||
--default \
|
||||
--protocol-v2 \
|
||||
--insecure \
|
||||
--update \
|
||||
--validity 30d \
|
||||
--extensions '{}'
|
||||
|
||||
cp provisioning.jwt "${OUTDIR}/"
|
||||
23
hack/choria/initialize/reset-choria-config
Executable file
23
hack/choria/initialize/reset-choria-config
Executable file
@@ -0,0 +1,23 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# This script resets the choria config for a Namespace
|
||||
|
||||
PARENT="$(cd $(dirname "$0") && pwd)"
|
||||
: "${NAMESPACE:=jeff-holos}"
|
||||
export NAMESPACE
|
||||
|
||||
set -xeuo pipefail
|
||||
|
||||
KUBECONFIG=$HOME/.holos/kubeconfig.provisioner kubectl delete secret -n jeff-holos choria-agents choria-broker choria-provisioner choria-issuer
|
||||
|
||||
"${PARENT}/init-choria-provisioner-creds"
|
||||
|
||||
stamp="$(date)"
|
||||
|
||||
kubectl -n $NAMESPACE annotate externalsecret choria-broker secret.holos.run/refresh="$stamp" --overwrite
|
||||
kubectl -n $NAMESPACE annotate externalsecret choria-provisioner secret.holos.run/refresh="$stamp" --overwrite
|
||||
|
||||
kubectl -n $NAMESPACE wait --for='jsonpath={.status.conditions[?(@.type=="Ready")].status}=True' externalsecret choria-provisioner choria-broker
|
||||
|
||||
kubectl -n $NAMESPACE rollout restart statefulset choria-broker
|
||||
kubectl -n $NAMESPACE rollout restart deployment choria-provisioner
|
||||
23
hack/choria/initialize/templates/broker/broker.conf
Normal file
23
hack/choria/initialize/templates/broker/broker.conf
Normal file
@@ -0,0 +1,23 @@
|
||||
loglevel = info
|
||||
plugin.choria.stats_address = 0.0.0.0
|
||||
plugin.choria.stats_port = 8222
|
||||
plugin.choria.broker_network = true
|
||||
plugin.choria.network.client_port = 4222
|
||||
plugin.choria.network.peer_port = 5222
|
||||
plugin.choria.network.system.user = system
|
||||
plugin.choria.network.system.password = system
|
||||
plugin.choria.network.peers = nats://choria-broker-0.choria-broker:5222,nats://choria-broker-1.choria-broker:5222,nats://choria-broker-2.choria-broker:5222
|
||||
plugin.choria.use_srv = false
|
||||
plugin.choria.network.websocket_port = 4333
|
||||
|
||||
plugin.security.provider = choria
|
||||
# NOTE: plugin.security.choria.ca must not be set or provisioning will fail
|
||||
# with a unhandled choria_provisioning purpose token error
|
||||
plugin.security.choria.certificate = /etc/choria-tls/tls.crt
|
||||
plugin.security.choria.key = /etc/choria-tls/tls.key
|
||||
plugin.security.choria.token_file = /etc/choria/broker.jwt
|
||||
plugin.security.choria.seed_file = /etc/choria/broker.seed
|
||||
plugin.choria.network.provisioning.client_password = {{ .Env.BROKER_PASSWORD }}
|
||||
|
||||
plugin.security.issuer.names = choria
|
||||
plugin.security.issuer.choria.public = {{ .Env.ISSUER }}
|
||||
1
hack/choria/initialize/templates/provisioner/ISSUER
Normal file
1
hack/choria/initialize/templates/provisioner/ISSUER
Normal file
@@ -0,0 +1 @@
|
||||
{{ .Env.ISSUER -}}
|
||||
7
hack/choria/initialize/templates/provisioner/choria.cfg
Normal file
7
hack/choria/initialize/templates/provisioner/choria.cfg
Normal file
@@ -0,0 +1,7 @@
|
||||
plugin.security.provider = choria
|
||||
plugin.security.choria.token_file = /etc/provisioner/signer.jwt
|
||||
plugin.security.choria.seed_file = /etc/provisioner/signer.seed
|
||||
|
||||
identity = provisioner_signer
|
||||
|
||||
plugin.choria.middleware_hosts = choria-broker-0.choria-broker:4222,choria-broker-1.choria-broker:4222,choria-broker-2.choria-broker:4222
|
||||
9
hack/choria/initialize/templates/provisioner/entrypoint
Normal file
9
hack/choria/initialize/templates/provisioner/entrypoint
Normal file
@@ -0,0 +1,9 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
|
||||
set -xeuo pipefail
|
||||
|
||||
mkdir -p /home/choria/bin
|
||||
install -m 0755 /etc/provisioner/helper.rb /home/choria/bin/helper.rb
|
||||
|
||||
exec /usr/sbin/choria-provisioner --config=/etc/provisioner/provisioner.yaml --choria-config=/etc/provisioner/choria.cfg
|
||||
134
hack/choria/initialize/templates/provisioner/helper.rb
Executable file
134
hack/choria/initialize/templates/provisioner/helper.rb
Executable file
@@ -0,0 +1,134 @@
|
||||
#!/usr/bin/ruby
|
||||
|
||||
require "json"
|
||||
require "yaml"
|
||||
require "base64"
|
||||
require "net/http"
|
||||
require "openssl"
|
||||
|
||||
def parse_input
|
||||
input = STDIN.read
|
||||
|
||||
begin
|
||||
File.open("/tmp/request.json", "w") {|f| f.write(input)}
|
||||
rescue Exception
|
||||
end
|
||||
|
||||
request = JSON.parse(input)
|
||||
request["inventory"] = JSON.parse(request["inventory"])
|
||||
|
||||
request
|
||||
end
|
||||
|
||||
def validate!(request, reply)
|
||||
if request["identity"] && request["identity"].length == 0
|
||||
reply["msg"] = "No identity received in request"
|
||||
reply["defer"] = true
|
||||
return false
|
||||
end
|
||||
|
||||
unless request["ed25519_pubkey"]
|
||||
reply["msg"] = "No ed15519 public key received"
|
||||
reply["defer"] = true
|
||||
return false
|
||||
end
|
||||
|
||||
unless request["ed25519_pubkey"]
|
||||
reply["msg"] = "No ed15519 directory received"
|
||||
reply["defer"] = true
|
||||
return false
|
||||
end
|
||||
|
||||
if request["ed25519_pubkey"]["directory"].length == 0
|
||||
reply["msg"] = "No ed15519 directory received"
|
||||
reply["defer"] = true
|
||||
return false
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def publish_reply(reply)
|
||||
begin
|
||||
File.open("/tmp/reply.json", "w") {|f| f.write(reply.to_json)}
|
||||
rescue Exception
|
||||
end
|
||||
|
||||
puts reply.to_json
|
||||
end
|
||||
|
||||
def publish_reply!(reply)
|
||||
publish_reply(reply)
|
||||
exit
|
||||
end
|
||||
|
||||
def set_config!(request, reply)
|
||||
# stub data the helper will fetch from the saas
|
||||
customers = {
|
||||
"one" => {
|
||||
:brokers => "nats://managed.example.net:9222", # whoever is the leader for this site
|
||||
:site => "customer_one",
|
||||
:source => {
|
||||
:host => "nats://cust_one:s3cret@saas-nats.choria.local",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
customer = request["jwt"]["extensions"]["customer"]
|
||||
brokers = customers[customer][:brokers]
|
||||
source = customers[customer][:source]
|
||||
|
||||
reply["configuration"].merge!(
|
||||
"identity" => request["identity"],
|
||||
"loglevel" => "warn",
|
||||
"plugin.choria.server.provision" => "false",
|
||||
"plugin.choria.middleware_hosts" => brokers,
|
||||
"plugin.security.issuer.names" => "choria",
|
||||
"plugin.security.issuer.choria.public" => "{{ .Env.ISSUER }}",
|
||||
"plugin.security.provider" => "choria",
|
||||
"plugin.security.choria.token_file" => File.join(request["ed25519_pubkey"]["directory"], "server.jwt"),
|
||||
"plugin.security.choria.seed_file" => File.join(request["ed25519_pubkey"]["directory"], "server.seed"),
|
||||
"machine_room.role" => "leader",
|
||||
"machine_room.site" => customers[customer][:site],
|
||||
"machine_room.source.host" => source[:host],
|
||||
)
|
||||
|
||||
reply["server_claims"].merge!(
|
||||
"exp" => 5*60*60*24*365,
|
||||
"pub_subjects" => [">"],
|
||||
"permissions" => {
|
||||
"streams" => true,
|
||||
"submission" => true,
|
||||
"service_host" => true,
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
reply = {
|
||||
"defer" => false,
|
||||
"msg" => "",
|
||||
"certificate" => "",
|
||||
"ca" => "",
|
||||
"configuration" => {},
|
||||
"server_claims" => {}
|
||||
}
|
||||
|
||||
begin
|
||||
request = parse_input
|
||||
|
||||
reply["msg"] = "Validating"
|
||||
unless validate!(request, reply)
|
||||
publish_reply!(reply)
|
||||
end
|
||||
|
||||
set_config!(request, reply)
|
||||
|
||||
reply["msg"] = "Done"
|
||||
publish_reply!(reply)
|
||||
rescue SystemExit
|
||||
rescue Exception
|
||||
reply["msg"] = "Unexpected failure during provisioning: %s: %s" % [$!.class, $!.to_s]
|
||||
reply["defer"] = true
|
||||
publish_reply!(reply)
|
||||
end
|
||||
@@ -0,0 +1,17 @@
|
||||
workers: 4
|
||||
interval: 1m
|
||||
logfile: /dev/stdout
|
||||
loglevel: info
|
||||
# The entrypoint script installs this helper script.
|
||||
helper: /home/choria/bin/helper.rb
|
||||
token: "{{ .Env.PROVISIONER_TOKEN }}"
|
||||
choria_insecure: false
|
||||
site: holos
|
||||
broker_provisioning_password: "{{ .Env.BROKER_PASSWORD }}"
|
||||
jwt_verify_cert: "{{ .Env.ISSUER }}"
|
||||
jwt_signing_key: /etc/provisioner/signer.seed
|
||||
jwt_signing_token: /etc/provisioner/signer.jwt
|
||||
|
||||
features:
|
||||
jwt: true
|
||||
ed25519: true
|
||||
1
hack/choria/initialize/templates/provisioner/token
Normal file
1
hack/choria/initialize/templates/provisioner/token
Normal file
@@ -0,0 +1 @@
|
||||
{{ .Env.PROVISIONER_TOKEN -}}
|
||||
16
hack/setup/bare
Executable file
16
hack/setup/bare
Executable 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
|
||||
@@ -3,5 +3,6 @@ USER root
|
||||
WORKDIR /app
|
||||
ADD bin bin
|
||||
RUN chown -R app: /app
|
||||
USER app
|
||||
# Kubernetes requires the user to be numeric
|
||||
USER 8192
|
||||
ENTRYPOINT bin/holos server
|
||||
|
||||
@@ -101,15 +101,44 @@ spec:
|
||||
gateways:
|
||||
- istio-ingress/default
|
||||
hosts:
|
||||
- '{developer}.holos.dev.k2.ois.run'
|
||||
- '{developer}.app.dev.k2.holos.run'
|
||||
http:
|
||||
- route:
|
||||
- name: "coffee-ui"
|
||||
match:
|
||||
- uri:
|
||||
prefix: "/ui"
|
||||
route:
|
||||
- destination:
|
||||
host: coffee
|
||||
port:
|
||||
number: 4200
|
||||
- name: "holos-api"
|
||||
route:
|
||||
- destination:
|
||||
host: '{name}'
|
||||
port:
|
||||
number: {listen_port}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: coffee
|
||||
spec:
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 4200
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Endpoints
|
||||
metadata:
|
||||
name: coffee
|
||||
subsets:
|
||||
- addresses:
|
||||
- ip: 192.168.2.21
|
||||
ports:
|
||||
- port: 4200
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: holos
|
||||
@@ -120,117 +149,6 @@ metadata:
|
||||
imagePullSecrets:
|
||||
- name: kube-system-ecr-image-pull-creds
|
||||
---
|
||||
apiVersion: security.istio.io/v1beta1
|
||||
kind: AuthorizationPolicy
|
||||
metadata:
|
||||
labels:
|
||||
app: '{name}'
|
||||
holos.run/developer: '{developer}'
|
||||
name: '{name}-allow-groups'
|
||||
namespace: '{namespace}'
|
||||
spec:
|
||||
action: ALLOW
|
||||
rules:
|
||||
- when:
|
||||
- key: request.auth.claims[groups]
|
||||
values:
|
||||
- holos-developer
|
||||
- holos-developer@openinfrastructure.co
|
||||
selector:
|
||||
matchLabels:
|
||||
holos.run/authz: dev-holos-sso
|
||||
---
|
||||
apiVersion: security.istio.io/v1beta1
|
||||
kind: AuthorizationPolicy
|
||||
metadata:
|
||||
name: '{name}-allow-nothing'
|
||||
namespace: '{namespace}'
|
||||
labels:
|
||||
app: '{name}'
|
||||
holos.run/developer: '{developer}'
|
||||
spec:
|
||||
action: ALLOW
|
||||
selector:
|
||||
matchLabels:
|
||||
holos.run/authz: dev-holos-sso
|
||||
---
|
||||
apiVersion: security.istio.io/v1beta1
|
||||
kind: AuthorizationPolicy
|
||||
metadata:
|
||||
name: '{name}-allow-well-known-paths'
|
||||
namespace: '{namespace}'
|
||||
labels:
|
||||
app: '{name}'
|
||||
holos.run/developer: '{developer}'
|
||||
spec:
|
||||
action: ALLOW
|
||||
rules:
|
||||
- to:
|
||||
- operation:
|
||||
paths:
|
||||
- /healthz
|
||||
- /metrics
|
||||
- /callbacks/github
|
||||
selector:
|
||||
matchLabels:
|
||||
holos.run/authz: dev-holos-sso
|
||||
---
|
||||
apiVersion: security.istio.io/v1beta1
|
||||
kind: AuthorizationPolicy
|
||||
metadata:
|
||||
name: '{name}-auth'
|
||||
namespace: '{namespace}'
|
||||
labels:
|
||||
app: '{name}'
|
||||
holos.run/developer: '{developer}'
|
||||
spec:
|
||||
action: CUSTOM
|
||||
provider:
|
||||
name: dev-holos-sso
|
||||
rules:
|
||||
- to:
|
||||
- operation:
|
||||
notPaths:
|
||||
- /healthz
|
||||
- /metrics
|
||||
- /callbacks/github
|
||||
when:
|
||||
- key: request.headers[Authorization]
|
||||
notValues:
|
||||
- Bearer *
|
||||
selector:
|
||||
matchLabels:
|
||||
holos.run/authz: dev-holos-sso
|
||||
---
|
||||
apiVersion: security.istio.io/v1beta1
|
||||
kind: RequestAuthentication
|
||||
metadata:
|
||||
name: '{name}'
|
||||
namespace: '{namespace}'
|
||||
labels:
|
||||
app: '{name}'
|
||||
holos.run/developer: '{developer}'
|
||||
spec:
|
||||
jwtRules:
|
||||
- audiences:
|
||||
- https://sso.dev.holos.run
|
||||
forwardOriginalToken: true
|
||||
fromHeaders:
|
||||
- name: x-auth-request-access-token
|
||||
issuer: https://idex.core.ois.run
|
||||
jwksUri: https://idex.core.ois.run/keys
|
||||
- audiences:
|
||||
- holos-cli
|
||||
forwardOriginalToken: true
|
||||
fromHeaders:
|
||||
- name: authorization
|
||||
prefix: 'Bearer '
|
||||
issuer: https://idex.core.ois.run
|
||||
jwksUri: https://idex.core.ois.run/keys
|
||||
selector:
|
||||
matchLabels:
|
||||
holos.run/authz: dev-holos-sso
|
||||
---
|
||||
apiVersion: postgres-operator.crunchydata.com/v1beta1
|
||||
kind: PGAdmin
|
||||
metadata:
|
||||
|
||||
273
internal/builder/builder.go
Normal file
273
internal/builder/builder.go
Normal file
@@ -0,0 +1,273 @@
|
||||
// Package builder is responsible for building fully rendered kubernetes api
|
||||
// objects from various input directories. A directory may contain a platform
|
||||
// spec or a component spec.
|
||||
package builder
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"cuelang.org/go/cue/build"
|
||||
"cuelang.org/go/cue/cuecontext"
|
||||
"cuelang.org/go/cue/load"
|
||||
"github.com/holos-run/holos/api/v1alpha1"
|
||||
|
||||
"github.com/holos-run/holos"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/logger"
|
||||
)
|
||||
|
||||
const (
|
||||
KubernetesObjects = v1alpha1.KubernetesObjectsKind
|
||||
// Helm is the value of the kind field of holos build output indicating helm
|
||||
// values and helm command information.
|
||||
Helm = v1alpha1.HelmChartKind
|
||||
// Skip is the value when the instance should be skipped
|
||||
Skip = "Skip"
|
||||
// KustomizeBuild is the value of the kind field of cue output indicating holos should process the component using kustomize build to render output.
|
||||
KustomizeBuild = v1alpha1.KustomizeBuildKind
|
||||
)
|
||||
|
||||
// An Option configures a Builder
|
||||
type Option func(*config)
|
||||
|
||||
type config struct {
|
||||
args []string
|
||||
cluster string
|
||||
}
|
||||
|
||||
type Builder struct {
|
||||
cfg config
|
||||
}
|
||||
|
||||
// New returns a new *Builder configured by opts Option.
|
||||
func New(opts ...Option) *Builder {
|
||||
var cfg config
|
||||
for _, f := range opts {
|
||||
f(&cfg)
|
||||
}
|
||||
b := &Builder{cfg: cfg}
|
||||
return b
|
||||
}
|
||||
|
||||
// Entrypoints configures the leaf directories Builder builds.
|
||||
func Entrypoints(args []string) Option {
|
||||
return func(cfg *config) { cfg.args = args }
|
||||
}
|
||||
|
||||
// Cluster configures the cluster name for the holos component instance.
|
||||
func Cluster(name string) Option {
|
||||
return func(cfg *config) { cfg.cluster = name }
|
||||
}
|
||||
|
||||
// Cluster returns the cluster name of the component instance being built.
|
||||
func (b *Builder) Cluster() string {
|
||||
return b.cfg.cluster
|
||||
}
|
||||
|
||||
// Instances returns the cue build instances being built.
|
||||
func (b *Builder) Instances(ctx context.Context) ([]*build.Instance, error) {
|
||||
log := logger.FromContext(ctx)
|
||||
|
||||
mod, err := b.findCueMod()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
dir := string(mod)
|
||||
|
||||
cfg := load.Config{Dir: dir}
|
||||
|
||||
// Make args relative to the module directory
|
||||
args := make([]string, len(b.cfg.args))
|
||||
for idx, path := range b.cfg.args {
|
||||
target, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(fmt.Errorf("could not find absolute path: %w", err))
|
||||
}
|
||||
relPath, err := filepath.Rel(dir, target)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(fmt.Errorf("invalid argument, must be relative to cue.mod: %w", err))
|
||||
}
|
||||
relPath = "./" + relPath
|
||||
args[idx] = relPath
|
||||
equiv := fmt.Sprintf("cue export --out yaml -t cluster=%v %v", b.Cluster(), relPath)
|
||||
log.Debug("cue: equivalent command: " + equiv)
|
||||
}
|
||||
|
||||
// Refer to https://github.com/cue-lang/cue/blob/v0.7.0/cmd/cue/cmd/common.go#L429
|
||||
cfg.Tags = append(cfg.Tags, "cluster="+b.Cluster())
|
||||
log.DebugContext(ctx, fmt.Sprintf("cue: tags %v", cfg.Tags))
|
||||
|
||||
return load.Instances(args, &cfg), nil
|
||||
}
|
||||
|
||||
func (b *Builder) Run(ctx context.Context) (results []*v1alpha1.Result, err error) {
|
||||
log := logger.FromContext(ctx)
|
||||
log.DebugContext(ctx, "cue: building instances")
|
||||
instances, err := b.Instances(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
results = make([]*v1alpha1.Result, 0, len(instances)*8)
|
||||
|
||||
// Each CUE instance provides a BuildPlan
|
||||
for idx, instance := range instances {
|
||||
log.DebugContext(ctx, "cue: building instance", "idx", idx, "dir", instance.Dir)
|
||||
r, err := b.runInstance(ctx, instance)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(fmt.Errorf("could not run: %w", err))
|
||||
}
|
||||
results = append(results, r...)
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func (b Builder) runInstance(ctx context.Context, instance *build.Instance) (results []*v1alpha1.Result, err error) {
|
||||
path := holos.InstancePath(instance.Dir)
|
||||
log := logger.FromContext(ctx).With("dir", path)
|
||||
|
||||
if err := instance.Err; err != nil {
|
||||
return nil, errors.Wrap(fmt.Errorf("could not load: %w", err))
|
||||
}
|
||||
cueCtx := cuecontext.New()
|
||||
value := cueCtx.BuildInstance(instance)
|
||||
if err := value.Err(); err != nil {
|
||||
return nil, errors.Wrap(fmt.Errorf("could not build %s: %w", instance.Dir, err))
|
||||
}
|
||||
log.DebugContext(ctx, "cue: validating instance")
|
||||
if err := value.Validate(); err != nil {
|
||||
return nil, errors.Wrap(fmt.Errorf("could not validate: %w", err))
|
||||
}
|
||||
|
||||
log.DebugContext(ctx, "cue: decoding holos build plan")
|
||||
jsonBytes, err := value.MarshalJSON()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(fmt.Errorf("could not marshal cue instance %s: %w", instance.Dir, err))
|
||||
}
|
||||
decoder := json.NewDecoder(bytes.NewReader(jsonBytes))
|
||||
// Discriminate the type of build plan.
|
||||
tm := &v1alpha1.TypeMeta{}
|
||||
err = decoder.Decode(tm)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(fmt.Errorf("invalid BuildPlan: %s: %w", instance.Dir, err))
|
||||
}
|
||||
|
||||
log.DebugContext(ctx, "cue: discriminated build kind: "+tm.Kind, "kind", tm.Kind, "apiVersion", tm.APIVersion)
|
||||
|
||||
// New decoder for the full object
|
||||
decoder = json.NewDecoder(bytes.NewReader(jsonBytes))
|
||||
decoder.DisallowUnknownFields()
|
||||
|
||||
switch tm.Kind {
|
||||
case "BuildPlan":
|
||||
var bp v1alpha1.BuildPlan
|
||||
if err = decoder.Decode(&bp); err != nil {
|
||||
err = errors.Wrap(fmt.Errorf("could not decode BuildPlan %s: %w", instance.Dir, err))
|
||||
return
|
||||
}
|
||||
results, err = b.buildPlan(ctx, &bp, path)
|
||||
case "Platform":
|
||||
var pf v1alpha1.Platform
|
||||
if err = decoder.Decode(&pf); err != nil {
|
||||
err = errors.Wrap(fmt.Errorf("could not decode Platform %s: %w", instance.Dir, err))
|
||||
return
|
||||
}
|
||||
results, err = b.buildPlatform(ctx, &pf)
|
||||
default:
|
||||
err = errors.Wrap(fmt.Errorf("unknown kind: %v", tm.Kind))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (b *Builder) buildPlatform(ctx context.Context, pf *v1alpha1.Platform) (results []*v1alpha1.Result, err error) {
|
||||
log := logger.FromContext(ctx)
|
||||
log.ErrorContext(ctx, "not implemented", "platform", pf)
|
||||
return nil, errors.Wrap(fmt.Errorf("not implemeneted"))
|
||||
}
|
||||
|
||||
func (b *Builder) buildPlan(ctx context.Context, buildPlan *v1alpha1.BuildPlan, path holos.InstancePath) (results []*v1alpha1.Result, err error) {
|
||||
log := logger.FromContext(ctx)
|
||||
|
||||
if err := buildPlan.Validate(); err != nil {
|
||||
log.WarnContext(ctx, "could not validate", "skipped", true, "err", err)
|
||||
return nil, errors.Wrap(fmt.Errorf("could not validate %w", err))
|
||||
}
|
||||
|
||||
if buildPlan.Spec.Disabled {
|
||||
log.DebugContext(ctx, "skipped: spec.disabled is true", "skipped", true)
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: concurrent renders
|
||||
results = make([]*v1alpha1.Result, 0, buildPlan.ResultCapacity())
|
||||
log.DebugContext(ctx, "allocated results slice", "cap", buildPlan.ResultCapacity())
|
||||
for _, component := range buildPlan.Spec.Components.Resources {
|
||||
if result, err := component.Render(ctx, path); err != nil {
|
||||
return nil, errors.Wrap(fmt.Errorf("could not render: %w", err))
|
||||
} else {
|
||||
results = append(results, result)
|
||||
}
|
||||
}
|
||||
|
||||
for _, component := range buildPlan.Spec.Components.KubernetesObjectsList {
|
||||
if result, err := component.Render(ctx, path); err != nil {
|
||||
return nil, errors.Wrap(fmt.Errorf("could not render: %w", err))
|
||||
} else {
|
||||
results = append(results, result)
|
||||
}
|
||||
}
|
||||
for _, component := range buildPlan.Spec.Components.HelmChartList {
|
||||
if result, err := component.Render(ctx, path); err != nil {
|
||||
return nil, errors.Wrap(fmt.Errorf("could not render: %w", err))
|
||||
} else {
|
||||
results = append(results, result)
|
||||
}
|
||||
}
|
||||
for _, component := range buildPlan.Spec.Components.KustomizeBuildList {
|
||||
if result, err := component.Render(ctx, path); err != nil {
|
||||
return nil, errors.Wrap(fmt.Errorf("could not render: %w", err))
|
||||
} else {
|
||||
results = append(results, result)
|
||||
}
|
||||
}
|
||||
|
||||
log.DebugContext(ctx, "returning results", "len", len(results))
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
// findCueMod returns the root module location containing the cue.mod file or
|
||||
// directory or an error if the builder arguments do not share a common root
|
||||
// module.
|
||||
func (b *Builder) findCueMod() (dir holos.PathCueMod, err error) {
|
||||
for _, origPath := range b.cfg.args {
|
||||
absPath, err := filepath.Abs(origPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
path := holos.PathCueMod(absPath)
|
||||
for {
|
||||
if _, err := os.Stat(filepath.Join(string(path), "cue.mod")); err == nil {
|
||||
if dir != "" && dir != path {
|
||||
return "", fmt.Errorf("multiple modules not supported: %v is not %v", dir, path)
|
||||
}
|
||||
dir = path
|
||||
break
|
||||
} else if !os.IsNotExist(err) {
|
||||
return "", err
|
||||
}
|
||||
parentPath := holos.PathCueMod(filepath.Dir(string(path)))
|
||||
if parentPath == path {
|
||||
return "", fmt.Errorf("no cue.mod from root to leaf: %v", origPath)
|
||||
}
|
||||
path = parentPath
|
||||
}
|
||||
}
|
||||
return dir, nil
|
||||
}
|
||||
@@ -2,12 +2,13 @@ package build
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strings"
|
||||
|
||||
"github.com/holos-run/holos/internal/builder"
|
||||
"github.com/holos-run/holos/internal/cli/command"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/holos"
|
||||
"github.com/holos-run/holos/internal/internal/builder"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -20,10 +21,12 @@ func makeBuildRunFunc(cfg *holos.Config) command.RunFunc {
|
||||
return err
|
||||
}
|
||||
outs := make([]string, 0, len(results))
|
||||
for _, result := range results {
|
||||
if result.Skip {
|
||||
for idx, result := range results {
|
||||
if result == nil || result.Skip {
|
||||
slog.Debug("skip result", "idx", idx, "result", result)
|
||||
continue
|
||||
}
|
||||
slog.Debug("append result", "idx", idx, "result.kind", result.Kind)
|
||||
outs = append(outs, result.AccumulatedOutput())
|
||||
}
|
||||
out := strings.Join(outs, "---\n")
|
||||
|
||||
50
internal/cli/controller/controller.go
Normal file
50
internal/cli/controller/controller.go
Normal file
@@ -0,0 +1,50 @@
|
||||
// Package controller integrates Choria Machine Room into Holos for cluster management.
|
||||
package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
mr "github.com/choria-io/machine-room"
|
||||
"github.com/holos-run/holos/internal/cli/command"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/holos"
|
||||
"github.com/holos-run/holos/version"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
// SigningKey is the public key from choria jwt keys machine-signer.seed machine-signer.public, refer to gen-machine-signer.
|
||||
SigningKey = "2a136e3875f4375968ae8e8d400ba24864d3ed7c4109675f357d32cc3ca1d5a7"
|
||||
)
|
||||
|
||||
func New(cfg *holos.Config) *cobra.Command {
|
||||
cmd := command.New("controller")
|
||||
cmd.Args = cobra.ArbitraryArgs
|
||||
cmd.DisableFlagParsing = true
|
||||
cmd.RunE = func(c *cobra.Command, args []string) error {
|
||||
if SigningKey == "" {
|
||||
return errors.Wrap(fmt.Errorf("could not run: controller.SigningKey not set from build variables"))
|
||||
}
|
||||
|
||||
ctx := c.Context()
|
||||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
}
|
||||
|
||||
app, err := mr.New(mr.Options{
|
||||
Name: "controller",
|
||||
Contact: "jeff@openinfrastructure.co",
|
||||
Version: version.Version,
|
||||
Help: "Holos Controller",
|
||||
MachineSigningKey: SigningKey,
|
||||
Args: args,
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(fmt.Errorf("could not make machine room app: %w", err))
|
||||
}
|
||||
|
||||
return app.Run(ctx)
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
// New returns a new login command.
|
||||
func New(cfg *holos.Config) *cobra.Command {
|
||||
cmd := command.New("login")
|
||||
cmd.Short = "log in by caching credentials"
|
||||
var printClaims bool
|
||||
|
||||
config := token.NewConfig()
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
|
||||
func New(cfg *holos.Config) *cobra.Command {
|
||||
cmd := command.New("logout")
|
||||
cmd.Short = "log out by deleting cached credentials"
|
||||
cmd.RunE = func(c *cobra.Command, args []string) error {
|
||||
if err := os.RemoveAll(token.CacheDir); err != nil {
|
||||
return errors.Wrap(fmt.Errorf("could not logout: %w", err))
|
||||
|
||||
@@ -1,52 +1,18 @@
|
||||
package render
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"github.com/holos-run/holos/internal/builder"
|
||||
"github.com/holos-run/holos/internal/cli/command"
|
||||
"github.com/holos-run/holos/internal/errors"
|
||||
"github.com/holos-run/holos/internal/holos"
|
||||
"github.com/holos-run/holos/internal/internal/builder"
|
||||
"github.com/holos-run/holos/internal/logger"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func makeRenderRunFunc(cfg *holos.Config) command.RunFunc {
|
||||
return func(cmd *cobra.Command, args []string) error {
|
||||
if cfg.ClusterName() == "" {
|
||||
return errors.Wrap(fmt.Errorf("missing cluster name"))
|
||||
}
|
||||
|
||||
ctx := cmd.Context()
|
||||
log := logger.FromContext(ctx)
|
||||
build := builder.New(builder.Entrypoints(args), builder.Cluster(cfg.ClusterName()))
|
||||
results, err := build.Run(cmd.Context())
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
// TODO: Avoid accidental over-writes if to holos component instances result in
|
||||
// the same file path. Write files into a blank temporary directory, error if a
|
||||
// file exists, then move the directory into place.
|
||||
for _, result := range results {
|
||||
if result.Skip {
|
||||
continue
|
||||
}
|
||||
// API Objects
|
||||
path := result.Filename(cfg.WriteTo(), cfg.ClusterName())
|
||||
if err := result.Save(ctx, path, result.AccumulatedOutput()); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
// Kustomization
|
||||
path = result.KustomizationFilename(cfg.WriteTo(), cfg.ClusterName())
|
||||
if err := result.Save(ctx, path, result.KsContent); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
log.InfoContext(ctx, "rendered "+result.Name(), "status", "ok", "action", "rendered", "name", result.Name())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// New returns the render subcommand for the root command
|
||||
func New(cfg *holos.Config) *cobra.Command {
|
||||
cmd := command.New("render [directory...]")
|
||||
@@ -55,6 +21,67 @@ func New(cfg *holos.Config) *cobra.Command {
|
||||
cmd.Flags().SortFlags = false
|
||||
cmd.Flags().AddGoFlagSet(cfg.WriteFlagSet())
|
||||
cmd.Flags().AddGoFlagSet(cfg.ClusterFlagSet())
|
||||
cmd.RunE = makeRenderRunFunc(cfg)
|
||||
|
||||
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"))
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
// TODO: Avoid accidental over-writes if to holos component instances result in
|
||||
// the same file path. Write files into a blank temporary directory, error if a
|
||||
// file exists, then move the directory into place.
|
||||
var result Result
|
||||
for _, result = range results {
|
||||
if result.Continue() {
|
||||
continue
|
||||
}
|
||||
// API Objects
|
||||
path := result.Filename(cfg.WriteTo(), cfg.ClusterName())
|
||||
if err := result.Save(ctx, path, result.AccumulatedOutput()); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
// Kustomization
|
||||
path = result.KustomizationFilename(cfg.WriteTo(), cfg.ClusterName())
|
||||
if err := result.Save(ctx, path, result.KustomizationContent()); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
log.InfoContext(ctx, "rendered "+result.Name(), "status", "ok", "action", "rendered", "name", result.Name())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
type Result interface {
|
||||
Continue() bool
|
||||
Name() string
|
||||
Filename(writeTo string, cluster string) string
|
||||
KustomizationFilename(writeTo string, cluster string) string
|
||||
Save(ctx context.Context, path string, content string) error
|
||||
AccumulatedOutput() string
|
||||
KustomizationContent() string
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/holos-run/holos/internal/server"
|
||||
|
||||
"github.com/holos-run/holos/internal/cli/build"
|
||||
"github.com/holos-run/holos/internal/cli/controller"
|
||||
"github.com/holos-run/holos/internal/cli/create"
|
||||
"github.com/holos-run/holos/internal/cli/get"
|
||||
"github.com/holos-run/holos/internal/cli/kv"
|
||||
@@ -15,6 +16,7 @@ import (
|
||||
"github.com/holos-run/holos/internal/cli/logout"
|
||||
"github.com/holos-run/holos/internal/cli/preflight"
|
||||
"github.com/holos-run/holos/internal/cli/render"
|
||||
"github.com/holos-run/holos/internal/cli/token"
|
||||
"github.com/holos-run/holos/internal/cli/txtar"
|
||||
"github.com/holos-run/holos/internal/holos"
|
||||
"github.com/holos-run/holos/internal/logger"
|
||||
@@ -60,6 +62,7 @@ func New(cfg *holos.Config) *cobra.Command {
|
||||
rootCmd.AddCommand(preflight.New(cfg))
|
||||
rootCmd.AddCommand(login.New(cfg))
|
||||
rootCmd.AddCommand(logout.New(cfg))
|
||||
rootCmd.AddCommand(token.New(cfg))
|
||||
|
||||
// Maybe not needed?
|
||||
rootCmd.AddCommand(txtar.New(cfg))
|
||||
@@ -70,5 +73,8 @@ func New(cfg *holos.Config) *cobra.Command {
|
||||
// Server
|
||||
rootCmd.AddCommand(server.New(cfg))
|
||||
|
||||
// Controller
|
||||
rootCmd.AddCommand(controller.New(cfg))
|
||||
|
||||
return rootCmd
|
||||
}
|
||||
|
||||
44
internal/cli/token/token.go
Normal file
44
internal/cli/token/token.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package token
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/holos-run/holos/internal/cli/command"
|
||||
"github.com/holos-run/holos/internal/holos"
|
||||
"github.com/holos-run/holos/internal/token"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// New returns a new login command.
|
||||
func New(cfg *holos.Config) *cobra.Command {
|
||||
cmd := command.New("token")
|
||||
cmd.Short = "write id token to stdout"
|
||||
cmd.Long = "Useful with curl / grpcurl -H $(holos token)"
|
||||
|
||||
config := token.NewConfig()
|
||||
cmd.Flags().AddGoFlagSet(config.FlagSet())
|
||||
|
||||
fs := &flag.FlagSet{}
|
||||
cmd.Flags().AddGoFlagSet(fs)
|
||||
|
||||
cmd.RunE = func(c *cobra.Command, args []string) error {
|
||||
ctx := c.Context()
|
||||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
}
|
||||
token, err := token.Get(ctx, cfg.Logger(), config)
|
||||
if err != nil {
|
||||
slog.Error("could not get token", "err", err)
|
||||
return fmt.Errorf("could not get token: %w", err)
|
||||
}
|
||||
|
||||
fmt.Fprintf(cmd.OutOrStdout(), token.Bearer)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
@@ -15,7 +15,9 @@ import (
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"github.com/holos-run/holos/internal/ent/organization"
|
||||
"github.com/holos-run/holos/internal/ent/platform"
|
||||
"github.com/holos-run/holos/internal/ent/user"
|
||||
)
|
||||
|
||||
@@ -26,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
|
||||
}
|
||||
@@ -40,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)
|
||||
}
|
||||
|
||||
@@ -134,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
|
||||
}
|
||||
@@ -155,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
|
||||
}
|
||||
@@ -185,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...)
|
||||
}
|
||||
|
||||
@@ -192,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...)
|
||||
}
|
||||
|
||||
@@ -200,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:
|
||||
@@ -315,6 +326,54 @@ func (c *OrganizationClient) GetX(ctx context.Context, id uuid.UUID) *Organizati
|
||||
return obj
|
||||
}
|
||||
|
||||
// QueryCreator queries the creator edge of a Organization.
|
||||
func (c *OrganizationClient) QueryCreator(o *Organization) *UserQuery {
|
||||
query := (&UserClient{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(user.Table, user.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, false, organization.CreatorTable, organization.CreatorColumn),
|
||||
)
|
||||
fromV = sqlgraph.Neighbors(o.driver.Dialect(), step)
|
||||
return fromV, nil
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
// QueryUsers queries the users edge of a Organization.
|
||||
func (c *OrganizationClient) QueryUsers(o *Organization) *UserQuery {
|
||||
query := (&UserClient{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(user.Table, user.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2M, false, organization.UsersTable, organization.UsersPrimaryKey...),
|
||||
)
|
||||
fromV = sqlgraph.Neighbors(o.driver.Dialect(), step)
|
||||
return fromV, nil
|
||||
}
|
||||
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(platform.Table, platform.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
|
||||
@@ -340,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 `platform.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 `platform.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(platform.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(platform.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(platform.Table, platform.FieldID, id),
|
||||
sqlgraph.To(user.Table, user.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, false, platform.CreatorTable, platform.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(platform.Table, platform.FieldID, id),
|
||||
sqlgraph.To(organization.Table, organization.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, false, platform.OrganizationTable, platform.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
|
||||
@@ -448,6 +672,22 @@ func (c *UserClient) GetX(ctx context.Context, id uuid.UUID) *User {
|
||||
return obj
|
||||
}
|
||||
|
||||
// QueryOrganizations queries the organizations edge of a User.
|
||||
func (c *UserClient) QueryOrganizations(u *User) *OrganizationQuery {
|
||||
query := (&OrganizationClient{config: c.config}).Query()
|
||||
query.path = func(context.Context) (fromV *sql.Selector, _ error) {
|
||||
id := u.ID
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(user.Table, user.FieldID, id),
|
||||
sqlgraph.To(organization.Table, organization.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2M, true, user.OrganizationsTable, user.OrganizationsPrimaryKey...),
|
||||
)
|
||||
fromV = sqlgraph.Neighbors(u.driver.Dialect(), step)
|
||||
return fromV, nil
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
// Hooks returns the client hooks.
|
||||
func (c *UserClient) Hooks() []Hook {
|
||||
return c.hooks.User
|
||||
@@ -476,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
|
||||
}
|
||||
)
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"github.com/holos-run/holos/internal/ent/organization"
|
||||
"github.com/holos-run/holos/internal/ent/platform"
|
||||
"github.com/holos-run/holos/internal/ent/user"
|
||||
)
|
||||
|
||||
@@ -75,6 +76,7 @@ func checkColumn(table, column string) error {
|
||||
initCheck.Do(func() {
|
||||
columnCheck = sql.NewColumnCheck(map[string]func(string) bool{
|
||||
organization.Table: organization.ValidColumn,
|
||||
platform.Table: platform.ValidColumn,
|
||||
user.Table: user.ValidColumn,
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
package ent
|
||||
|
||||
//go:generate go run -mod=mod entgo.io/ent/cmd/ent generate --feature sql/upsert ./schema
|
||||
//go:generate go run entgo.io/ent/cmd/ent generate --feature sql/upsert ./schema
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -15,12 +15,62 @@ var (
|
||||
{Name: "updated_at", Type: field.TypeTime},
|
||||
{Name: "name", Type: field.TypeString, Unique: true},
|
||||
{Name: "display_name", Type: field.TypeString},
|
||||
{Name: "creator_id", Type: field.TypeUUID},
|
||||
}
|
||||
// OrganizationsTable holds the schema information for the "organizations" table.
|
||||
OrganizationsTable = &schema.Table{
|
||||
Name: "organizations",
|
||||
Columns: OrganizationsColumns,
|
||||
PrimaryKey: []*schema.Column{OrganizationsColumns[0]},
|
||||
ForeignKeys: []*schema.ForeignKey{
|
||||
{
|
||||
Symbol: "organizations_users_creator",
|
||||
Columns: []*schema.Column{OrganizationsColumns[5]},
|
||||
RefColumns: []*schema.Column{UsersColumns[0]},
|
||||
OnDelete: schema.NoAction,
|
||||
},
|
||||
},
|
||||
}
|
||||
// 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{
|
||||
@@ -37,13 +87,52 @@ var (
|
||||
Name: "users",
|
||||
Columns: UsersColumns,
|
||||
PrimaryKey: []*schema.Column{UsersColumns[0]},
|
||||
Indexes: []*schema.Index{
|
||||
{
|
||||
Name: "user_iss_sub",
|
||||
Unique: true,
|
||||
Columns: []*schema.Column{UsersColumns[4], UsersColumns[5]},
|
||||
},
|
||||
},
|
||||
}
|
||||
// OrganizationUsersColumns holds the columns for the "organization_users" table.
|
||||
OrganizationUsersColumns = []*schema.Column{
|
||||
{Name: "organization_id", Type: field.TypeUUID},
|
||||
{Name: "user_id", Type: field.TypeUUID},
|
||||
}
|
||||
// OrganizationUsersTable holds the schema information for the "organization_users" table.
|
||||
OrganizationUsersTable = &schema.Table{
|
||||
Name: "organization_users",
|
||||
Columns: OrganizationUsersColumns,
|
||||
PrimaryKey: []*schema.Column{OrganizationUsersColumns[0], OrganizationUsersColumns[1]},
|
||||
ForeignKeys: []*schema.ForeignKey{
|
||||
{
|
||||
Symbol: "organization_users_organization_id",
|
||||
Columns: []*schema.Column{OrganizationUsersColumns[0]},
|
||||
RefColumns: []*schema.Column{OrganizationsColumns[0]},
|
||||
OnDelete: schema.Cascade,
|
||||
},
|
||||
{
|
||||
Symbol: "organization_users_user_id",
|
||||
Columns: []*schema.Column{OrganizationUsersColumns[1]},
|
||||
RefColumns: []*schema.Column{UsersColumns[0]},
|
||||
OnDelete: schema.Cascade,
|
||||
},
|
||||
},
|
||||
}
|
||||
// Tables holds all the tables in the schema.
|
||||
Tables = []*schema.Table{
|
||||
OrganizationsTable,
|
||||
PlatformsTable,
|
||||
UsersTable,
|
||||
OrganizationUsersTable,
|
||||
}
|
||||
)
|
||||
|
||||
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
@@ -11,6 +11,7 @@ import (
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"github.com/gofrs/uuid"
|
||||
"github.com/holos-run/holos/internal/ent/organization"
|
||||
"github.com/holos-run/holos/internal/ent/user"
|
||||
)
|
||||
|
||||
// Organization is the model entity for the Organization schema.
|
||||
@@ -25,10 +26,57 @@ type Organization struct {
|
||||
// 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"`
|
||||
DisplayName string `json:"display_name,omitempty"`
|
||||
// CreatorID holds the value of the "creator_id" field.
|
||||
CreatorID uuid.UUID `json:"creator_id,omitempty"`
|
||||
// Edges holds the relations/edges for other nodes in the graph.
|
||||
// The values are being populated by the OrganizationQuery when eager-loading is set.
|
||||
Edges OrganizationEdges `json:"edges"`
|
||||
selectValues sql.SelectValues
|
||||
}
|
||||
|
||||
// OrganizationEdges holds the relations/edges for other nodes in the graph.
|
||||
type OrganizationEdges struct {
|
||||
// Creator holds the value of the creator edge.
|
||||
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 [3]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 OrganizationEdges) 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"}
|
||||
}
|
||||
|
||||
// UsersOrErr returns the Users value or an error if the edge
|
||||
// was not loaded in eager-loading.
|
||||
func (e OrganizationEdges) UsersOrErr() ([]*User, error) {
|
||||
if e.loadedTypes[1] {
|
||||
return e.Users, nil
|
||||
}
|
||||
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))
|
||||
@@ -38,7 +86,7 @@ func (*Organization) scanValues(columns []string) ([]any, error) {
|
||||
values[i] = new(sql.NullString)
|
||||
case organization.FieldCreatedAt, organization.FieldUpdatedAt:
|
||||
values[i] = new(sql.NullTime)
|
||||
case organization.FieldID:
|
||||
case organization.FieldID, organization.FieldCreatorID:
|
||||
values[i] = new(uuid.UUID)
|
||||
default:
|
||||
values[i] = new(sql.UnknownType)
|
||||
@@ -85,6 +133,12 @@ func (o *Organization) assignValues(columns []string, values []any) error {
|
||||
} else if value.Valid {
|
||||
o.DisplayName = value.String
|
||||
}
|
||||
case organization.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 {
|
||||
o.CreatorID = *value
|
||||
}
|
||||
default:
|
||||
o.selectValues.Set(columns[i], values[i])
|
||||
}
|
||||
@@ -98,6 +152,21 @@ func (o *Organization) Value(name string) (ent.Value, error) {
|
||||
return o.selectValues.Get(name)
|
||||
}
|
||||
|
||||
// QueryCreator queries the "creator" edge of the Organization entity.
|
||||
func (o *Organization) QueryCreator() *UserQuery {
|
||||
return NewOrganizationClient(o.config).QueryCreator(o)
|
||||
}
|
||||
|
||||
// QueryUsers queries the "users" edge of the Organization entity.
|
||||
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.
|
||||
@@ -132,6 +201,9 @@ func (o *Organization) String() string {
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("display_name=")
|
||||
builder.WriteString(o.DisplayName)
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("creator_id=")
|
||||
builder.WriteString(fmt.Sprintf("%v", o.CreatorID))
|
||||
builder.WriteByte(')')
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"github.com/gofrs/uuid"
|
||||
)
|
||||
|
||||
@@ -22,8 +23,35 @@ const (
|
||||
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"
|
||||
// EdgeCreator holds the string denoting the creator edge name in mutations.
|
||||
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.
|
||||
CreatorTable = "organizations"
|
||||
// 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"
|
||||
// UsersTable is the table that holds the users relation/edge. The primary key declared below.
|
||||
UsersTable = "organization_users"
|
||||
// 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 "platform" package.
|
||||
PlatformsInverseTable = "platforms"
|
||||
// PlatformsColumn is the table column denoting the platforms relation/edge.
|
||||
PlatformsColumn = "org_id"
|
||||
)
|
||||
|
||||
// Columns holds all SQL columns for organization fields.
|
||||
@@ -33,8 +61,15 @@ var Columns = []string{
|
||||
FieldUpdatedAt,
|
||||
FieldName,
|
||||
FieldDisplayName,
|
||||
FieldCreatorID,
|
||||
}
|
||||
|
||||
var (
|
||||
// UsersPrimaryKey and UsersColumn2 are the table columns denoting the
|
||||
// primary key for the users relation (M2M).
|
||||
UsersPrimaryKey = []string{"organization_id", "user_id"}
|
||||
)
|
||||
|
||||
// ValidColumn reports if the column name is valid (part of the table columns).
|
||||
func ValidColumn(column string) bool {
|
||||
for i := range Columns {
|
||||
@@ -85,3 +120,64 @@ func ByName(opts ...sql.OrderTermOption) OrderOption {
|
||||
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()
|
||||
}
|
||||
|
||||
// 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...))
|
||||
}
|
||||
}
|
||||
|
||||
// ByUsersCount orders the results by users count.
|
||||
func ByUsersCount(opts ...sql.OrderTermOption) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
sqlgraph.OrderByNeighborsCount(s, newUsersStep(), opts...)
|
||||
}
|
||||
}
|
||||
|
||||
// ByUsers orders the results by users terms.
|
||||
func ByUsers(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
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),
|
||||
sqlgraph.To(CreatorInverseTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, false, CreatorTable, CreatorColumn),
|
||||
)
|
||||
}
|
||||
func newUsersStep() *sqlgraph.Step {
|
||||
return sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(UsersInverseTable, FieldID),
|
||||
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),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ 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"
|
||||
)
|
||||
@@ -75,6 +76,11 @@ func DisplayName(v string) predicate.Organization {
|
||||
return predicate.Organization(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.Organization {
|
||||
return predicate.Organization(sql.FieldEQ(FieldCreatorID, v))
|
||||
}
|
||||
|
||||
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
|
||||
func CreatedAtEQ(v time.Time) predicate.Organization {
|
||||
return predicate.Organization(sql.FieldEQ(FieldCreatedAt, v))
|
||||
@@ -285,6 +291,95 @@ func DisplayNameContainsFold(v string) predicate.Organization {
|
||||
return predicate.Organization(sql.FieldContainsFold(FieldDisplayName, v))
|
||||
}
|
||||
|
||||
// CreatorIDEQ applies the EQ predicate on the "creator_id" field.
|
||||
func CreatorIDEQ(v uuid.UUID) predicate.Organization {
|
||||
return predicate.Organization(sql.FieldEQ(FieldCreatorID, v))
|
||||
}
|
||||
|
||||
// CreatorIDNEQ applies the NEQ predicate on the "creator_id" field.
|
||||
func CreatorIDNEQ(v uuid.UUID) predicate.Organization {
|
||||
return predicate.Organization(sql.FieldNEQ(FieldCreatorID, v))
|
||||
}
|
||||
|
||||
// CreatorIDIn applies the In predicate on the "creator_id" field.
|
||||
func CreatorIDIn(vs ...uuid.UUID) predicate.Organization {
|
||||
return predicate.Organization(sql.FieldIn(FieldCreatorID, vs...))
|
||||
}
|
||||
|
||||
// CreatorIDNotIn applies the NotIn predicate on the "creator_id" field.
|
||||
func CreatorIDNotIn(vs ...uuid.UUID) predicate.Organization {
|
||||
return predicate.Organization(sql.FieldNotIn(FieldCreatorID, vs...))
|
||||
}
|
||||
|
||||
// HasCreator applies the HasEdge predicate on the "creator" edge.
|
||||
func HasCreator() predicate.Organization {
|
||||
return predicate.Organization(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.Organization {
|
||||
return predicate.Organization(func(s *sql.Selector) {
|
||||
step := newCreatorStep()
|
||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||
for _, p := range preds {
|
||||
p(s)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// HasUsers applies the HasEdge predicate on the "users" edge.
|
||||
func HasUsers() predicate.Organization {
|
||||
return predicate.Organization(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2M, false, UsersTable, UsersPrimaryKey...),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
})
|
||||
}
|
||||
|
||||
// HasUsersWith applies the HasEdge predicate on the "users" edge with a given conditions (other predicates).
|
||||
func HasUsersWith(preds ...predicate.User) predicate.Organization {
|
||||
return predicate.Organization(func(s *sql.Selector) {
|
||||
step := newUsersStep()
|
||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||
for _, p := range preds {
|
||||
p(s)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 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...))
|
||||
|
||||
@@ -14,6 +14,8 @@ import (
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/gofrs/uuid"
|
||||
"github.com/holos-run/holos/internal/ent/organization"
|
||||
"github.com/holos-run/holos/internal/ent/platform"
|
||||
"github.com/holos-run/holos/internal/ent/user"
|
||||
)
|
||||
|
||||
// OrganizationCreate is the builder for creating a Organization entity.
|
||||
@@ -64,6 +66,12 @@ func (oc *OrganizationCreate) SetDisplayName(s string) *OrganizationCreate {
|
||||
return oc
|
||||
}
|
||||
|
||||
// SetCreatorID sets the "creator_id" field.
|
||||
func (oc *OrganizationCreate) SetCreatorID(u uuid.UUID) *OrganizationCreate {
|
||||
oc.mutation.SetCreatorID(u)
|
||||
return oc
|
||||
}
|
||||
|
||||
// SetID sets the "id" field.
|
||||
func (oc *OrganizationCreate) SetID(u uuid.UUID) *OrganizationCreate {
|
||||
oc.mutation.SetID(u)
|
||||
@@ -78,6 +86,41 @@ func (oc *OrganizationCreate) SetNillableID(u *uuid.UUID) *OrganizationCreate {
|
||||
return oc
|
||||
}
|
||||
|
||||
// SetCreator sets the "creator" edge to the User entity.
|
||||
func (oc *OrganizationCreate) SetCreator(u *User) *OrganizationCreate {
|
||||
return oc.SetCreatorID(u.ID)
|
||||
}
|
||||
|
||||
// AddUserIDs adds the "users" edge to the User entity by IDs.
|
||||
func (oc *OrganizationCreate) AddUserIDs(ids ...uuid.UUID) *OrganizationCreate {
|
||||
oc.mutation.AddUserIDs(ids...)
|
||||
return oc
|
||||
}
|
||||
|
||||
// AddUsers adds the "users" edges to the User entity.
|
||||
func (oc *OrganizationCreate) AddUsers(u ...*User) *OrganizationCreate {
|
||||
ids := make([]uuid.UUID, len(u))
|
||||
for i := range u {
|
||||
ids[i] = u[i].ID
|
||||
}
|
||||
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
|
||||
@@ -146,6 +189,12 @@ func (oc *OrganizationCreate) check() error {
|
||||
if _, ok := oc.mutation.DisplayName(); !ok {
|
||||
return &ValidationError{Name: "display_name", err: errors.New(`ent: missing required field "Organization.display_name"`)}
|
||||
}
|
||||
if _, ok := oc.mutation.CreatorID(); !ok {
|
||||
return &ValidationError{Name: "creator_id", err: errors.New(`ent: missing required field "Organization.creator_id"`)}
|
||||
}
|
||||
if _, ok := oc.mutation.CreatorID(); !ok {
|
||||
return &ValidationError{Name: "creator", err: errors.New(`ent: missing required edge "Organization.creator"`)}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -198,6 +247,55 @@ func (oc *OrganizationCreate) createSpec() (*Organization, *sqlgraph.CreateSpec)
|
||||
_spec.SetField(organization.FieldDisplayName, field.TypeString, value)
|
||||
_node.DisplayName = value
|
||||
}
|
||||
if nodes := oc.mutation.CreatorIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: false,
|
||||
Table: organization.CreatorTable,
|
||||
Columns: []string{organization.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)
|
||||
}
|
||||
_node.CreatorID = nodes[0]
|
||||
_spec.Edges = append(_spec.Edges, edge)
|
||||
}
|
||||
if nodes := oc.mutation.UsersIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2M,
|
||||
Inverse: false,
|
||||
Table: organization.UsersTable,
|
||||
Columns: organization.UsersPrimaryKey,
|
||||
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 = 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(platform.FieldID, field.TypeUUID),
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges = append(_spec.Edges, edge)
|
||||
}
|
||||
return _node, _spec
|
||||
}
|
||||
|
||||
@@ -286,6 +384,18 @@ func (u *OrganizationUpsert) UpdateDisplayName() *OrganizationUpsert {
|
||||
return u
|
||||
}
|
||||
|
||||
// SetCreatorID sets the "creator_id" field.
|
||||
func (u *OrganizationUpsert) SetCreatorID(v uuid.UUID) *OrganizationUpsert {
|
||||
u.Set(organization.FieldCreatorID, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateCreatorID sets the "creator_id" field to the value that was provided on create.
|
||||
func (u *OrganizationUpsert) UpdateCreatorID() *OrganizationUpsert {
|
||||
u.SetExcluded(organization.FieldCreatorID)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateNewValues updates the mutable fields using the new values that were set on create except the ID field.
|
||||
// Using this option is equivalent to using:
|
||||
//
|
||||
@@ -379,6 +489,20 @@ func (u *OrganizationUpsertOne) UpdateDisplayName() *OrganizationUpsertOne {
|
||||
})
|
||||
}
|
||||
|
||||
// SetCreatorID sets the "creator_id" field.
|
||||
func (u *OrganizationUpsertOne) SetCreatorID(v uuid.UUID) *OrganizationUpsertOne {
|
||||
return u.Update(func(s *OrganizationUpsert) {
|
||||
s.SetCreatorID(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateCreatorID sets the "creator_id" field to the value that was provided on create.
|
||||
func (u *OrganizationUpsertOne) UpdateCreatorID() *OrganizationUpsertOne {
|
||||
return u.Update(func(s *OrganizationUpsert) {
|
||||
s.UpdateCreatorID()
|
||||
})
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (u *OrganizationUpsertOne) Exec(ctx context.Context) error {
|
||||
if len(u.create.conflict) == 0 {
|
||||
@@ -639,6 +763,20 @@ func (u *OrganizationUpsertBulk) UpdateDisplayName() *OrganizationUpsertBulk {
|
||||
})
|
||||
}
|
||||
|
||||
// SetCreatorID sets the "creator_id" field.
|
||||
func (u *OrganizationUpsertBulk) SetCreatorID(v uuid.UUID) *OrganizationUpsertBulk {
|
||||
return u.Update(func(s *OrganizationUpsert) {
|
||||
s.SetCreatorID(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateCreatorID sets the "creator_id" field to the value that was provided on create.
|
||||
func (u *OrganizationUpsertBulk) UpdateCreatorID() *OrganizationUpsertBulk {
|
||||
return u.Update(func(s *OrganizationUpsert) {
|
||||
s.UpdateCreatorID()
|
||||
})
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (u *OrganizationUpsertBulk) Exec(ctx context.Context) error {
|
||||
if u.create.err != nil {
|
||||
|
||||
@@ -4,6 +4,7 @@ package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
@@ -12,16 +13,21 @@ import (
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/gofrs/uuid"
|
||||
"github.com/holos-run/holos/internal/ent/organization"
|
||||
"github.com/holos-run/holos/internal/ent/platform"
|
||||
"github.com/holos-run/holos/internal/ent/predicate"
|
||||
"github.com/holos-run/holos/internal/ent/user"
|
||||
)
|
||||
|
||||
// OrganizationQuery is the builder for querying Organization entities.
|
||||
type OrganizationQuery struct {
|
||||
config
|
||||
ctx *QueryContext
|
||||
order []organization.OrderOption
|
||||
inters []Interceptor
|
||||
predicates []predicate.Organization
|
||||
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)
|
||||
@@ -58,6 +64,72 @@ func (oq *OrganizationQuery) Order(o ...organization.OrderOption) *OrganizationQ
|
||||
return oq
|
||||
}
|
||||
|
||||
// QueryCreator chains the current query on the "creator" edge.
|
||||
func (oq *OrganizationQuery) QueryCreator() *UserQuery {
|
||||
query := (&UserClient{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(user.Table, user.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, false, organization.CreatorTable, organization.CreatorColumn),
|
||||
)
|
||||
fromU = sqlgraph.SetNeighbors(oq.driver.Dialect(), step)
|
||||
return fromU, nil
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
// QueryUsers chains the current query on the "users" edge.
|
||||
func (oq *OrganizationQuery) QueryUsers() *UserQuery {
|
||||
query := (&UserClient{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(user.Table, user.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2M, false, organization.UsersTable, organization.UsersPrimaryKey...),
|
||||
)
|
||||
fromU = sqlgraph.SetNeighbors(oq.driver.Dialect(), step)
|
||||
return fromU, nil
|
||||
}
|
||||
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(platform.Table, platform.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) {
|
||||
@@ -245,17 +317,53 @@ 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...),
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
// 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 (oq *OrganizationQuery) WithCreator(opts ...func(*UserQuery)) *OrganizationQuery {
|
||||
query := (&UserClient{config: oq.config}).Query()
|
||||
for _, opt := range opts {
|
||||
opt(query)
|
||||
}
|
||||
oq.withCreator = query
|
||||
return oq
|
||||
}
|
||||
|
||||
// WithUsers tells the query-builder to eager-load the nodes that are connected to
|
||||
// the "users" edge. The optional arguments are used to configure the query builder of the edge.
|
||||
func (oq *OrganizationQuery) WithUsers(opts ...func(*UserQuery)) *OrganizationQuery {
|
||||
query := (&UserClient{config: oq.config}).Query()
|
||||
for _, opt := range opts {
|
||||
opt(query)
|
||||
}
|
||||
oq.withUsers = query
|
||||
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.
|
||||
//
|
||||
@@ -332,8 +440,13 @@ func (oq *OrganizationQuery) prepareQuery(ctx context.Context) error {
|
||||
|
||||
func (oq *OrganizationQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Organization, error) {
|
||||
var (
|
||||
nodes = []*Organization{}
|
||||
_spec = oq.querySpec()
|
||||
nodes = []*Organization{}
|
||||
_spec = oq.querySpec()
|
||||
loadedTypes = [3]bool{
|
||||
oq.withCreator != nil,
|
||||
oq.withUsers != nil,
|
||||
oq.withPlatforms != nil,
|
||||
}
|
||||
)
|
||||
_spec.ScanValues = func(columns []string) ([]any, error) {
|
||||
return (*Organization).scanValues(nil, columns)
|
||||
@@ -341,6 +454,7 @@ func (oq *OrganizationQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]
|
||||
_spec.Assign = func(columns []string, values []any) error {
|
||||
node := &Organization{config: oq.config}
|
||||
nodes = append(nodes, node)
|
||||
node.Edges.loadedTypes = loadedTypes
|
||||
return node.assignValues(columns, values)
|
||||
}
|
||||
for i := range hooks {
|
||||
@@ -352,9 +466,150 @@ func (oq *OrganizationQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]
|
||||
if len(nodes) == 0 {
|
||||
return nodes, nil
|
||||
}
|
||||
if query := oq.withCreator; query != nil {
|
||||
if err := oq.loadCreator(ctx, query, nodes, nil,
|
||||
func(n *Organization, e *User) { n.Edges.Creator = e }); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if query := oq.withUsers; query != nil {
|
||||
if err := oq.loadUsers(ctx, query, nodes,
|
||||
func(n *Organization) { n.Edges.Users = []*User{} },
|
||||
func(n *Organization, e *User) { n.Edges.Users = append(n.Edges.Users, e) }); err != nil {
|
||||
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
|
||||
}
|
||||
|
||||
func (oq *OrganizationQuery) loadCreator(ctx context.Context, query *UserQuery, nodes []*Organization, init func(*Organization), assign func(*Organization, *User)) error {
|
||||
ids := make([]uuid.UUID, 0, len(nodes))
|
||||
nodeids := make(map[uuid.UUID][]*Organization)
|
||||
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 (oq *OrganizationQuery) loadUsers(ctx context.Context, query *UserQuery, nodes []*Organization, init func(*Organization), assign func(*Organization, *User)) error {
|
||||
edgeIDs := make([]driver.Value, len(nodes))
|
||||
byID := make(map[uuid.UUID]*Organization)
|
||||
nids := make(map[uuid.UUID]map[*Organization]struct{})
|
||||
for i, node := range nodes {
|
||||
edgeIDs[i] = node.ID
|
||||
byID[node.ID] = node
|
||||
if init != nil {
|
||||
init(node)
|
||||
}
|
||||
}
|
||||
query.Where(func(s *sql.Selector) {
|
||||
joinT := sql.Table(organization.UsersTable)
|
||||
s.Join(joinT).On(s.C(user.FieldID), joinT.C(organization.UsersPrimaryKey[1]))
|
||||
s.Where(sql.InValues(joinT.C(organization.UsersPrimaryKey[0]), edgeIDs...))
|
||||
columns := s.SelectedColumns()
|
||||
s.Select(joinT.C(organization.UsersPrimaryKey[0]))
|
||||
s.AppendSelect(columns...)
|
||||
s.SetDistinct(false)
|
||||
})
|
||||
if err := query.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
qr := QuerierFunc(func(ctx context.Context, q Query) (Value, error) {
|
||||
return query.sqlAll(ctx, func(_ context.Context, spec *sqlgraph.QuerySpec) {
|
||||
assign := spec.Assign
|
||||
values := spec.ScanValues
|
||||
spec.ScanValues = func(columns []string) ([]any, error) {
|
||||
values, err := values(columns[1:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return append([]any{new(uuid.UUID)}, values...), nil
|
||||
}
|
||||
spec.Assign = func(columns []string, values []any) error {
|
||||
outValue := *values[0].(*uuid.UUID)
|
||||
inValue := *values[1].(*uuid.UUID)
|
||||
if nids[inValue] == nil {
|
||||
nids[inValue] = map[*Organization]struct{}{byID[outValue]: {}}
|
||||
return assign(columns[1:], values[1:])
|
||||
}
|
||||
nids[inValue][byID[outValue]] = struct{}{}
|
||||
return nil
|
||||
}
|
||||
})
|
||||
})
|
||||
neighbors, err := withInterceptors[[]*User](ctx, query, qr, query.inters)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, n := range neighbors {
|
||||
nodes, ok := nids[n.ID]
|
||||
if !ok {
|
||||
return fmt.Errorf(`unexpected "users" node returned %v`, n.ID)
|
||||
}
|
||||
for kn := range nodes {
|
||||
assign(kn, n)
|
||||
}
|
||||
}
|
||||
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(platform.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()
|
||||
_spec.Node.Columns = oq.ctx.Fields
|
||||
@@ -380,6 +635,9 @@ func (oq *OrganizationQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
|
||||
}
|
||||
}
|
||||
if oq.withCreator != nil {
|
||||
_spec.Node.AddColumnOnce(organization.FieldCreatorID)
|
||||
}
|
||||
}
|
||||
if ps := oq.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
|
||||
@@ -11,8 +11,11 @@ import (
|
||||
"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"
|
||||
"github.com/holos-run/holos/internal/ent/platform"
|
||||
"github.com/holos-run/holos/internal/ent/predicate"
|
||||
"github.com/holos-run/holos/internal/ent/user"
|
||||
)
|
||||
|
||||
// OrganizationUpdate is the builder for updating Organization entities.
|
||||
@@ -62,11 +65,108 @@ func (ou *OrganizationUpdate) SetNillableDisplayName(s *string) *OrganizationUpd
|
||||
return ou
|
||||
}
|
||||
|
||||
// SetCreatorID sets the "creator_id" field.
|
||||
func (ou *OrganizationUpdate) SetCreatorID(u uuid.UUID) *OrganizationUpdate {
|
||||
ou.mutation.SetCreatorID(u)
|
||||
return ou
|
||||
}
|
||||
|
||||
// SetNillableCreatorID sets the "creator_id" field if the given value is not nil.
|
||||
func (ou *OrganizationUpdate) SetNillableCreatorID(u *uuid.UUID) *OrganizationUpdate {
|
||||
if u != nil {
|
||||
ou.SetCreatorID(*u)
|
||||
}
|
||||
return ou
|
||||
}
|
||||
|
||||
// SetCreator sets the "creator" edge to the User entity.
|
||||
func (ou *OrganizationUpdate) SetCreator(u *User) *OrganizationUpdate {
|
||||
return ou.SetCreatorID(u.ID)
|
||||
}
|
||||
|
||||
// AddUserIDs adds the "users" edge to the User entity by IDs.
|
||||
func (ou *OrganizationUpdate) AddUserIDs(ids ...uuid.UUID) *OrganizationUpdate {
|
||||
ou.mutation.AddUserIDs(ids...)
|
||||
return ou
|
||||
}
|
||||
|
||||
// AddUsers adds the "users" edges to the User entity.
|
||||
func (ou *OrganizationUpdate) AddUsers(u ...*User) *OrganizationUpdate {
|
||||
ids := make([]uuid.UUID, len(u))
|
||||
for i := range u {
|
||||
ids[i] = u[i].ID
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
// ClearCreator clears the "creator" edge to the User entity.
|
||||
func (ou *OrganizationUpdate) ClearCreator() *OrganizationUpdate {
|
||||
ou.mutation.ClearCreator()
|
||||
return ou
|
||||
}
|
||||
|
||||
// ClearUsers clears all "users" edges to the User entity.
|
||||
func (ou *OrganizationUpdate) ClearUsers() *OrganizationUpdate {
|
||||
ou.mutation.ClearUsers()
|
||||
return ou
|
||||
}
|
||||
|
||||
// RemoveUserIDs removes the "users" edge to User entities by IDs.
|
||||
func (ou *OrganizationUpdate) RemoveUserIDs(ids ...uuid.UUID) *OrganizationUpdate {
|
||||
ou.mutation.RemoveUserIDs(ids...)
|
||||
return ou
|
||||
}
|
||||
|
||||
// RemoveUsers removes "users" edges to User entities.
|
||||
func (ou *OrganizationUpdate) RemoveUsers(u ...*User) *OrganizationUpdate {
|
||||
ids := make([]uuid.UUID, len(u))
|
||||
for i := range u {
|
||||
ids[i] = u[i].ID
|
||||
}
|
||||
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()
|
||||
@@ -110,6 +210,9 @@ func (ou *OrganizationUpdate) check() error {
|
||||
return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "Organization.name": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := ou.mutation.CreatorID(); ou.mutation.CreatorCleared() && !ok {
|
||||
return errors.New(`ent: clearing a required unique edge "Organization.creator"`)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -134,6 +237,125 @@ func (ou *OrganizationUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
if value, ok := ou.mutation.DisplayName(); ok {
|
||||
_spec.SetField(organization.FieldDisplayName, field.TypeString, value)
|
||||
}
|
||||
if ou.mutation.CreatorCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: false,
|
||||
Table: organization.CreatorTable,
|
||||
Columns: []string{organization.CreatorColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUUID),
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := ou.mutation.CreatorIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: false,
|
||||
Table: organization.CreatorTable,
|
||||
Columns: []string{organization.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 ou.mutation.UsersCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2M,
|
||||
Inverse: false,
|
||||
Table: organization.UsersTable,
|
||||
Columns: organization.UsersPrimaryKey,
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUUID),
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := ou.mutation.RemovedUsersIDs(); len(nodes) > 0 && !ou.mutation.UsersCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2M,
|
||||
Inverse: false,
|
||||
Table: organization.UsersTable,
|
||||
Columns: organization.UsersPrimaryKey,
|
||||
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.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := ou.mutation.UsersIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2M,
|
||||
Inverse: false,
|
||||
Table: organization.UsersTable,
|
||||
Columns: organization.UsersPrimaryKey,
|
||||
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 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(platform.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(platform.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(platform.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}
|
||||
@@ -188,11 +410,108 @@ func (ouo *OrganizationUpdateOne) SetNillableDisplayName(s *string) *Organizatio
|
||||
return ouo
|
||||
}
|
||||
|
||||
// SetCreatorID sets the "creator_id" field.
|
||||
func (ouo *OrganizationUpdateOne) SetCreatorID(u uuid.UUID) *OrganizationUpdateOne {
|
||||
ouo.mutation.SetCreatorID(u)
|
||||
return ouo
|
||||
}
|
||||
|
||||
// SetNillableCreatorID sets the "creator_id" field if the given value is not nil.
|
||||
func (ouo *OrganizationUpdateOne) SetNillableCreatorID(u *uuid.UUID) *OrganizationUpdateOne {
|
||||
if u != nil {
|
||||
ouo.SetCreatorID(*u)
|
||||
}
|
||||
return ouo
|
||||
}
|
||||
|
||||
// SetCreator sets the "creator" edge to the User entity.
|
||||
func (ouo *OrganizationUpdateOne) SetCreator(u *User) *OrganizationUpdateOne {
|
||||
return ouo.SetCreatorID(u.ID)
|
||||
}
|
||||
|
||||
// AddUserIDs adds the "users" edge to the User entity by IDs.
|
||||
func (ouo *OrganizationUpdateOne) AddUserIDs(ids ...uuid.UUID) *OrganizationUpdateOne {
|
||||
ouo.mutation.AddUserIDs(ids...)
|
||||
return ouo
|
||||
}
|
||||
|
||||
// AddUsers adds the "users" edges to the User entity.
|
||||
func (ouo *OrganizationUpdateOne) AddUsers(u ...*User) *OrganizationUpdateOne {
|
||||
ids := make([]uuid.UUID, len(u))
|
||||
for i := range u {
|
||||
ids[i] = u[i].ID
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
// ClearCreator clears the "creator" edge to the User entity.
|
||||
func (ouo *OrganizationUpdateOne) ClearCreator() *OrganizationUpdateOne {
|
||||
ouo.mutation.ClearCreator()
|
||||
return ouo
|
||||
}
|
||||
|
||||
// ClearUsers clears all "users" edges to the User entity.
|
||||
func (ouo *OrganizationUpdateOne) ClearUsers() *OrganizationUpdateOne {
|
||||
ouo.mutation.ClearUsers()
|
||||
return ouo
|
||||
}
|
||||
|
||||
// RemoveUserIDs removes the "users" edge to User entities by IDs.
|
||||
func (ouo *OrganizationUpdateOne) RemoveUserIDs(ids ...uuid.UUID) *OrganizationUpdateOne {
|
||||
ouo.mutation.RemoveUserIDs(ids...)
|
||||
return ouo
|
||||
}
|
||||
|
||||
// RemoveUsers removes "users" edges to User entities.
|
||||
func (ouo *OrganizationUpdateOne) RemoveUsers(u ...*User) *OrganizationUpdateOne {
|
||||
ids := make([]uuid.UUID, len(u))
|
||||
for i := range u {
|
||||
ids[i] = u[i].ID
|
||||
}
|
||||
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...)
|
||||
@@ -249,6 +568,9 @@ func (ouo *OrganizationUpdateOne) check() error {
|
||||
return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "Organization.name": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := ouo.mutation.CreatorID(); ouo.mutation.CreatorCleared() && !ok {
|
||||
return errors.New(`ent: clearing a required unique edge "Organization.creator"`)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -290,6 +612,125 @@ func (ouo *OrganizationUpdateOne) sqlSave(ctx context.Context) (_node *Organizat
|
||||
if value, ok := ouo.mutation.DisplayName(); ok {
|
||||
_spec.SetField(organization.FieldDisplayName, field.TypeString, value)
|
||||
}
|
||||
if ouo.mutation.CreatorCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: false,
|
||||
Table: organization.CreatorTable,
|
||||
Columns: []string{organization.CreatorColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUUID),
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := ouo.mutation.CreatorIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: false,
|
||||
Table: organization.CreatorTable,
|
||||
Columns: []string{organization.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 ouo.mutation.UsersCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2M,
|
||||
Inverse: false,
|
||||
Table: organization.UsersTable,
|
||||
Columns: organization.UsersPrimaryKey,
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUUID),
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := ouo.mutation.RemovedUsersIDs(); len(nodes) > 0 && !ouo.mutation.UsersCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2M,
|
||||
Inverse: false,
|
||||
Table: organization.UsersTable,
|
||||
Columns: organization.UsersPrimaryKey,
|
||||
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.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := ouo.mutation.UsersIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2M,
|
||||
Inverse: false,
|
||||
Table: organization.UsersTable,
|
||||
Columns: organization.UsersPrimaryKey,
|
||||
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 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(platform.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(platform.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(platform.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
262
internal/ent/platform.go
Normal 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"
|
||||
"github.com/holos-run/holos/internal/ent/platform"
|
||||
"github.com/holos-run/holos/internal/ent/user"
|
||||
holos "github.com/holos-run/holos/service/gen/holos/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 *holos.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 *holos.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 platform.FieldForm, platform.FieldModel, platform.FieldCue:
|
||||
values[i] = new([]byte)
|
||||
case platform.FieldName, platform.FieldDisplayName, platform.FieldCueDefinition:
|
||||
values[i] = new(sql.NullString)
|
||||
case platform.FieldCreatedAt, platform.FieldUpdatedAt:
|
||||
values[i] = new(sql.NullTime)
|
||||
case platform.FieldID, platform.FieldOrgID, platform.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 platform.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 platform.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 platform.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 platform.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 platform.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 platform.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 platform.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 platform.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 platform.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 platform.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 platform.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
|
||||
167
internal/ent/platform/platform.go
Normal file
167
internal/ent/platform/platform.go
Normal file
@@ -0,0 +1,167 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package platform
|
||||
|
||||
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),
|
||||
)
|
||||
}
|
||||
553
internal/ent/platform/where.go
Normal file
553
internal/ent/platform/where.go
Normal file
@@ -0,0 +1,553 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package platform
|
||||
|
||||
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))
|
||||
}
|
||||
1108
internal/ent/platform_create.go
Normal file
1108
internal/ent/platform_create.go
Normal file
File diff suppressed because it is too large
Load Diff
88
internal/ent/platform_delete.go
Normal file
88
internal/ent/platform_delete.go
Normal file
@@ -0,0 +1,88 @@
|
||||
// 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/platform"
|
||||
"github.com/holos-run/holos/internal/ent/predicate"
|
||||
)
|
||||
|
||||
// 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(platform.Table, sqlgraph.NewFieldSpec(platform.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{platform.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)
|
||||
}
|
||||
}
|
||||
681
internal/ent/platform_query.go
Normal file
681
internal/ent/platform_query.go
Normal 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"
|
||||
"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 []platform.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 ...platform.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(platform.Table, platform.FieldID, selector),
|
||||
sqlgraph.To(user.Table, user.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, false, platform.CreatorTable, platform.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(platform.Table, platform.FieldID, selector),
|
||||
sqlgraph.To(organization.Table, organization.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, false, platform.OrganizationTable, platform.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{platform.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{platform.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{platform.Label}
|
||||
default:
|
||||
return nil, &NotSingularError{platform.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{platform.Label}
|
||||
default:
|
||||
err = &NotSingularError{platform.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(platform.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([]platform.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(platform.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 = platform.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(platform.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 = platform.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 !platform.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(platform.Table, platform.Columns, sqlgraph.NewFieldSpec(platform.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, platform.FieldID)
|
||||
for i := range fields {
|
||||
if fields[i] != platform.FieldID {
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
|
||||
}
|
||||
}
|
||||
if pq.withCreator != nil {
|
||||
_spec.Node.AddColumnOnce(platform.FieldCreatorID)
|
||||
}
|
||||
if pq.withOrganization != nil {
|
||||
_spec.Node.AddColumnOnce(platform.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(platform.Table)
|
||||
columns := pq.ctx.Fields
|
||||
if len(columns) == 0 {
|
||||
columns = platform.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)
|
||||
}
|
||||
710
internal/ent/platform_update.go
Normal file
710
internal/ent/platform_update.go
Normal 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"
|
||||
"github.com/holos-run/holos/internal/ent/platform"
|
||||
"github.com/holos-run/holos/internal/ent/predicate"
|
||||
"github.com/holos-run/holos/internal/ent/user"
|
||||
holos "github.com/holos-run/holos/service/gen/holos/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(h *holos.Form) *PlatformUpdate {
|
||||
pu.mutation.SetForm(h)
|
||||
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(h *holos.Model) *PlatformUpdate {
|
||||
pu.mutation.SetModel(h)
|
||||
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 := platform.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 := platform.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(platform.Table, platform.Columns, sqlgraph.NewFieldSpec(platform.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(platform.FieldUpdatedAt, field.TypeTime, value)
|
||||
}
|
||||
if value, ok := pu.mutation.Name(); ok {
|
||||
_spec.SetField(platform.FieldName, field.TypeString, value)
|
||||
}
|
||||
if value, ok := pu.mutation.DisplayName(); ok {
|
||||
_spec.SetField(platform.FieldDisplayName, field.TypeString, value)
|
||||
}
|
||||
if value, ok := pu.mutation.Form(); ok {
|
||||
_spec.SetField(platform.FieldForm, field.TypeJSON, value)
|
||||
}
|
||||
if pu.mutation.FormCleared() {
|
||||
_spec.ClearField(platform.FieldForm, field.TypeJSON)
|
||||
}
|
||||
if value, ok := pu.mutation.Model(); ok {
|
||||
_spec.SetField(platform.FieldModel, field.TypeJSON, value)
|
||||
}
|
||||
if pu.mutation.ModelCleared() {
|
||||
_spec.ClearField(platform.FieldModel, field.TypeJSON)
|
||||
}
|
||||
if value, ok := pu.mutation.Cue(); ok {
|
||||
_spec.SetField(platform.FieldCue, field.TypeBytes, value)
|
||||
}
|
||||
if pu.mutation.CueCleared() {
|
||||
_spec.ClearField(platform.FieldCue, field.TypeBytes)
|
||||
}
|
||||
if value, ok := pu.mutation.CueDefinition(); ok {
|
||||
_spec.SetField(platform.FieldCueDefinition, field.TypeString, value)
|
||||
}
|
||||
if pu.mutation.CueDefinitionCleared() {
|
||||
_spec.ClearField(platform.FieldCueDefinition, field.TypeString)
|
||||
}
|
||||
if pu.mutation.CreatorCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: false,
|
||||
Table: platform.CreatorTable,
|
||||
Columns: []string{platform.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: platform.CreatorTable,
|
||||
Columns: []string{platform.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: platform.OrganizationTable,
|
||||
Columns: []string{platform.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: platform.OrganizationTable,
|
||||
Columns: []string{platform.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{platform.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(h *holos.Form) *PlatformUpdateOne {
|
||||
puo.mutation.SetForm(h)
|
||||
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(h *holos.Model) *PlatformUpdateOne {
|
||||
puo.mutation.SetModel(h)
|
||||
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 := platform.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 := platform.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(platform.Table, platform.Columns, sqlgraph.NewFieldSpec(platform.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, platform.FieldID)
|
||||
for _, f := range fields {
|
||||
if !platform.ValidColumn(f) {
|
||||
return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
if f != platform.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(platform.FieldUpdatedAt, field.TypeTime, value)
|
||||
}
|
||||
if value, ok := puo.mutation.Name(); ok {
|
||||
_spec.SetField(platform.FieldName, field.TypeString, value)
|
||||
}
|
||||
if value, ok := puo.mutation.DisplayName(); ok {
|
||||
_spec.SetField(platform.FieldDisplayName, field.TypeString, value)
|
||||
}
|
||||
if value, ok := puo.mutation.Form(); ok {
|
||||
_spec.SetField(platform.FieldForm, field.TypeJSON, value)
|
||||
}
|
||||
if puo.mutation.FormCleared() {
|
||||
_spec.ClearField(platform.FieldForm, field.TypeJSON)
|
||||
}
|
||||
if value, ok := puo.mutation.Model(); ok {
|
||||
_spec.SetField(platform.FieldModel, field.TypeJSON, value)
|
||||
}
|
||||
if puo.mutation.ModelCleared() {
|
||||
_spec.ClearField(platform.FieldModel, field.TypeJSON)
|
||||
}
|
||||
if value, ok := puo.mutation.Cue(); ok {
|
||||
_spec.SetField(platform.FieldCue, field.TypeBytes, value)
|
||||
}
|
||||
if puo.mutation.CueCleared() {
|
||||
_spec.ClearField(platform.FieldCue, field.TypeBytes)
|
||||
}
|
||||
if value, ok := puo.mutation.CueDefinition(); ok {
|
||||
_spec.SetField(platform.FieldCueDefinition, field.TypeString, value)
|
||||
}
|
||||
if puo.mutation.CueDefinitionCleared() {
|
||||
_spec.ClearField(platform.FieldCueDefinition, field.TypeString)
|
||||
}
|
||||
if puo.mutation.CreatorCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: false,
|
||||
Table: platform.CreatorTable,
|
||||
Columns: []string{platform.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: platform.CreatorTable,
|
||||
Columns: []string{platform.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: platform.OrganizationTable,
|
||||
Columns: []string{platform.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: platform.OrganizationTable,
|
||||
Columns: []string{platform.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{platform.Label}
|
||||
} else if sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
puo.mutation.done = true
|
||||
return _node, nil
|
||||
}
|
||||
@@ -9,5 +9,8 @@ import (
|
||||
// Organization is the predicate function for organization builders.
|
||||
type Organization func(*sql.Selector)
|
||||
|
||||
// Platform is the predicate function for platform builders.
|
||||
type Platform func(*sql.Selector)
|
||||
|
||||
// User is the predicate function for user builders.
|
||||
type User func(*sql.Selector)
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/gofrs/uuid"
|
||||
"github.com/holos-run/holos/internal/ent/organization"
|
||||
"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)
|
||||
platformMixin := schema.Platform{}.Mixin()
|
||||
platformMixinFields0 := platformMixin[0].Fields()
|
||||
_ = platformMixinFields0
|
||||
platformMixinFields1 := platformMixin[1].Fields()
|
||||
_ = platformMixinFields1
|
||||
platformFields := schema.Platform{}.Fields()
|
||||
_ = platformFields
|
||||
// platformDescCreatedAt is the schema descriptor for created_at field.
|
||||
platformDescCreatedAt := platformMixinFields1[0].Descriptor()
|
||||
// platform.DefaultCreatedAt holds the default value on creation for the created_at field.
|
||||
platform.DefaultCreatedAt = platformDescCreatedAt.Default.(func() time.Time)
|
||||
// platformDescUpdatedAt is the schema descriptor for updated_at field.
|
||||
platformDescUpdatedAt := platformMixinFields1[1].Descriptor()
|
||||
// platform.DefaultUpdatedAt holds the default value on creation for the updated_at field.
|
||||
platform.DefaultUpdatedAt = platformDescUpdatedAt.Default.(func() time.Time)
|
||||
// platform.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
|
||||
platform.UpdateDefaultUpdatedAt = platformDescUpdatedAt.UpdateDefault.(func() time.Time)
|
||||
// platformDescName is the schema descriptor for name field.
|
||||
platformDescName := platformFields[1].Descriptor()
|
||||
// platform.NameValidator is a validator for the "name" field. It is called by the builders before save.
|
||||
platform.NameValidator = platformDescName.Validators[0].(func(string) error)
|
||||
// platformDescID is the schema descriptor for id field.
|
||||
platformDescID := platformMixinFields0[0].Descriptor()
|
||||
// platform.DefaultID holds the default value on creation for the id field.
|
||||
platform.DefaultID = platformDescID.Default.(func() uuid.UUID)
|
||||
userMixin := schema.User{}.Mixin()
|
||||
userMixinFields0 := userMixin[0].Fields()
|
||||
_ = userMixinFields0
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/schema/field"
|
||||
"entgo.io/ent/schema/mixin"
|
||||
"github.com/gofrs/uuid"
|
||||
"time"
|
||||
)
|
||||
|
||||
func newUUID() uuid.UUID {
|
||||
@@ -18,6 +19,7 @@ type BaseMixin struct {
|
||||
|
||||
func (BaseMixin) Fields() []ent.Field {
|
||||
return []ent.Field{
|
||||
// id represents the identity of the entity.
|
||||
field.UUID("id", uuid.UUID{}).Default(newUUID),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,26 +2,39 @@ package schema
|
||||
|
||||
import (
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/schema/edge"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/gofrs/uuid"
|
||||
)
|
||||
|
||||
// User holds the schema definition for the User entity, the internal
|
||||
// representation and identity of a single human user. Users are scoped
|
||||
// globally.
|
||||
// Organization represents an organization account.
|
||||
type Organization struct {
|
||||
ent.Schema
|
||||
}
|
||||
|
||||
func (Organization) Fields() []ent.Field {
|
||||
return []ent.Field{
|
||||
field.String("name").NotEmpty().Unique(),
|
||||
field.String("display_name"),
|
||||
}
|
||||
}
|
||||
|
||||
func (Organization) Mixin() []ent.Mixin {
|
||||
return []ent.Mixin{
|
||||
BaseMixin{},
|
||||
TimeMixin{},
|
||||
}
|
||||
}
|
||||
|
||||
func (Organization) Fields() []ent.Field {
|
||||
return []ent.Field{
|
||||
field.String("name").NotEmpty().Unique(),
|
||||
field.String("display_name"),
|
||||
field.UUID("creator_id", uuid.UUID{}),
|
||||
}
|
||||
}
|
||||
|
||||
func (Organization) Edges() []ent.Edge {
|
||||
return []ent.Edge{
|
||||
edge.To("creator", User.Type).
|
||||
Field("creator_id").
|
||||
Unique().
|
||||
Required(),
|
||||
edge.To("users", User.Type),
|
||||
edge.From("platforms", Platform.Type).
|
||||
Ref("organization"),
|
||||
}
|
||||
}
|
||||
|
||||
62
internal/ent/schema/platform.go
Normal file
62
internal/ent/schema/platform.go
Normal 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"
|
||||
holos "github.com/holos-run/holos/service/gen/holos/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", &holos.Form{}).
|
||||
Optional().
|
||||
Comment("JSON representation of FormlyFormConfig[] refer to https://github.com/holos-run/holos/issues/161"),
|
||||
field.JSON("model", &holos.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(),
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,9 @@ package schema
|
||||
|
||||
import (
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/schema/edge"
|
||||
"entgo.io/ent/schema/field"
|
||||
"entgo.io/ent/schema/index"
|
||||
)
|
||||
|
||||
// User holds the schema definition for the User entity, the internal
|
||||
@@ -28,3 +30,16 @@ func (User) Fields() []ent.Field {
|
||||
field.String("name"),
|
||||
}
|
||||
}
|
||||
|
||||
func (User) Edges() []ent.Edge {
|
||||
return []ent.Edge{
|
||||
edge.From("organizations", Organization.Type).
|
||||
Ref("users"),
|
||||
}
|
||||
}
|
||||
|
||||
func (User) Indexes() []ent.Index {
|
||||
return []ent.Index{
|
||||
index.Fields("iss", "sub").Unique(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -29,10 +29,31 @@ type User struct {
|
||||
// Sub holds the value of the "sub" field.
|
||||
Sub string `json:"sub,omitempty"`
|
||||
// Name holds the value of the "name" field.
|
||||
Name string `json:"name,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
// Edges holds the relations/edges for other nodes in the graph.
|
||||
// The values are being populated by the UserQuery when eager-loading is set.
|
||||
Edges UserEdges `json:"edges"`
|
||||
selectValues sql.SelectValues
|
||||
}
|
||||
|
||||
// UserEdges holds the relations/edges for other nodes in the graph.
|
||||
type UserEdges struct {
|
||||
// Organizations holds the value of the organizations edge.
|
||||
Organizations []*Organization `json:"organizations,omitempty"`
|
||||
// loadedTypes holds the information for reporting if a
|
||||
// type was loaded (or requested) in eager-loading or not.
|
||||
loadedTypes [1]bool
|
||||
}
|
||||
|
||||
// OrganizationsOrErr returns the Organizations value or an error if the edge
|
||||
// was not loaded in eager-loading.
|
||||
func (e UserEdges) OrganizationsOrErr() ([]*Organization, error) {
|
||||
if e.loadedTypes[0] {
|
||||
return e.Organizations, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "organizations"}
|
||||
}
|
||||
|
||||
// scanValues returns the types for scanning values from sql.Rows.
|
||||
func (*User) scanValues(columns []string) ([]any, error) {
|
||||
values := make([]any, len(columns))
|
||||
@@ -114,6 +135,11 @@ func (u *User) Value(name string) (ent.Value, error) {
|
||||
return u.selectValues.Get(name)
|
||||
}
|
||||
|
||||
// QueryOrganizations queries the "organizations" edge of the User entity.
|
||||
func (u *User) QueryOrganizations() *OrganizationQuery {
|
||||
return NewUserClient(u.config).QueryOrganizations(u)
|
||||
}
|
||||
|
||||
// Update returns a builder for updating this User.
|
||||
// Note that you need to call User.Unwrap() before calling this method if this User
|
||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"github.com/gofrs/uuid"
|
||||
)
|
||||
|
||||
@@ -26,8 +27,15 @@ const (
|
||||
FieldSub = "sub"
|
||||
// FieldName holds the string denoting the name field in the database.
|
||||
FieldName = "name"
|
||||
// EdgeOrganizations holds the string denoting the organizations edge name in mutations.
|
||||
EdgeOrganizations = "organizations"
|
||||
// Table holds the table name of the user in the database.
|
||||
Table = "users"
|
||||
// OrganizationsTable is the table that holds the organizations relation/edge. The primary key declared below.
|
||||
OrganizationsTable = "organization_users"
|
||||
// OrganizationsInverseTable is the table name for the Organization entity.
|
||||
// It exists in this package in order to avoid circular dependency with the "organization" package.
|
||||
OrganizationsInverseTable = "organizations"
|
||||
)
|
||||
|
||||
// Columns holds all SQL columns for user fields.
|
||||
@@ -41,6 +49,12 @@ var Columns = []string{
|
||||
FieldName,
|
||||
}
|
||||
|
||||
var (
|
||||
// OrganizationsPrimaryKey and OrganizationsColumn2 are the table columns denoting the
|
||||
// primary key for the organizations relation (M2M).
|
||||
OrganizationsPrimaryKey = []string{"organization_id", "user_id"}
|
||||
)
|
||||
|
||||
// ValidColumn reports if the column name is valid (part of the table columns).
|
||||
func ValidColumn(column string) bool {
|
||||
for i := range Columns {
|
||||
@@ -101,3 +115,24 @@ func BySub(opts ...sql.OrderTermOption) OrderOption {
|
||||
func ByName(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldName, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByOrganizationsCount orders the results by organizations count.
|
||||
func ByOrganizationsCount(opts ...sql.OrderTermOption) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
sqlgraph.OrderByNeighborsCount(s, newOrganizationsStep(), opts...)
|
||||
}
|
||||
}
|
||||
|
||||
// ByOrganizations orders the results by organizations terms.
|
||||
func ByOrganizations(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
sqlgraph.OrderByNeighborTerms(s, newOrganizationsStep(), append([]sql.OrderTerm{term}, terms...)...)
|
||||
}
|
||||
}
|
||||
func newOrganizationsStep() *sqlgraph.Step {
|
||||
return sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(OrganizationsInverseTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2M, true, OrganizationsTable, OrganizationsPrimaryKey...),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ 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"
|
||||
)
|
||||
@@ -425,6 +426,29 @@ func NameContainsFold(v string) predicate.User {
|
||||
return predicate.User(sql.FieldContainsFold(FieldName, v))
|
||||
}
|
||||
|
||||
// HasOrganizations applies the HasEdge predicate on the "organizations" edge.
|
||||
func HasOrganizations() predicate.User {
|
||||
return predicate.User(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2M, true, OrganizationsTable, OrganizationsPrimaryKey...),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
})
|
||||
}
|
||||
|
||||
// HasOrganizationsWith applies the HasEdge predicate on the "organizations" edge with a given conditions (other predicates).
|
||||
func HasOrganizationsWith(preds ...predicate.Organization) predicate.User {
|
||||
return predicate.User(func(s *sql.Selector) {
|
||||
step := newOrganizationsStep()
|
||||
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.User) predicate.User {
|
||||
return predicate.User(sql.AndPredicates(predicates...))
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/gofrs/uuid"
|
||||
"github.com/holos-run/holos/internal/ent/organization"
|
||||
"github.com/holos-run/holos/internal/ent/user"
|
||||
)
|
||||
|
||||
@@ -90,6 +91,21 @@ func (uc *UserCreate) SetNillableID(u *uuid.UUID) *UserCreate {
|
||||
return uc
|
||||
}
|
||||
|
||||
// AddOrganizationIDs adds the "organizations" edge to the Organization entity by IDs.
|
||||
func (uc *UserCreate) AddOrganizationIDs(ids ...uuid.UUID) *UserCreate {
|
||||
uc.mutation.AddOrganizationIDs(ids...)
|
||||
return uc
|
||||
}
|
||||
|
||||
// AddOrganizations adds the "organizations" edges to the Organization entity.
|
||||
func (uc *UserCreate) AddOrganizations(o ...*Organization) *UserCreate {
|
||||
ids := make([]uuid.UUID, len(o))
|
||||
for i := range o {
|
||||
ids[i] = o[i].ID
|
||||
}
|
||||
return uc.AddOrganizationIDs(ids...)
|
||||
}
|
||||
|
||||
// Mutation returns the UserMutation object of the builder.
|
||||
func (uc *UserCreate) Mutation() *UserMutation {
|
||||
return uc.mutation
|
||||
@@ -224,6 +240,22 @@ func (uc *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) {
|
||||
_spec.SetField(user.FieldName, field.TypeString, value)
|
||||
_node.Name = value
|
||||
}
|
||||
if nodes := uc.mutation.OrganizationsIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2M,
|
||||
Inverse: true,
|
||||
Table: user.OrganizationsTable,
|
||||
Columns: user.OrganizationsPrimaryKey,
|
||||
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 = append(_spec.Edges, edge)
|
||||
}
|
||||
return _node, _spec
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user