feat: key generation, basic CLI
This commit is contained in:
parent
497cac49dd
commit
886e8aa11e
25 changed files with 709 additions and 64 deletions
|
@ -28,6 +28,34 @@ builds:
|
||||||
- windows
|
- windows
|
||||||
## <<Stencil::Block(klefkiExtraOS)>>
|
## <<Stencil::Block(klefkiExtraOS)>>
|
||||||
|
|
||||||
|
## <</Stencil::Block>>
|
||||||
|
ignore:
|
||||||
|
- goos: windows
|
||||||
|
goarch: arm
|
||||||
|
mod_timestamp: "{{ .CommitTimestamp }}"
|
||||||
|
- main: ./cmd/klefkictl
|
||||||
|
flags:
|
||||||
|
- -trimpath
|
||||||
|
ldflags:
|
||||||
|
- -s
|
||||||
|
- -w
|
||||||
|
## <<Stencil::Block(klefkictlLdflags)>>
|
||||||
|
|
||||||
|
## <</Stencil::Block>>
|
||||||
|
env:
|
||||||
|
- CGO_ENABLED=0
|
||||||
|
goarch:
|
||||||
|
- amd64
|
||||||
|
- arm64
|
||||||
|
## <<Stencil::Block(klefkictlExtraArch)>>
|
||||||
|
|
||||||
|
## <</Stencil::Block>>
|
||||||
|
goos:
|
||||||
|
- linux
|
||||||
|
- darwin
|
||||||
|
- windows
|
||||||
|
## <<Stencil::Block(klefkictlExtraOS)>>
|
||||||
|
|
||||||
## <</Stencil::Block>>
|
## <</Stencil::Block>>
|
||||||
ignore:
|
ignore:
|
||||||
- goos: windows
|
- goos: windows
|
||||||
|
|
49
cmd/klefkictl/klefkictl.go
Normal file
49
cmd/klefkictl/klefkictl.go
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
// Copyright (C) 2025 klefki contributors
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
exitCode := 0
|
||||||
|
defer func() { os.Exit(exitCode) }()
|
||||||
|
|
||||||
|
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
rootCmd := &cobra.Command{
|
||||||
|
Use: "klefkictl",
|
||||||
|
Short: "CLI for interacting with klefki",
|
||||||
|
}
|
||||||
|
rootCmd.AddCommand(
|
||||||
|
newNewCommand(),
|
||||||
|
newListCommand(),
|
||||||
|
newDeleteCommand(),
|
||||||
|
)
|
||||||
|
if err := rootCmd.ExecuteContext(ctx); err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, err)
|
||||||
|
exitCode = 1
|
||||||
|
}
|
||||||
|
}
|
43
cmd/klefkictl/klefkictl_delete.go
Normal file
43
cmd/klefkictl/klefkictl_delete.go
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
// Copyright (C) 2025 klefki contributors
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.rgst.io/homelab/klefki/internal/db"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// newDeleteCommand creates a dekete [cobra.Command]
|
||||||
|
func newDeleteCommand() *cobra.Command {
|
||||||
|
return &cobra.Command{
|
||||||
|
Use: "delete <fingerprint>",
|
||||||
|
Short: "Delete a known machine by fingerprint",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
db, err := db.New(cmd.Context())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to open DB: %w", err)
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
return db.Machine.DeleteOneID(args[0]).Exec(cmd.Context())
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
65
cmd/klefkictl/klefkictl_list.go
Normal file
65
cmd/klefkictl/klefkictl_list.go
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
// Copyright (C) 2025 klefki contributors
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"text/tabwriter"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.rgst.io/homelab/klefki/internal/db"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// newListCommand creates a list [cobra.Command]
|
||||||
|
func newListCommand() *cobra.Command {
|
||||||
|
return &cobra.Command{
|
||||||
|
Use: "list",
|
||||||
|
Short: "List all known machines",
|
||||||
|
Args: cobra.NoArgs,
|
||||||
|
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||||
|
db, err := db.New(cmd.Context())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to open DB: %w", err)
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
ms, err := db.Machine.Query().All(cmd.Context())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(ms) == 0 {
|
||||||
|
fmt.Println("No results found")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
tw := tabwriter.NewWriter(os.Stdout, 2, 2, 2, ' ', 0)
|
||||||
|
fmt.Fprint(tw, "FINGERPRINT\tCREATED AT\n")
|
||||||
|
for _, m := range ms {
|
||||||
|
createdAt, err := time.Parse(time.RFC3339, m.CreatedAt)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to parse created_at (%s): %w", m.CreatedAt, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(tw, "%s\t%s\n", m.ID, createdAt.Local())
|
||||||
|
}
|
||||||
|
return tw.Flush()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
68
cmd/klefkictl/klefkictl_new.go
Normal file
68
cmd/klefkictl/klefkictl_new.go
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
// Copyright (C) 2025 klefki contributors
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.rgst.io/homelab/klefki/internal/db"
|
||||||
|
"git.rgst.io/homelab/klefki/internal/machines"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// newNewCommand creates a new [cobra.Command]
|
||||||
|
func newNewCommand() *cobra.Command {
|
||||||
|
return &cobra.Command{
|
||||||
|
Use: "new",
|
||||||
|
Short: "Create a new machine",
|
||||||
|
Args: cobra.NoArgs,
|
||||||
|
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||||
|
db, err := db.New(cmd.Context())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to open DB: %w", err)
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
m, err := machines.NewMachine()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fprint, err := m.Fingerprint()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
privKey, err := m.EncodePrivateKey()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := db.Machine.Create().
|
||||||
|
SetID(fprint).SetPublicKey(m.PublicKey).
|
||||||
|
Exec(cmd.Context()); err != nil {
|
||||||
|
return fmt.Errorf("failed to write to DB: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Fingerprint:", fprint)
|
||||||
|
fmt.Println("Private Key:")
|
||||||
|
fmt.Println(privKey)
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
6
go.mod
6
go.mod
|
@ -4,6 +4,9 @@ go 1.23
|
||||||
|
|
||||||
require (
|
require (
|
||||||
entgo.io/ent v0.14.2
|
entgo.io/ent v0.14.2
|
||||||
|
github.com/davecgh/go-spew v1.1.1
|
||||||
|
github.com/ncruces/go-sqlite3 v0.23.1
|
||||||
|
github.com/spf13/cobra v1.9.1
|
||||||
google.golang.org/grpc v1.70.0
|
google.golang.org/grpc v1.70.0
|
||||||
google.golang.org/protobuf v1.36.5
|
google.golang.org/protobuf v1.36.5
|
||||||
)
|
)
|
||||||
|
@ -20,10 +23,11 @@ require (
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||||
|
github.com/ncruces/julianday v1.0.0 // indirect
|
||||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||||
github.com/rivo/uniseg v0.2.0 // indirect
|
github.com/rivo/uniseg v0.2.0 // indirect
|
||||||
github.com/spf13/cobra v1.9.1 // indirect
|
|
||||||
github.com/spf13/pflag v1.0.6 // indirect
|
github.com/spf13/pflag v1.0.6 // indirect
|
||||||
|
github.com/tetratelabs/wazero v1.9.0 // indirect
|
||||||
github.com/zclconf/go-cty v1.16.2 // indirect
|
github.com/zclconf/go-cty v1.16.2 // indirect
|
||||||
github.com/zclconf/go-cty-yaml v1.1.0 // indirect
|
github.com/zclconf/go-cty-yaml v1.1.0 // indirect
|
||||||
golang.org/x/mod v0.23.0 // indirect
|
golang.org/x/mod v0.23.0 // indirect
|
||||||
|
|
6
go.sum
generated
6
go.sum
generated
|
@ -38,6 +38,10 @@ github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwp
|
||||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||||
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
|
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/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
|
||||||
|
github.com/ncruces/go-sqlite3 v0.23.1 h1:zGAd76q+Tr18z/xKGatUlzBQdjR3J+rexfANUcjAgkY=
|
||||||
|
github.com/ncruces/go-sqlite3 v0.23.1/go.mod h1:Xg3FyAZl25HcBSFmcbymdfoTqD7jRnBUmv1jSrbIjdE=
|
||||||
|
github.com/ncruces/julianday v1.0.0 h1:fH0OKwa7NWvniGQtxdJRxAgkBMolni2BjDHaWTxqt7M=
|
||||||
|
github.com/ncruces/julianday v1.0.0/go.mod h1:Dusn2KvZrrovOMJuOt0TNXL6tB7U2E8kvza5fFc9G7g=
|
||||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
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/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
@ -51,6 +55,8 @@ github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
||||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
|
github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I=
|
||||||
|
github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM=
|
||||||
github.com/zclconf/go-cty v1.16.2 h1:LAJSwc3v81IRBZyUVQDUdZ7hs3SYs9jv0eZJDWHD/70=
|
github.com/zclconf/go-cty v1.16.2 h1:LAJSwc3v81IRBZyUVQDUdZ7hs3SYs9jv0eZJDWHD/70=
|
||||||
github.com/zclconf/go-cty v1.16.2/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
|
github.com/zclconf/go-cty v1.16.2/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
|
||||||
github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo=
|
github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo=
|
||||||
|
|
45
internal/db/db.go
Normal file
45
internal/db/db.go
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
// Copyright (C) 2025 klefki contributors
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0
|
||||||
|
|
||||||
|
// Package db contains the DB glue logic.
|
||||||
|
package db
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"entgo.io/ent/dialect"
|
||||||
|
"git.rgst.io/homelab/klefki/internal/db/ent"
|
||||||
|
|
||||||
|
_ "github.com/ncruces/go-sqlite3/driver" // Used by ent.
|
||||||
|
_ "github.com/ncruces/go-sqlite3/embed" // Also used by ent.
|
||||||
|
)
|
||||||
|
|
||||||
|
// New creates a new connection to the DB.
|
||||||
|
func New(ctx context.Context) (*ent.Client, error) {
|
||||||
|
client, err := ent.Open(dialect.SQLite, "file:data/klefkictl.db")
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to open database: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run the automatic migration tool to create all schema resources.
|
||||||
|
if err := client.Schema.Create(ctx); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to run DB migrations: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return client, nil
|
||||||
|
}
|
23
internal/db/ent/machine.go
generated
23
internal/db/ent/machine.go
generated
|
@ -18,7 +18,9 @@ type Machine struct {
|
||||||
// Fingerprint of the public key
|
// Fingerprint of the public key
|
||||||
ID string `json:"id,omitempty"`
|
ID string `json:"id,omitempty"`
|
||||||
// Public key of the machine
|
// Public key of the machine
|
||||||
PublicKey string `json:"public_key,omitempty"`
|
PublicKey []byte `json:"public_key,omitempty"`
|
||||||
|
// When this machine was added in UTC
|
||||||
|
CreatedAt string `json:"created_at,omitempty"`
|
||||||
selectValues sql.SelectValues
|
selectValues sql.SelectValues
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +29,9 @@ func (*Machine) scanValues(columns []string) ([]any, error) {
|
||||||
values := make([]any, len(columns))
|
values := make([]any, len(columns))
|
||||||
for i := range columns {
|
for i := range columns {
|
||||||
switch columns[i] {
|
switch columns[i] {
|
||||||
case machine.FieldID, machine.FieldPublicKey:
|
case machine.FieldPublicKey:
|
||||||
|
values[i] = new([]byte)
|
||||||
|
case machine.FieldID, machine.FieldCreatedAt:
|
||||||
values[i] = new(sql.NullString)
|
values[i] = new(sql.NullString)
|
||||||
default:
|
default:
|
||||||
values[i] = new(sql.UnknownType)
|
values[i] = new(sql.UnknownType)
|
||||||
|
@ -51,10 +55,16 @@ func (m *Machine) assignValues(columns []string, values []any) error {
|
||||||
m.ID = value.String
|
m.ID = value.String
|
||||||
}
|
}
|
||||||
case machine.FieldPublicKey:
|
case machine.FieldPublicKey:
|
||||||
if value, ok := values[i].(*sql.NullString); !ok {
|
if value, ok := values[i].(*[]byte); !ok {
|
||||||
return fmt.Errorf("unexpected type %T for field public_key", values[i])
|
return fmt.Errorf("unexpected type %T for field public_key", values[i])
|
||||||
|
} else if value != nil {
|
||||||
|
m.PublicKey = *value
|
||||||
|
}
|
||||||
|
case machine.FieldCreatedAt:
|
||||||
|
if value, ok := values[i].(*sql.NullString); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field created_at", values[i])
|
||||||
} else if value.Valid {
|
} else if value.Valid {
|
||||||
m.PublicKey = value.String
|
m.CreatedAt = value.String
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
m.selectValues.Set(columns[i], values[i])
|
m.selectValues.Set(columns[i], values[i])
|
||||||
|
@ -93,7 +103,10 @@ func (m *Machine) String() string {
|
||||||
builder.WriteString("Machine(")
|
builder.WriteString("Machine(")
|
||||||
builder.WriteString(fmt.Sprintf("id=%v, ", m.ID))
|
builder.WriteString(fmt.Sprintf("id=%v, ", m.ID))
|
||||||
builder.WriteString("public_key=")
|
builder.WriteString("public_key=")
|
||||||
builder.WriteString(m.PublicKey)
|
builder.WriteString(fmt.Sprintf("%v", m.PublicKey))
|
||||||
|
builder.WriteString(", ")
|
||||||
|
builder.WriteString("created_at=")
|
||||||
|
builder.WriteString(m.CreatedAt)
|
||||||
builder.WriteByte(')')
|
builder.WriteByte(')')
|
||||||
return builder.String()
|
return builder.String()
|
||||||
}
|
}
|
||||||
|
|
14
internal/db/ent/machine/machine.go
generated
14
internal/db/ent/machine/machine.go
generated
|
@ -13,6 +13,8 @@ const (
|
||||||
FieldID = "id"
|
FieldID = "id"
|
||||||
// FieldPublicKey holds the string denoting the public_key field in the database.
|
// FieldPublicKey holds the string denoting the public_key field in the database.
|
||||||
FieldPublicKey = "public_key"
|
FieldPublicKey = "public_key"
|
||||||
|
// FieldCreatedAt holds the string denoting the created_at field in the database.
|
||||||
|
FieldCreatedAt = "created_at"
|
||||||
// Table holds the table name of the machine in the database.
|
// Table holds the table name of the machine in the database.
|
||||||
Table = "machines"
|
Table = "machines"
|
||||||
)
|
)
|
||||||
|
@ -21,6 +23,7 @@ const (
|
||||||
var Columns = []string{
|
var Columns = []string{
|
||||||
FieldID,
|
FieldID,
|
||||||
FieldPublicKey,
|
FieldPublicKey,
|
||||||
|
FieldCreatedAt,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidColumn reports if the column name is valid (part of the table columns).
|
// ValidColumn reports if the column name is valid (part of the table columns).
|
||||||
|
@ -33,6 +36,11 @@ func ValidColumn(column string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
|
||||||
|
DefaultCreatedAt string
|
||||||
|
)
|
||||||
|
|
||||||
// OrderOption defines the ordering options for the Machine queries.
|
// OrderOption defines the ordering options for the Machine queries.
|
||||||
type OrderOption func(*sql.Selector)
|
type OrderOption func(*sql.Selector)
|
||||||
|
|
||||||
|
@ -41,7 +49,7 @@ func ByID(opts ...sql.OrderTermOption) OrderOption {
|
||||||
return sql.OrderByField(FieldID, opts...).ToFunc()
|
return sql.OrderByField(FieldID, opts...).ToFunc()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ByPublicKey orders the results by the public_key field.
|
// ByCreatedAt orders the results by the created_at field.
|
||||||
func ByPublicKey(opts ...sql.OrderTermOption) OrderOption {
|
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||||
return sql.OrderByField(FieldPublicKey, opts...).ToFunc()
|
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
|
||||||
}
|
}
|
||||||
|
|
93
internal/db/ent/machine/where.go
generated
93
internal/db/ent/machine/where.go
generated
|
@ -63,73 +63,118 @@ func IDContainsFold(id string) predicate.Machine {
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublicKey applies equality check predicate on the "public_key" field. It's identical to PublicKeyEQ.
|
// PublicKey applies equality check predicate on the "public_key" field. It's identical to PublicKeyEQ.
|
||||||
func PublicKey(v string) predicate.Machine {
|
func PublicKey(v []byte) predicate.Machine {
|
||||||
return predicate.Machine(sql.FieldEQ(FieldPublicKey, v))
|
return predicate.Machine(sql.FieldEQ(FieldPublicKey, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
|
||||||
|
func CreatedAt(v string) predicate.Machine {
|
||||||
|
return predicate.Machine(sql.FieldEQ(FieldCreatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
// PublicKeyEQ applies the EQ predicate on the "public_key" field.
|
// PublicKeyEQ applies the EQ predicate on the "public_key" field.
|
||||||
func PublicKeyEQ(v string) predicate.Machine {
|
func PublicKeyEQ(v []byte) predicate.Machine {
|
||||||
return predicate.Machine(sql.FieldEQ(FieldPublicKey, v))
|
return predicate.Machine(sql.FieldEQ(FieldPublicKey, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublicKeyNEQ applies the NEQ predicate on the "public_key" field.
|
// PublicKeyNEQ applies the NEQ predicate on the "public_key" field.
|
||||||
func PublicKeyNEQ(v string) predicate.Machine {
|
func PublicKeyNEQ(v []byte) predicate.Machine {
|
||||||
return predicate.Machine(sql.FieldNEQ(FieldPublicKey, v))
|
return predicate.Machine(sql.FieldNEQ(FieldPublicKey, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublicKeyIn applies the In predicate on the "public_key" field.
|
// PublicKeyIn applies the In predicate on the "public_key" field.
|
||||||
func PublicKeyIn(vs ...string) predicate.Machine {
|
func PublicKeyIn(vs ...[]byte) predicate.Machine {
|
||||||
return predicate.Machine(sql.FieldIn(FieldPublicKey, vs...))
|
return predicate.Machine(sql.FieldIn(FieldPublicKey, vs...))
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublicKeyNotIn applies the NotIn predicate on the "public_key" field.
|
// PublicKeyNotIn applies the NotIn predicate on the "public_key" field.
|
||||||
func PublicKeyNotIn(vs ...string) predicate.Machine {
|
func PublicKeyNotIn(vs ...[]byte) predicate.Machine {
|
||||||
return predicate.Machine(sql.FieldNotIn(FieldPublicKey, vs...))
|
return predicate.Machine(sql.FieldNotIn(FieldPublicKey, vs...))
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublicKeyGT applies the GT predicate on the "public_key" field.
|
// PublicKeyGT applies the GT predicate on the "public_key" field.
|
||||||
func PublicKeyGT(v string) predicate.Machine {
|
func PublicKeyGT(v []byte) predicate.Machine {
|
||||||
return predicate.Machine(sql.FieldGT(FieldPublicKey, v))
|
return predicate.Machine(sql.FieldGT(FieldPublicKey, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublicKeyGTE applies the GTE predicate on the "public_key" field.
|
// PublicKeyGTE applies the GTE predicate on the "public_key" field.
|
||||||
func PublicKeyGTE(v string) predicate.Machine {
|
func PublicKeyGTE(v []byte) predicate.Machine {
|
||||||
return predicate.Machine(sql.FieldGTE(FieldPublicKey, v))
|
return predicate.Machine(sql.FieldGTE(FieldPublicKey, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublicKeyLT applies the LT predicate on the "public_key" field.
|
// PublicKeyLT applies the LT predicate on the "public_key" field.
|
||||||
func PublicKeyLT(v string) predicate.Machine {
|
func PublicKeyLT(v []byte) predicate.Machine {
|
||||||
return predicate.Machine(sql.FieldLT(FieldPublicKey, v))
|
return predicate.Machine(sql.FieldLT(FieldPublicKey, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublicKeyLTE applies the LTE predicate on the "public_key" field.
|
// PublicKeyLTE applies the LTE predicate on the "public_key" field.
|
||||||
func PublicKeyLTE(v string) predicate.Machine {
|
func PublicKeyLTE(v []byte) predicate.Machine {
|
||||||
return predicate.Machine(sql.FieldLTE(FieldPublicKey, v))
|
return predicate.Machine(sql.FieldLTE(FieldPublicKey, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublicKeyContains applies the Contains predicate on the "public_key" field.
|
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
|
||||||
func PublicKeyContains(v string) predicate.Machine {
|
func CreatedAtEQ(v string) predicate.Machine {
|
||||||
return predicate.Machine(sql.FieldContains(FieldPublicKey, v))
|
return predicate.Machine(sql.FieldEQ(FieldCreatedAt, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublicKeyHasPrefix applies the HasPrefix predicate on the "public_key" field.
|
// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
|
||||||
func PublicKeyHasPrefix(v string) predicate.Machine {
|
func CreatedAtNEQ(v string) predicate.Machine {
|
||||||
return predicate.Machine(sql.FieldHasPrefix(FieldPublicKey, v))
|
return predicate.Machine(sql.FieldNEQ(FieldCreatedAt, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublicKeyHasSuffix applies the HasSuffix predicate on the "public_key" field.
|
// CreatedAtIn applies the In predicate on the "created_at" field.
|
||||||
func PublicKeyHasSuffix(v string) predicate.Machine {
|
func CreatedAtIn(vs ...string) predicate.Machine {
|
||||||
return predicate.Machine(sql.FieldHasSuffix(FieldPublicKey, v))
|
return predicate.Machine(sql.FieldIn(FieldCreatedAt, vs...))
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublicKeyEqualFold applies the EqualFold predicate on the "public_key" field.
|
// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
|
||||||
func PublicKeyEqualFold(v string) predicate.Machine {
|
func CreatedAtNotIn(vs ...string) predicate.Machine {
|
||||||
return predicate.Machine(sql.FieldEqualFold(FieldPublicKey, v))
|
return predicate.Machine(sql.FieldNotIn(FieldCreatedAt, vs...))
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublicKeyContainsFold applies the ContainsFold predicate on the "public_key" field.
|
// CreatedAtGT applies the GT predicate on the "created_at" field.
|
||||||
func PublicKeyContainsFold(v string) predicate.Machine {
|
func CreatedAtGT(v string) predicate.Machine {
|
||||||
return predicate.Machine(sql.FieldContainsFold(FieldPublicKey, v))
|
return predicate.Machine(sql.FieldGT(FieldCreatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAtGTE applies the GTE predicate on the "created_at" field.
|
||||||
|
func CreatedAtGTE(v string) predicate.Machine {
|
||||||
|
return predicate.Machine(sql.FieldGTE(FieldCreatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAtLT applies the LT predicate on the "created_at" field.
|
||||||
|
func CreatedAtLT(v string) predicate.Machine {
|
||||||
|
return predicate.Machine(sql.FieldLT(FieldCreatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAtLTE applies the LTE predicate on the "created_at" field.
|
||||||
|
func CreatedAtLTE(v string) predicate.Machine {
|
||||||
|
return predicate.Machine(sql.FieldLTE(FieldCreatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAtContains applies the Contains predicate on the "created_at" field.
|
||||||
|
func CreatedAtContains(v string) predicate.Machine {
|
||||||
|
return predicate.Machine(sql.FieldContains(FieldCreatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAtHasPrefix applies the HasPrefix predicate on the "created_at" field.
|
||||||
|
func CreatedAtHasPrefix(v string) predicate.Machine {
|
||||||
|
return predicate.Machine(sql.FieldHasPrefix(FieldCreatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAtHasSuffix applies the HasSuffix predicate on the "created_at" field.
|
||||||
|
func CreatedAtHasSuffix(v string) predicate.Machine {
|
||||||
|
return predicate.Machine(sql.FieldHasSuffix(FieldCreatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAtEqualFold applies the EqualFold predicate on the "created_at" field.
|
||||||
|
func CreatedAtEqualFold(v string) predicate.Machine {
|
||||||
|
return predicate.Machine(sql.FieldEqualFold(FieldCreatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAtContainsFold applies the ContainsFold predicate on the "created_at" field.
|
||||||
|
func CreatedAtContainsFold(v string) predicate.Machine {
|
||||||
|
return predicate.Machine(sql.FieldContainsFold(FieldCreatedAt, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
// And groups predicates with the AND operator between them.
|
// And groups predicates with the AND operator between them.
|
||||||
|
|
37
internal/db/ent/machine_create.go
generated
37
internal/db/ent/machine_create.go
generated
|
@ -20,8 +20,22 @@ type MachineCreate struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetPublicKey sets the "public_key" field.
|
// SetPublicKey sets the "public_key" field.
|
||||||
func (mc *MachineCreate) SetPublicKey(s string) *MachineCreate {
|
func (mc *MachineCreate) SetPublicKey(b []byte) *MachineCreate {
|
||||||
mc.mutation.SetPublicKey(s)
|
mc.mutation.SetPublicKey(b)
|
||||||
|
return mc
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetCreatedAt sets the "created_at" field.
|
||||||
|
func (mc *MachineCreate) SetCreatedAt(s string) *MachineCreate {
|
||||||
|
mc.mutation.SetCreatedAt(s)
|
||||||
|
return mc
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
|
||||||
|
func (mc *MachineCreate) SetNillableCreatedAt(s *string) *MachineCreate {
|
||||||
|
if s != nil {
|
||||||
|
mc.SetCreatedAt(*s)
|
||||||
|
}
|
||||||
return mc
|
return mc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +52,7 @@ func (mc *MachineCreate) Mutation() *MachineMutation {
|
||||||
|
|
||||||
// Save creates the Machine in the database.
|
// Save creates the Machine in the database.
|
||||||
func (mc *MachineCreate) Save(ctx context.Context) (*Machine, error) {
|
func (mc *MachineCreate) Save(ctx context.Context) (*Machine, error) {
|
||||||
|
mc.defaults()
|
||||||
return withHooks(ctx, mc.sqlSave, mc.mutation, mc.hooks)
|
return withHooks(ctx, mc.sqlSave, mc.mutation, mc.hooks)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,11 +78,22 @@ func (mc *MachineCreate) ExecX(ctx context.Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// defaults sets the default values of the builder before save.
|
||||||
|
func (mc *MachineCreate) defaults() {
|
||||||
|
if _, ok := mc.mutation.CreatedAt(); !ok {
|
||||||
|
v := machine.DefaultCreatedAt
|
||||||
|
mc.mutation.SetCreatedAt(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check runs all checks and user-defined validators on the builder.
|
// check runs all checks and user-defined validators on the builder.
|
||||||
func (mc *MachineCreate) check() error {
|
func (mc *MachineCreate) check() error {
|
||||||
if _, ok := mc.mutation.PublicKey(); !ok {
|
if _, ok := mc.mutation.PublicKey(); !ok {
|
||||||
return &ValidationError{Name: "public_key", err: errors.New(`ent: missing required field "Machine.public_key"`)}
|
return &ValidationError{Name: "public_key", err: errors.New(`ent: missing required field "Machine.public_key"`)}
|
||||||
}
|
}
|
||||||
|
if _, ok := mc.mutation.CreatedAt(); !ok {
|
||||||
|
return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "Machine.created_at"`)}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,9 +130,13 @@ func (mc *MachineCreate) createSpec() (*Machine, *sqlgraph.CreateSpec) {
|
||||||
_spec.ID.Value = id
|
_spec.ID.Value = id
|
||||||
}
|
}
|
||||||
if value, ok := mc.mutation.PublicKey(); ok {
|
if value, ok := mc.mutation.PublicKey(); ok {
|
||||||
_spec.SetField(machine.FieldPublicKey, field.TypeString, value)
|
_spec.SetField(machine.FieldPublicKey, field.TypeBytes, value)
|
||||||
_node.PublicKey = value
|
_node.PublicKey = value
|
||||||
}
|
}
|
||||||
|
if value, ok := mc.mutation.CreatedAt(); ok {
|
||||||
|
_spec.SetField(machine.FieldCreatedAt, field.TypeString, value)
|
||||||
|
_node.CreatedAt = value
|
||||||
|
}
|
||||||
return _node, _spec
|
return _node, _spec
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,6 +158,7 @@ func (mcb *MachineCreateBulk) Save(ctx context.Context) ([]*Machine, error) {
|
||||||
for i := range mcb.builders {
|
for i := range mcb.builders {
|
||||||
func(i int, root context.Context) {
|
func(i int, root context.Context) {
|
||||||
builder := mcb.builders[i]
|
builder := mcb.builders[i]
|
||||||
|
builder.defaults()
|
||||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||||
mutation, ok := m.(*MachineMutation)
|
mutation, ok := m.(*MachineMutation)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
4
internal/db/ent/machine_query.go
generated
4
internal/db/ent/machine_query.go
generated
|
@ -262,7 +262,7 @@ func (mq *MachineQuery) Clone() *MachineQuery {
|
||||||
// Example:
|
// Example:
|
||||||
//
|
//
|
||||||
// var v []struct {
|
// var v []struct {
|
||||||
// PublicKey string `json:"public_key,omitempty"`
|
// PublicKey []byte `json:"public_key,omitempty"`
|
||||||
// Count int `json:"count,omitempty"`
|
// Count int `json:"count,omitempty"`
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
|
@ -285,7 +285,7 @@ func (mq *MachineQuery) GroupBy(field string, fields ...string) *MachineGroupBy
|
||||||
// Example:
|
// Example:
|
||||||
//
|
//
|
||||||
// var v []struct {
|
// var v []struct {
|
||||||
// PublicKey string `json:"public_key,omitempty"`
|
// PublicKey []byte `json:"public_key,omitempty"`
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// client.Machine.Query().
|
// client.Machine.Query().
|
||||||
|
|
42
internal/db/ent/machine_update.go
generated
42
internal/db/ent/machine_update.go
generated
|
@ -28,15 +28,21 @@ func (mu *MachineUpdate) Where(ps ...predicate.Machine) *MachineUpdate {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetPublicKey sets the "public_key" field.
|
// SetPublicKey sets the "public_key" field.
|
||||||
func (mu *MachineUpdate) SetPublicKey(s string) *MachineUpdate {
|
func (mu *MachineUpdate) SetPublicKey(b []byte) *MachineUpdate {
|
||||||
mu.mutation.SetPublicKey(s)
|
mu.mutation.SetPublicKey(b)
|
||||||
return mu
|
return mu
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetNillablePublicKey sets the "public_key" field if the given value is not nil.
|
// SetCreatedAt sets the "created_at" field.
|
||||||
func (mu *MachineUpdate) SetNillablePublicKey(s *string) *MachineUpdate {
|
func (mu *MachineUpdate) SetCreatedAt(s string) *MachineUpdate {
|
||||||
|
mu.mutation.SetCreatedAt(s)
|
||||||
|
return mu
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
|
||||||
|
func (mu *MachineUpdate) SetNillableCreatedAt(s *string) *MachineUpdate {
|
||||||
if s != nil {
|
if s != nil {
|
||||||
mu.SetPublicKey(*s)
|
mu.SetCreatedAt(*s)
|
||||||
}
|
}
|
||||||
return mu
|
return mu
|
||||||
}
|
}
|
||||||
|
@ -83,7 +89,10 @@ func (mu *MachineUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if value, ok := mu.mutation.PublicKey(); ok {
|
if value, ok := mu.mutation.PublicKey(); ok {
|
||||||
_spec.SetField(machine.FieldPublicKey, field.TypeString, value)
|
_spec.SetField(machine.FieldPublicKey, field.TypeBytes, value)
|
||||||
|
}
|
||||||
|
if value, ok := mu.mutation.CreatedAt(); ok {
|
||||||
|
_spec.SetField(machine.FieldCreatedAt, field.TypeString, value)
|
||||||
}
|
}
|
||||||
if n, err = sqlgraph.UpdateNodes(ctx, mu.driver, _spec); err != nil {
|
if n, err = sqlgraph.UpdateNodes(ctx, mu.driver, _spec); err != nil {
|
||||||
if _, ok := err.(*sqlgraph.NotFoundError); ok {
|
if _, ok := err.(*sqlgraph.NotFoundError); ok {
|
||||||
|
@ -106,15 +115,21 @@ type MachineUpdateOne struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetPublicKey sets the "public_key" field.
|
// SetPublicKey sets the "public_key" field.
|
||||||
func (muo *MachineUpdateOne) SetPublicKey(s string) *MachineUpdateOne {
|
func (muo *MachineUpdateOne) SetPublicKey(b []byte) *MachineUpdateOne {
|
||||||
muo.mutation.SetPublicKey(s)
|
muo.mutation.SetPublicKey(b)
|
||||||
return muo
|
return muo
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetNillablePublicKey sets the "public_key" field if the given value is not nil.
|
// SetCreatedAt sets the "created_at" field.
|
||||||
func (muo *MachineUpdateOne) SetNillablePublicKey(s *string) *MachineUpdateOne {
|
func (muo *MachineUpdateOne) SetCreatedAt(s string) *MachineUpdateOne {
|
||||||
|
muo.mutation.SetCreatedAt(s)
|
||||||
|
return muo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
|
||||||
|
func (muo *MachineUpdateOne) SetNillableCreatedAt(s *string) *MachineUpdateOne {
|
||||||
if s != nil {
|
if s != nil {
|
||||||
muo.SetPublicKey(*s)
|
muo.SetCreatedAt(*s)
|
||||||
}
|
}
|
||||||
return muo
|
return muo
|
||||||
}
|
}
|
||||||
|
@ -191,7 +206,10 @@ func (muo *MachineUpdateOne) sqlSave(ctx context.Context) (_node *Machine, err e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if value, ok := muo.mutation.PublicKey(); ok {
|
if value, ok := muo.mutation.PublicKey(); ok {
|
||||||
_spec.SetField(machine.FieldPublicKey, field.TypeString, value)
|
_spec.SetField(machine.FieldPublicKey, field.TypeBytes, value)
|
||||||
|
}
|
||||||
|
if value, ok := muo.mutation.CreatedAt(); ok {
|
||||||
|
_spec.SetField(machine.FieldCreatedAt, field.TypeString, value)
|
||||||
}
|
}
|
||||||
_node = &Machine{config: muo.config}
|
_node = &Machine{config: muo.config}
|
||||||
_spec.Assign = _node.assignValues
|
_spec.Assign = _node.assignValues
|
||||||
|
|
3
internal/db/ent/migrate/schema.go
generated
3
internal/db/ent/migrate/schema.go
generated
|
@ -11,7 +11,8 @@ var (
|
||||||
// MachinesColumns holds the columns for the "machines" table.
|
// MachinesColumns holds the columns for the "machines" table.
|
||||||
MachinesColumns = []*schema.Column{
|
MachinesColumns = []*schema.Column{
|
||||||
{Name: "id", Type: field.TypeString},
|
{Name: "id", Type: field.TypeString},
|
||||||
{Name: "public_key", Type: field.TypeString},
|
{Name: "public_key", Type: field.TypeBytes},
|
||||||
|
{Name: "created_at", Type: field.TypeString, Default: "2025-02-23T06:06:02Z"},
|
||||||
}
|
}
|
||||||
// MachinesTable holds the schema information for the "machines" table.
|
// MachinesTable holds the schema information for the "machines" table.
|
||||||
MachinesTable = &schema.Table{
|
MachinesTable = &schema.Table{
|
||||||
|
|
68
internal/db/ent/mutation.go
generated
68
internal/db/ent/mutation.go
generated
|
@ -32,7 +32,8 @@ type MachineMutation struct {
|
||||||
op Op
|
op Op
|
||||||
typ string
|
typ string
|
||||||
id *string
|
id *string
|
||||||
public_key *string
|
public_key *[]byte
|
||||||
|
created_at *string
|
||||||
clearedFields map[string]struct{}
|
clearedFields map[string]struct{}
|
||||||
done bool
|
done bool
|
||||||
oldValue func(context.Context) (*Machine, error)
|
oldValue func(context.Context) (*Machine, error)
|
||||||
|
@ -144,12 +145,12 @@ func (m *MachineMutation) IDs(ctx context.Context) ([]string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetPublicKey sets the "public_key" field.
|
// SetPublicKey sets the "public_key" field.
|
||||||
func (m *MachineMutation) SetPublicKey(s string) {
|
func (m *MachineMutation) SetPublicKey(b []byte) {
|
||||||
m.public_key = &s
|
m.public_key = &b
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublicKey returns the value of the "public_key" field in the mutation.
|
// PublicKey returns the value of the "public_key" field in the mutation.
|
||||||
func (m *MachineMutation) PublicKey() (r string, exists bool) {
|
func (m *MachineMutation) PublicKey() (r []byte, exists bool) {
|
||||||
v := m.public_key
|
v := m.public_key
|
||||||
if v == nil {
|
if v == nil {
|
||||||
return
|
return
|
||||||
|
@ -160,7 +161,7 @@ func (m *MachineMutation) PublicKey() (r string, exists bool) {
|
||||||
// OldPublicKey returns the old "public_key" field's value of the Machine entity.
|
// OldPublicKey returns the old "public_key" field's value of the Machine entity.
|
||||||
// If the Machine object wasn't provided to the builder, the object is fetched from the database.
|
// If the Machine object wasn't provided to the builder, the object is fetched from the database.
|
||||||
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||||
func (m *MachineMutation) OldPublicKey(ctx context.Context) (v string, err error) {
|
func (m *MachineMutation) OldPublicKey(ctx context.Context) (v []byte, err error) {
|
||||||
if !m.op.Is(OpUpdateOne) {
|
if !m.op.Is(OpUpdateOne) {
|
||||||
return v, errors.New("OldPublicKey is only allowed on UpdateOne operations")
|
return v, errors.New("OldPublicKey is only allowed on UpdateOne operations")
|
||||||
}
|
}
|
||||||
|
@ -179,6 +180,42 @@ func (m *MachineMutation) ResetPublicKey() {
|
||||||
m.public_key = nil
|
m.public_key = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetCreatedAt sets the "created_at" field.
|
||||||
|
func (m *MachineMutation) SetCreatedAt(s string) {
|
||||||
|
m.created_at = &s
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAt returns the value of the "created_at" field in the mutation.
|
||||||
|
func (m *MachineMutation) CreatedAt() (r string, exists bool) {
|
||||||
|
v := m.created_at
|
||||||
|
if v == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return *v, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// OldCreatedAt returns the old "created_at" field's value of the Machine entity.
|
||||||
|
// If the Machine object wasn't provided to the builder, the object is fetched from the database.
|
||||||
|
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||||
|
func (m *MachineMutation) OldCreatedAt(ctx context.Context) (v string, err error) {
|
||||||
|
if !m.op.Is(OpUpdateOne) {
|
||||||
|
return v, errors.New("OldCreatedAt is only allowed on UpdateOne operations")
|
||||||
|
}
|
||||||
|
if m.id == nil || m.oldValue == nil {
|
||||||
|
return v, errors.New("OldCreatedAt requires an ID field in the mutation")
|
||||||
|
}
|
||||||
|
oldValue, err := m.oldValue(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return v, fmt.Errorf("querying old value for OldCreatedAt: %w", err)
|
||||||
|
}
|
||||||
|
return oldValue.CreatedAt, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetCreatedAt resets all changes to the "created_at" field.
|
||||||
|
func (m *MachineMutation) ResetCreatedAt() {
|
||||||
|
m.created_at = nil
|
||||||
|
}
|
||||||
|
|
||||||
// Where appends a list predicates to the MachineMutation builder.
|
// Where appends a list predicates to the MachineMutation builder.
|
||||||
func (m *MachineMutation) Where(ps ...predicate.Machine) {
|
func (m *MachineMutation) Where(ps ...predicate.Machine) {
|
||||||
m.predicates = append(m.predicates, ps...)
|
m.predicates = append(m.predicates, ps...)
|
||||||
|
@ -213,10 +250,13 @@ func (m *MachineMutation) Type() string {
|
||||||
// order to get all numeric fields that were incremented/decremented, call
|
// order to get all numeric fields that were incremented/decremented, call
|
||||||
// AddedFields().
|
// AddedFields().
|
||||||
func (m *MachineMutation) Fields() []string {
|
func (m *MachineMutation) Fields() []string {
|
||||||
fields := make([]string, 0, 1)
|
fields := make([]string, 0, 2)
|
||||||
if m.public_key != nil {
|
if m.public_key != nil {
|
||||||
fields = append(fields, machine.FieldPublicKey)
|
fields = append(fields, machine.FieldPublicKey)
|
||||||
}
|
}
|
||||||
|
if m.created_at != nil {
|
||||||
|
fields = append(fields, machine.FieldCreatedAt)
|
||||||
|
}
|
||||||
return fields
|
return fields
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,6 +267,8 @@ func (m *MachineMutation) Field(name string) (ent.Value, bool) {
|
||||||
switch name {
|
switch name {
|
||||||
case machine.FieldPublicKey:
|
case machine.FieldPublicKey:
|
||||||
return m.PublicKey()
|
return m.PublicKey()
|
||||||
|
case machine.FieldCreatedAt:
|
||||||
|
return m.CreatedAt()
|
||||||
}
|
}
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
@ -238,6 +280,8 @@ func (m *MachineMutation) OldField(ctx context.Context, name string) (ent.Value,
|
||||||
switch name {
|
switch name {
|
||||||
case machine.FieldPublicKey:
|
case machine.FieldPublicKey:
|
||||||
return m.OldPublicKey(ctx)
|
return m.OldPublicKey(ctx)
|
||||||
|
case machine.FieldCreatedAt:
|
||||||
|
return m.OldCreatedAt(ctx)
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("unknown Machine field %s", name)
|
return nil, fmt.Errorf("unknown Machine field %s", name)
|
||||||
}
|
}
|
||||||
|
@ -248,12 +292,19 @@ func (m *MachineMutation) OldField(ctx context.Context, name string) (ent.Value,
|
||||||
func (m *MachineMutation) SetField(name string, value ent.Value) error {
|
func (m *MachineMutation) SetField(name string, value ent.Value) error {
|
||||||
switch name {
|
switch name {
|
||||||
case machine.FieldPublicKey:
|
case machine.FieldPublicKey:
|
||||||
v, ok := value.(string)
|
v, ok := value.([]byte)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||||
}
|
}
|
||||||
m.SetPublicKey(v)
|
m.SetPublicKey(v)
|
||||||
return nil
|
return nil
|
||||||
|
case machine.FieldCreatedAt:
|
||||||
|
v, ok := value.(string)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||||
|
}
|
||||||
|
m.SetCreatedAt(v)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("unknown Machine field %s", name)
|
return fmt.Errorf("unknown Machine field %s", name)
|
||||||
}
|
}
|
||||||
|
@ -306,6 +357,9 @@ func (m *MachineMutation) ResetField(name string) error {
|
||||||
case machine.FieldPublicKey:
|
case machine.FieldPublicKey:
|
||||||
m.ResetPublicKey()
|
m.ResetPublicKey()
|
||||||
return nil
|
return nil
|
||||||
|
case machine.FieldCreatedAt:
|
||||||
|
m.ResetCreatedAt()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("unknown Machine field %s", name)
|
return fmt.Errorf("unknown Machine field %s", name)
|
||||||
}
|
}
|
||||||
|
|
11
internal/db/ent/runtime.go
generated
11
internal/db/ent/runtime.go
generated
|
@ -2,8 +2,19 @@
|
||||||
|
|
||||||
package ent
|
package ent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.rgst.io/homelab/klefki/internal/db/ent/machine"
|
||||||
|
"git.rgst.io/homelab/klefki/internal/db/ent/schema"
|
||||||
|
)
|
||||||
|
|
||||||
// The init function reads all schema descriptors with runtime code
|
// The init function reads all schema descriptors with runtime code
|
||||||
// (default values, validators, hooks and policies) and stitches it
|
// (default values, validators, hooks and policies) and stitches it
|
||||||
// to their package variables.
|
// to their package variables.
|
||||||
func init() {
|
func init() {
|
||||||
|
machineFields := schema.Machine{}.Fields()
|
||||||
|
_ = machineFields
|
||||||
|
// machineDescCreatedAt is the schema descriptor for created_at field.
|
||||||
|
machineDescCreatedAt := machineFields[2].Descriptor()
|
||||||
|
// machine.DefaultCreatedAt holds the default value on creation for the created_at field.
|
||||||
|
machine.DefaultCreatedAt = machineDescCreatedAt.Default.(string)
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
package schema
|
package schema
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
"entgo.io/ent"
|
"entgo.io/ent"
|
||||||
"entgo.io/ent/schema/field"
|
"entgo.io/ent/schema/field"
|
||||||
)
|
)
|
||||||
|
@ -31,6 +33,7 @@ type Machine struct {
|
||||||
func (Machine) Fields() []ent.Field {
|
func (Machine) Fields() []ent.Field {
|
||||||
return []ent.Field{
|
return []ent.Field{
|
||||||
field.String("id").Comment("Fingerprint of the public key"),
|
field.String("id").Comment("Fingerprint of the public key"),
|
||||||
field.String("public_key").Comment("Public key of the machine"),
|
field.Bytes("public_key").Comment("Public key of the machine"),
|
||||||
|
field.String("created_at").Comment("When this machine was added in UTC").Default(time.Now().UTC().Format(time.RFC3339)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
123
internal/machines/machine.go
Normal file
123
internal/machines/machine.go
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
// Copyright (C) 2025 klefki contributors
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0
|
||||||
|
|
||||||
|
package machines
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ed25519"
|
||||||
|
"crypto/sha256"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/pem"
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"git.rgst.io/homelab/klefki/internal/db/ent"
|
||||||
|
)
|
||||||
|
|
||||||
|
// getFingerprint returns a fingerprint of the key.
|
||||||
|
func getFingerprint(pub ed25519.PublicKey) (string, error) {
|
||||||
|
hasher := sha256.New()
|
||||||
|
if _, err := hasher.Write(pub); err != nil {
|
||||||
|
return "", fmt.Errorf("failed to hash provided public key: %w", err)
|
||||||
|
}
|
||||||
|
return "SHA256:" + base64.RawStdEncoding.EncodeToString(hasher.Sum(nil)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Machine is a known machine containing PKI used by it.
|
||||||
|
type Machine struct {
|
||||||
|
fprintOnce sync.Once
|
||||||
|
fingerprint string
|
||||||
|
|
||||||
|
// PublicKey is the public key for this machine. This is always set
|
||||||
|
// when initialized through [MachineFromDB] or [Machine].
|
||||||
|
PublicKey ed25519.PublicKey
|
||||||
|
|
||||||
|
// PrivateKye is the private key for this machine. This is normally
|
||||||
|
// not set instead only when [NewMachine] is called.
|
||||||
|
PrivateKey ed25519.PrivateKey
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns a string version of the machine containing only the
|
||||||
|
// fingerprint, if obtainable.
|
||||||
|
func (m *Machine) String() string {
|
||||||
|
fprint, err := m.Fingerprint()
|
||||||
|
if err != nil {
|
||||||
|
fprint = fmt.Sprintf("<failed to calculate: %v>", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Machine<" + fprint + ">"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fingerprint returns the fingerprint of the machine as calculated from
|
||||||
|
// the public key. This is calculated exactly once. If m.fingerprint is
|
||||||
|
// already set, this immediately returns that value instead of
|
||||||
|
// calculating it.
|
||||||
|
func (m *Machine) Fingerprint() (string, error) {
|
||||||
|
var err error
|
||||||
|
m.fprintOnce.Do(func() {
|
||||||
|
if m.fingerprint != "" {
|
||||||
|
return // NOOP if already set.
|
||||||
|
}
|
||||||
|
m.fingerprint, err = getFingerprint(m.PublicKey)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to calculate fingerprint: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return m.fingerprint, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncodePrivateKey returns a X509 PEM encoded private key for the
|
||||||
|
// ed25519 private key of this machine.
|
||||||
|
func (m *Machine) EncodePrivateKey() (string, error) {
|
||||||
|
privKey, err := x509.MarshalPKCS8PrivateKey(m.PrivateKey)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to marshal private key: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
encoded := pem.EncodeToMemory(&pem.Block{Type: "ED25519 PRIVATE KEY", Bytes: privKey})
|
||||||
|
return string(encoded), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncodePublicKey returns a X509 PEM encoded public key for the
|
||||||
|
// ed25519 public key of this machine.
|
||||||
|
func (m *Machine) EncodePublicKey() (string, error) {
|
||||||
|
privKey, err := x509.MarshalPKIXPublicKey(m.PublicKey)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to marshal public key: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
encoded := pem.EncodeToMemory(&pem.Block{Type: "ED25519 PUBLIC KEY", Bytes: privKey})
|
||||||
|
return string(encoded), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MachineFromDB creates a [Machine] from a [ent.Machine]. Note that the
|
||||||
|
// private key will never be set in this case as it is no longer known.
|
||||||
|
func MachineFromDB(m *ent.Machine) *Machine {
|
||||||
|
return &Machine{fingerprint: m.ID, PublicKey: ed25519.PublicKey(m.PublicKey)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMachine creates a new [Machine] with the private key included.
|
||||||
|
func NewMachine() (*Machine, error) {
|
||||||
|
pub, priv, err := ed25519.GenerateKey(nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to generate ed25519 key: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Machine{PublicKey: pub, PrivateKey: priv}, nil
|
||||||
|
}
|
20
internal/machines/machines.go
Normal file
20
internal/machines/machines.go
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright (C) 2025 klefki contributors
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0
|
||||||
|
|
||||||
|
// Package machines contains all of the code for creating and managing
|
||||||
|
// machines.
|
||||||
|
package machines
|
|
@ -7,12 +7,11 @@
|
||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
reflect "reflect"
|
|
||||||
unsafe "unsafe"
|
|
||||||
|
|
||||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||||
_ "google.golang.org/protobuf/types/gofeaturespb"
|
_ "google.golang.org/protobuf/types/gofeaturespb"
|
||||||
|
reflect "reflect"
|
||||||
|
unsafe "unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -8,7 +8,6 @@ package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
context "context"
|
context "context"
|
||||||
|
|
||||||
grpc "google.golang.org/grpc"
|
grpc "google.golang.org/grpc"
|
||||||
codes "google.golang.org/grpc/codes"
|
codes "google.golang.org/grpc/codes"
|
||||||
status "google.golang.org/grpc/status"
|
status "google.golang.org/grpc/status"
|
||||||
|
|
|
@ -46,10 +46,16 @@ func (s *Server) Run(_ context.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("starting gRPC server on %s\n", lis.Addr())
|
fmt.Printf("starting gRPC server on %s\n", lis.Addr())
|
||||||
|
|
||||||
return s.gs.Serve(lis)
|
return s.gs.Serve(lis)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetKey implements the GetKey request
|
||||||
|
func (s *Server) GetKey(_ context.Context, _ *pbgrpcv1.GetKeyRequest) (*pbgrpcv1.GetKeyResponse, error) {
|
||||||
|
resp := &pbgrpcv1.GetKeyResponse{}
|
||||||
|
resp.SetKey("hello-world")
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Close closes the server
|
// Close closes the server
|
||||||
func (s *Server) Close(_ context.Context) error {
|
func (s *Server) Close(_ context.Context) error {
|
||||||
if s.gs == nil {
|
if s.gs == nil {
|
||||||
|
|
3
stencil.lock
generated
3
stencil.lock
generated
|
@ -57,6 +57,9 @@ files:
|
||||||
- name: cmd/klefki/klefki.go
|
- name: cmd/klefki/klefki.go
|
||||||
template: cmd/$name/name.go.tpl
|
template: cmd/$name/name.go.tpl
|
||||||
module: github.com/rgst-io/stencil-golang
|
module: github.com/rgst-io/stencil-golang
|
||||||
|
- name: cmd/klefkictl/klefkictl.go
|
||||||
|
template: cmd/$name/name.go.tpl
|
||||||
|
module: github.com/rgst-io/stencil-golang
|
||||||
- name: go.mod
|
- name: go.mod
|
||||||
template: go.mod.tpl
|
template: go.mod.tpl
|
||||||
module: github.com/rgst-io/stencil-golang
|
module: github.com/rgst-io/stencil-golang
|
||||||
|
|
|
@ -4,5 +4,8 @@ arguments:
|
||||||
vcs_host: git.rgst.io
|
vcs_host: git.rgst.io
|
||||||
org: homelab
|
org: homelab
|
||||||
license: AGPL-3.0
|
license: AGPL-3.0
|
||||||
|
commands:
|
||||||
|
- klefki
|
||||||
|
- klefkictl
|
||||||
modules:
|
modules:
|
||||||
- name: github.com/rgst-io/stencil-golang
|
- name: github.com/rgst-io/stencil-golang
|
||||||
|
|
Loading…
Add table
Reference in a new issue