Skip to content

Commit

Permalink
various fixes, make member pool_id optional
Browse files Browse the repository at this point in the history
  • Loading branch information
notandy committed Aug 1, 2024
1 parent 02cc7dc commit 67f3d35
Show file tree
Hide file tree
Showing 10 changed files with 96 additions and 50 deletions.
1 change: 0 additions & 1 deletion internal/client/domain.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ func (*DomainDelete) Execute(_ []string) error {
}

func (*DomainSet) Execute(_ []string) error {

if DomainOptions.DomainSet.Disable && DomainOptions.DomainSet.Enable {
return fmt.Errorf("cannot enable and disable domain at the same time")
}
Expand Down
56 changes: 49 additions & 7 deletions internal/client/member.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package client

import (
"fmt"

"github.com/go-openapi/strfmt"

"github.com/sapcc/andromeda/client/members"
Expand All @@ -28,6 +30,7 @@ var MemberOptions struct {
MemberShow `command:"show" description:"Show Member"`
MemberCreate `command:"create" description:"Create Member"`
MemberDelete `command:"delete" description:"Delete Member"`
MemberSet `command:"set" description:"Update Member"`
}

type MemberList struct {
Expand All @@ -38,7 +41,6 @@ type MemberList struct {

type MemberShow struct {
PositionalMemberShow struct {
PoolID strfmt.UUID `description:"UUID of the pool"`
MemberID strfmt.UUID `description:"UUID of the member"`
} `positional-args:"yes" required:"yes"`
}
Expand All @@ -56,9 +58,19 @@ type MemberCreate struct {

type MemberDelete struct {
PositionalMemberDelete struct {
PoolID strfmt.UUID `description:"UUID of the pool"`
UUID strfmt.UUID `description:"UUID of the member"`
UUID strfmt.UUID `description:"UUID of the member"`
} `positional-args:"yes" required:"yes"`
}

type MemberSet struct {
PositionalMemberSet struct {
UUID strfmt.UUID `description:"UUID of the member"`
} `positional-args:"yes" required:"yes"`
Name *string `short:"n" long:"name" description:"Name of the Member"`
Address *strfmt.IPv4 `short:"a" long:"address" description:"Address of the Member"`
Port *int64 `short:"p" long:"port" description:"Port of the Member"`
Disable bool `short:"d" long:"disable" description:"Disable Member"`
Enable bool `short:"e" long:"enable" description:"Enable Member"`
}

func (*MemberList) Execute(_ []string) error {
Expand All @@ -72,12 +84,12 @@ func (*MemberList) Execute(_ []string) error {
}

func (*MemberCreate) Execute(_ []string) error {
adminStateUp := !MemberOptions.Disable
adminStateUp := !MemberOptions.MemberCreate.Disable
member := members.PostMembersBody{Member: &models.Member{
AdminStateUp: &adminStateUp,
Name: &MemberOptions.Name,
Address: &MemberOptions.Address,
Port: &MemberOptions.Port,
Name: &MemberOptions.MemberCreate.Name,
Address: &MemberOptions.MemberCreate.Address,
Port: &MemberOptions.MemberCreate.Port,
DatacenterID: &MemberOptions.DatacenterID,
PoolID: &MemberOptions.PositionalMemberCreate.PoolID,
}}
Expand Down Expand Up @@ -111,6 +123,36 @@ func (*MemberDelete) Execute(_ []string) error {
return nil
}

func (*MemberSet) Execute(_ []string) error {
if MemberOptions.MemberSet.Disable && MemberOptions.MemberSet.Enable {
return fmt.Errorf("cannot enable and disable member at the same time")
}

member := members.PutMembersMemberIDBody{Member: &models.Member{
Name: MemberOptions.MemberSet.Name,
Address: MemberOptions.MemberSet.Address,
Port: MemberOptions.MemberSet.Port,
}}
if MemberOptions.MemberSet.Disable {
adminStateUp := false
member.Member.AdminStateUp = &adminStateUp
} else if MemberOptions.MemberSet.Enable {
adminStateUp := true
member.Member.AdminStateUp = &adminStateUp
}

params := members.
NewPutMembersMemberIDParams().
WithMemberID(MemberOptions.MemberSet.PositionalMemberSet.UUID).
WithMember(member)

resp, err := AndromedaClient.Members.PutMembersMemberID(params)
if err != nil {
return err
}
return WriteTable(resp.GetPayload().Member)
}

func init() {
_, err := Parser.AddCommand("member", "Members", "Member Commands.", &MemberOptions)
if err != nil {
Expand Down
3 changes: 3 additions & 0 deletions internal/controller/member.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ func (c MemberController) PostMembers(params members.PostMembersParams) middlewa
if params.Member.Member.PoolID == nil {
return members.NewPostMembersBadRequest().WithPayload(utils.PoolIDRequired)
}
if params.Member.Member.Address == nil || params.Member.Member.Port == nil {
return members.NewPostMembersBadRequest().WithPayload(utils.MissingAddressOrPort)
}

projectID, err := auth.Authenticate(params.HTTPRequest, nil)
if err != nil {
Expand Down
28 changes: 18 additions & 10 deletions internal/driver/akamai/datacenter.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import (
"github.com/sapcc/andromeda/models"
)

var datacenterNotFound = errors.New("datacenter/GetDatacenterMeta: datacenter not found")

// GetDatacenterMeta return the meta id for a given datacenter uuid
func (s *AkamaiAgent) GetDatacenterMeta(datacenterUUID string, datacenters []*rpcmodels.Datacenter) (int, error) {
// Fetch from cache
Expand Down Expand Up @@ -68,13 +70,13 @@ func (s *AkamaiAgent) GetDatacenterMeta(datacenterUUID string, datacenters []*rp
}
}
if meta == 0 {
return 0, errors.New("datacenter/GetDatacenterMeta: datacenter not found")
return 0, datacenterNotFound
}

// sync meta id with andromeda database
// try syncing meta id with andromeda database
req := &server.DatacenterMetaRequest{Id: datacenterUUID, Meta: int32(meta)}
if _, err = s.rpc.UpdateDatacenterMeta(context.Background(), req); err != nil {
return meta, err
log.Errorf("UpdateDatacenterMeta(%s) failed: %v", datacenterUUID, err)
}

// cache meta id
Expand Down Expand Up @@ -144,28 +146,34 @@ func (s *AkamaiAgent) SyncDatacenter(datacenter *rpcmodels.Datacenter, force boo
var backendDatacenter *gtm.Datacenter
var err error

if meta == 0 && datacenter.ProvisioningStatus != models.DatacenterProvisioningStatusPENDINGCREATE {
meta, err = s.GetDatacenterMeta(datacenter.Id, nil)
if err != nil {
if meta == 0 {
if meta, err = s.GetDatacenterMeta(datacenter.Id, nil); err != nil {
return nil, err
}
}
if backendDatacenter, err = s.gtm.GetDatacenter(context.Background(), meta, config.Global.AkamaiConfig.Domain); err != nil {
return nil, err
if meta != 0 {
if backendDatacenter, err = s.gtm.GetDatacenter(context.Background(), meta, config.Global.AkamaiConfig.Domain); err != nil {
// check if datacenter is not found
var gtmErr *gtm.Error
if errors.As(err, &gtmErr) && gtmErr.StatusCode != 404 {
return nil, err
}
}
}

if datacenter.ProvisioningStatus == models.DatacenterProvisioningStatusPENDINGDELETE {
// Run Delete
// nothing to delete?
if backendDatacenter == nil {
// datacenter already deleted
return nil, nil
}

// run Delete
_, err = s.gtm.DeleteDatacenter(context.Background(), backendDatacenter, config.Global.AkamaiConfig.Domain)
return nil, err
}

// Consider synced
// consider synced
if !force && meta != 0 {
return datacenter, nil
}
Expand Down
6 changes: 3 additions & 3 deletions internal/rpc/server/rpc_server_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ func (u *RPCHandler) GetMonitors(ctx context.Context, request *SearchRequest) (*
}

func (u *RPCHandler) UpdateDatacenterMeta(ctx context.Context, req *DatacenterMetaRequest) (*rpcmodels.Datacenter, error) {
var res *rpcmodels.Datacenter
var res rpcmodels.Datacenter
if err := db.TxExecute(u.DB, func(tx *sqlx.Tx) error {
sql := tx.Rebind(`UPDATE datacenter SET meta = ? WHERE id = ?`)
if _, err := tx.Exec(sql, req.GetMeta(), req.GetId()); err != nil {
Expand All @@ -223,15 +223,15 @@ func (u *RPCHandler) UpdateDatacenterMeta(ctx context.Context, req *DatacenterMe

sql = tx.Rebind(`SELECT id, admin_state_up, city, state_or_province, continent, country,
latitude, longitude, scope, provisioning_status, provider, meta FROM datacenter WHERE id = ?`)
if err := tx.Get(res, sql, req.GetId()); err != nil {
if err := tx.Get(&res, sql, req.GetId()); err != nil {
return err
}

return nil
}); err != nil {
return nil, err
}
return res, nil
return &res, nil
}

func populatePools(u *RPCHandler, fullyPopulated bool, domainID string) ([]*rpcmodels.Pool, error) {
Expand Down
1 change: 1 addition & 0 deletions internal/utils/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ var (
InvalidSendString = &models.Error{Code: 409, Message: "invalid value for 'send': must be a URL path"}
MissingFQDN = &models.Error{Code: 400, Message: "invalid value for 'fqdn': 'fqdn' is required"}
MissingProvider = &models.Error{Code: 400, Message: "invalid value for 'provider': 'provider' is required"}
MissingAddressOrPort = &models.Error{Code: 400, Message: "invalid value for 'address' and 'port': 'address' and 'port' are required"}
FQDNImmutable = &models.Error{Code: 400, Message: "invalid value for 'fqdn': change of immutable attribute 'fqdn' not allowed"}
MySQLForeignKeyViolation = &mysql.MySQLError{Number: 1451}
)
Expand Down
24 changes: 9 additions & 15 deletions models/member.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions models/monitor.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 6 additions & 10 deletions restapi/embedded_spec.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 2 additions & 4 deletions swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1567,10 +1567,6 @@ definitions:

member:
type: object
required:
- address
- port
- pool_id
properties:
id:
type: string
Expand Down Expand Up @@ -1628,11 +1624,13 @@ definitions:
example: 80
minimum: 0
maximum: 65535
x-nullabe: true
address:
type: string
format: ipv4
description: Address to use.
example: 1.2.3.4
x-nullable: true
pool_id:
type: string
format: uuid
Expand Down

0 comments on commit 67f3d35

Please sign in to comment.