From 870ce0d764314b208ce3bc8d9f787b950850372f Mon Sep 17 00:00:00 2001 From: Hiram Chirino Date: Sun, 12 Nov 2023 12:56:04 -0500 Subject: [PATCH] precursor for #1628: auto create a reg-key for the admin user when the the apiserver is started in developer mode. * update the nexd container messages to use reg-keys to start nexd. Signed-off-by: Hiram Chirino --- hack/update-ca.sh | 13 +- internal/database/database.go | 2 + .../migration_20231113_0000/20231113-0000.go | 165 ++++++++++++++++++ 3 files changed, 174 insertions(+), 6 deletions(-) create mode 100644 internal/database/migration_20231113_0000/20231113-0000.go diff --git a/hack/update-ca.sh b/hack/update-ca.sh index 6f012277c..ab0c0aab8 100644 --- a/hack/update-ca.sh +++ b/hack/update-ca.sh @@ -21,16 +21,16 @@ fi if [ "$1" = "prod" ]; then cat << EOF > ~/.bash_history NEXD_LOGLEVEL=debug nexd --service-url https://qa.nexodus.io -NEXD_LOGLEVEL=debug nexd --service-url https://try.nexodus.io +NEXD_LOGLEVEL=debug nexd nexd --service-url https://qa.nexodus.io -nexd --service-url https://try.nexodus.io +nexd EOF cat << EOF > ~/.motd To connect this container to the nexodus network, try running: - nexd --service-url https://try.nexodus.io + nexd Press the up arrow to get this command from bash history. @@ -40,17 +40,18 @@ else cat << EOF > ~/.bash_history NEXD_LOGLEVEL=debug nexd --service-url https://try.nexodus.io NEXD_LOGLEVEL=debug nexd --service-url https://qa.nexodus.io -NEXD_LOGLEVEL=debug nexd --service-url https://try.nexodus.127.0.0.1.nip.io --username admin --password floofykittens +NEXD_LOGLEVEL=debug nexd --service-url https://try.nexodus.127.0.0.1.nip.io --reg-key RT:dev-admin-reg-key nexd --service-url https://try.nexodus.io nexd --service-url https://qa.nexodus.io -nexd --service-url https://try.nexodus.127.0.0.1.nip.io --username admin --password floofykittens +nexctl --service-url https://try.nexodus.127.0.0.1.nip.io --username admin --password floofykittens +nexd --service-url https://try.nexodus.127.0.0.1.nip.io --reg-key RT:dev-admin-reg-key EOF cat << EOF > ~/.motd To connect this container to the nexodus network, try running: - nexd --service-url https://try.nexodus.127.0.0.1.nip.io --username admin --password floofykittens + nexd --service-url https://try.nexodus.127.0.0.1.nip.io --reg-key RT:dev-admin-reg-key Commands for using a dev service, qa.nexodus.io, or try.nexodus.io are in bash history. diff --git a/internal/database/database.go b/internal/database/database.go index 1a4bd14fc..396b6544b 100644 --- a/internal/database/database.go +++ b/internal/database/database.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "github.com/nexodus-io/nexodus/internal/database/migration_20231108_0000" + "github.com/nexodus-io/nexodus/internal/database/migration_20231113_0000" "github.com/nexodus-io/nexodus/internal/database/migration_20231031_0000" "github.com/nexodus-io/nexodus/internal/database/migration_20231106_0000" @@ -97,6 +98,7 @@ func Migrations() *migrations.Migrations { migration_20231106_0000.New(), migration_20231107_0000.New(), migration_20231108_0000.New(), + migration_20231113_0000.New(), }, } } diff --git a/internal/database/migration_20231113_0000/20231113-0000.go b/internal/database/migration_20231113_0000/20231113-0000.go new file mode 100644 index 000000000..5b95be365 --- /dev/null +++ b/internal/database/migration_20231113_0000/20231113-0000.go @@ -0,0 +1,165 @@ +package migration_20231113_0000 + +import ( + "fmt" + "github.com/go-gormigrate/gormigrate/v2" + "github.com/google/uuid" + . "github.com/nexodus-io/nexodus/internal/database/migrations" + "gorm.io/gorm" + "os" + "time" +) + +type Base struct { + ID uuid.UUID `gorm:"type:uuid;primary_key;"` + CreatedAt time.Time + UpdatedAt time.Time + DeletedAt gorm.DeletedAt +} + +type User struct { + Base + IdpID string + UserName string + Organizations []*Organization `gorm:"many2many:user_organizations"` +} + +type Organization struct { + Base + OwnerID uuid.UUID + Name string + Description string + + Users []*User `gorm:"many2many:user_organizations;"` +} + +type VPC struct { + Base + OrganizationID uuid.UUID `json:"organization_id"` + Description string `json:"description"` + PrivateCidr bool `json:"private_cidr"` + Ipv4Cidr string `json:"ipv4_cidr"` + Ipv6Cidr string `json:"ipv6_cidr"` + + Organization *Organization `json:"-"` +} + +type SecurityGroup struct { + Base + Description string `json:"description"` + VpcId uuid.UUID `json:"vpc_id"` + OrganizationID uuid.UUID `json:"-"` // Denormalized from the VPC record for performance + InboundRules []SecurityRule `json:"inbound_rules,omitempty" gorm:"type:JSONB; serializer:json"` + OutboundRules []SecurityRule `json:"outbound_rules,omitempty" gorm:"type:JSONB; serializer:json"` + Revision uint64 `json:"revision" gorm:"type:bigserial;index:"` +} +type SecurityRule struct { + IpProtocol string `json:"ip_protocol"` + FromPort int64 `json:"from_port"` + ToPort int64 `json:"to_port"` + IpRanges []string `json:"ip_ranges,omitempty"` +} + +type RegKey struct { + Base + OwnerID uuid.UUID `json:"owner_id,omitempty"` + VpcID uuid.UUID `json:"vpc_id,omitempty"` + OrganizationID uuid.UUID `json:"-"` // OrganizationID is denormalized from the VPC record for performance + BearerToken string `json:"bearer_token,omitempty"` // BearerToken is the bearer token the client should use to authenticate the device registration request. + Description string `json:"description,omitempty"` + DeviceId *uuid.UUID `json:"device_id,omitempty"` // DeviceId is set if the RegKey was created for single use + ExpiresAt *time.Time `json:"expires_at,omitempty"` // ExpiresAt is optional, if set the registration key is only valid until the ExpiresAt time. +} + +const ( + defaultIPAMv4Cidr = "100.64.0.0/10" + defaultIPAMv6Cidr = "200::/64" +) + +func New() *gormigrate.Migration { + migrationId := "20231113-0000" + return CreateMigrationFromActions(migrationId, + func(tx *gorm.DB, apply bool) error { + if !(apply && os.Getenv("NEXAPI_ENVIRONMENT") == "development") { + return nil + } + return tx.Transaction(func(tx *gorm.DB) error { + + // do we need to create the admin user? + var count int64 + adminIdpId := "01578c9e-8e76-46a4-b2b2-50788cec2ccd" + if res := tx.Model(&User{}).Where("idp_id = ?", adminIdpId).Count(&count); res.Error != nil { + return res.Error + } + if count != 0 { + return nil + } + + user := &User{ + Base: Base{ + ID: uuid.New(), + }, + IdpID: adminIdpId, + UserName: "admin", + } + if res := tx.Create(user); res.Error != nil { + return res.Error + } + if res := tx.Create(&Organization{ + Base: Base{ + ID: user.ID, + }, + OwnerID: user.ID, + Name: user.UserName, + Description: fmt.Sprintf("%s's organization", user.UserName), + Users: []*User{{ + Base: Base{ + ID: user.ID, + }, + }}, + }); res.Error != nil { + return res.Error + } + if res := tx.Create(&VPC{ + Base: Base{ + ID: user.ID, + }, + OrganizationID: user.ID, + Description: "default vpc", + PrivateCidr: false, + Ipv4Cidr: defaultIPAMv4Cidr, + Ipv6Cidr: defaultIPAMv6Cidr, + }); res.Error != nil { + return res.Error + } + + if res := tx.Create(&SecurityGroup{ + Base: Base{ + ID: user.ID, + }, + VpcId: user.ID, + OrganizationID: user.ID, + Description: "default vpc security group", + InboundRules: []SecurityRule{}, + OutboundRules: []SecurityRule{}, + }); res.Error != nil { + return res.Error + } + if res := tx.Create(&RegKey{ + Base: Base{ + ID: user.ID, + }, + OwnerID: user.ID, + VpcID: user.ID, + OrganizationID: user.ID, + Description: "well known development reg key", + BearerToken: "RT:dev-admin-reg-key", + }); res.Error != nil { + return res.Error + } + + return nil + }) + }, + ) +}