mirror of
https://github.com/kittywitch/nixfiles.git
synced 2026-02-09 12:29:19 -08:00
[PULUMI] CA provider
This commit is contained in:
parent
64507a991c
commit
b224bd4935
27 changed files with 2727 additions and 313 deletions
133
provider-openssh/pkg/provider/provider.go
Normal file
133
provider-openssh/pkg/provider/provider.go
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
package provider
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/ed25519"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/blang/semver"
|
||||
p "github.com/pulumi/pulumi-go-provider"
|
||||
"github.com/pulumi/pulumi-go-provider/infer"
|
||||
"github.com/pulumi/pulumi-go-provider/integration"
|
||||
"github.com/pulumi/pulumi-go-provider/middleware/schema"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/common/tokens"
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
func Provider() p.Provider {
|
||||
return infer.Provider(infer.Options{
|
||||
Metadata: schema.Metadata{
|
||||
DisplayName: "OpenSSH Cert",
|
||||
Description: "I hope the people who worked on pulumi stub their toe every day",
|
||||
Keywords: []string{
|
||||
"pulumi",
|
||||
"openssh",
|
||||
"category/utility",
|
||||
"kind/native",
|
||||
},
|
||||
Homepage: "https://kittywit.ch",
|
||||
License: "WTFPL",
|
||||
Repository: "https://github.com/kittywitch/kittywitch",
|
||||
Publisher: "Pulumi",
|
||||
LogoURL: "https://raw.githubusercontent.com/pulumi/pulumi-command/master/assets/logo.svg",
|
||||
// This contains language specific details for generating the provider's SDKs
|
||||
LanguageMap: map[string]any{
|
||||
"go": map[string]any{
|
||||
"generateResourceContainerTypes": true,
|
||||
"importBasePath": "github.com/kittywitch/provider-opensshcertificate/sdk/go/provider",
|
||||
},
|
||||
},
|
||||
},
|
||||
Resources: []infer.InferredResource{infer.Resource[*OpenSSHCertificate, OpenSSHCertificateArgs, OpenSSHCertificateState]()},
|
||||
ModuleMap: map[tokens.ModuleName]tokens.ModuleName{
|
||||
"opensshcertificate": "index",
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
type OpenSSHCertificate struct{}
|
||||
|
||||
type OpenSSHCertificateArgs struct {
|
||||
Algorithm string `pulumi:"algorithm"`
|
||||
Kind string `pulumi:"kind"`
|
||||
Hostname string `pulumi:"hostname"`
|
||||
CAPrivateKey string `pulumi:"cakey"`
|
||||
UserPrivateKey string `pulumi:"userkey"`
|
||||
Duration string `pulumi:"duration"`
|
||||
}
|
||||
type OpenSSHCertificateState struct {
|
||||
OpenSSHCertificateArgs
|
||||
Content string `pulumi:"content"`
|
||||
}
|
||||
|
||||
func (c *OpenSSHCertificate) Create(ctx p.Context, name string, input OpenSSHCertificateArgs, preview bool) (string, OpenSSHCertificateState, error) {
|
||||
state := OpenSSHCertificateState{OpenSSHCertificateArgs: input}
|
||||
if preview {
|
||||
return name, state, nil
|
||||
}
|
||||
caPrivateKeyInterface, err := ssh.ParseRawPrivateKey([]byte(input.CAPrivateKey))
|
||||
if err != nil {
|
||||
return name, state, err
|
||||
}
|
||||
userPrivateKeyInterface, err := ssh.ParseRawPrivateKey([]byte(input.UserPrivateKey))
|
||||
if err != nil {
|
||||
return name, state, err
|
||||
}
|
||||
var signer ssh.Signer
|
||||
var userPublicKey crypto.PublicKey
|
||||
caPrivateKey := caPrivateKeyInterface.(*rsa.PrivateKey)
|
||||
switch input.Algorithm {
|
||||
case "rsa":
|
||||
userPrivateKey := userPrivateKeyInterface.(*rsa.PrivateKey)
|
||||
userPublicKey = userPrivateKey.Public()
|
||||
signer, err = ssh.NewSignerFromKey(caPrivateKey)
|
||||
case "ed25519":
|
||||
userPrivateKey := userPrivateKeyInterface.(*ed25519.PrivateKey)
|
||||
userPublicKey = userPrivateKey.Public()
|
||||
signer, err = ssh.NewSignerFromKey(caPrivateKey)
|
||||
default:
|
||||
panic("unsupported key algorithm")
|
||||
}
|
||||
if err != nil {
|
||||
return name, state, err
|
||||
}
|
||||
var cert ssh.Certificate
|
||||
switch input.Kind {
|
||||
case "user":
|
||||
cert.CertType = ssh.UserCert
|
||||
case "host":
|
||||
cert.CertType = ssh.HostCert
|
||||
default:
|
||||
panic("unsupported key kind")
|
||||
}
|
||||
cert.Key, err = ssh.NewPublicKey(userPublicKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
now := time.Now()
|
||||
nowunix := uint64(now.Unix())
|
||||
cert.Serial = nowunix
|
||||
cert.KeyId = input.Hostname
|
||||
cert.ValidPrincipals = []string{input.Hostname}
|
||||
cert.ValidAfter = nowunix
|
||||
duration, err := time.ParseDuration(input.Duration)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
cert.ValidBefore = uint64(now.Add(duration).Unix())
|
||||
err = cert.SignCert(rand.Reader, signer)
|
||||
state.Content = string(ssh.MarshalAuthorizedKey(&cert))
|
||||
return name, state, nil
|
||||
}
|
||||
|
||||
func Schema(version string) (string, error) {
|
||||
if strings.HasPrefix(version, "v") {
|
||||
version = version[1:]
|
||||
}
|
||||
s, err := integration.NewServer("opensshcertificate", semver.MustParse(version), Provider()).
|
||||
GetSchema(p.GetSchemaRequest{})
|
||||
return s.Schema, err
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue