Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v15] Add tctl resource commands for AutoUpdateConfig and AutoUpdateVersion #46867

Merged
merged 2 commits into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions api/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -3196,6 +3196,18 @@ func (c *Client) GetClusterAuditConfig(ctx context.Context) (types.ClusterAuditC
return resp, nil
}

// CreateAutoUpdateConfig creates AutoUpdateConfig resource.
func (c *Client) CreateAutoUpdateConfig(ctx context.Context, config *autoupdatev1pb.AutoUpdateConfig) (*autoupdatev1pb.AutoUpdateConfig, error) {
client := autoupdatev1pb.NewAutoUpdateServiceClient(c.conn)
resp, err := client.CreateAutoUpdateConfig(ctx, &autoupdatev1pb.CreateAutoUpdateConfigRequest{
Config: config,
})
if err != nil {
return nil, trace.Wrap(err)
}
return resp, nil
}

// GetAutoUpdateConfig gets AutoUpdateConfig resource.
func (c *Client) GetAutoUpdateConfig(ctx context.Context) (*autoupdatev1pb.AutoUpdateConfig, error) {
client := autoupdatev1pb.NewAutoUpdateServiceClient(c.conn)
Expand All @@ -3206,6 +3218,49 @@ func (c *Client) GetAutoUpdateConfig(ctx context.Context) (*autoupdatev1pb.AutoU
return resp, nil
}

// UpdateAutoUpdateConfig updates AutoUpdateConfig resource.
func (c *Client) UpdateAutoUpdateConfig(ctx context.Context, config *autoupdatev1pb.AutoUpdateConfig) (*autoupdatev1pb.AutoUpdateConfig, error) {
client := autoupdatev1pb.NewAutoUpdateServiceClient(c.conn)
resp, err := client.UpdateAutoUpdateConfig(ctx, &autoupdatev1pb.UpdateAutoUpdateConfigRequest{
Config: config,
})
if err != nil {
return nil, trace.Wrap(err)
}
return resp, nil
}

// UpsertAutoUpdateConfig updates or creates AutoUpdateConfig resource.
func (c *Client) UpsertAutoUpdateConfig(ctx context.Context, config *autoupdatev1pb.AutoUpdateConfig) (*autoupdatev1pb.AutoUpdateConfig, error) {
client := autoupdatev1pb.NewAutoUpdateServiceClient(c.conn)
resp, err := client.UpsertAutoUpdateConfig(ctx, &autoupdatev1pb.UpsertAutoUpdateConfigRequest{
Config: config,
})
if err != nil {
return nil, trace.Wrap(err)
}
return resp, nil
}

// DeleteAutoUpdateConfig deletes AutoUpdateConfig resource.
func (c *Client) DeleteAutoUpdateConfig(ctx context.Context) error {
client := autoupdatev1pb.NewAutoUpdateServiceClient(c.conn)
_, err := client.DeleteAutoUpdateConfig(ctx, &autoupdatev1pb.DeleteAutoUpdateConfigRequest{})
return trace.Wrap(err)
}

// CreateAutoUpdateVersion creates AutoUpdateVersion resource.
func (c *Client) CreateAutoUpdateVersion(ctx context.Context, version *autoupdatev1pb.AutoUpdateVersion) (*autoupdatev1pb.AutoUpdateVersion, error) {
client := autoupdatev1pb.NewAutoUpdateServiceClient(c.conn)
resp, err := client.CreateAutoUpdateVersion(ctx, &autoupdatev1pb.CreateAutoUpdateVersionRequest{
Version: version,
})
if err != nil {
return nil, trace.Wrap(err)
}
return resp, nil
}

// GetAutoUpdateVersion gets AutoUpdateVersion resource.
func (c *Client) GetAutoUpdateVersion(ctx context.Context) (*autoupdatev1pb.AutoUpdateVersion, error) {
client := autoupdatev1pb.NewAutoUpdateServiceClient(c.conn)
Expand All @@ -3216,6 +3271,37 @@ func (c *Client) GetAutoUpdateVersion(ctx context.Context) (*autoupdatev1pb.Auto
return resp, nil
}

// UpdateAutoUpdateVersion updates AutoUpdateVersion resource.
func (c *Client) UpdateAutoUpdateVersion(ctx context.Context, version *autoupdatev1pb.AutoUpdateVersion) (*autoupdatev1pb.AutoUpdateVersion, error) {
client := autoupdatev1pb.NewAutoUpdateServiceClient(c.conn)
resp, err := client.UpdateAutoUpdateVersion(ctx, &autoupdatev1pb.UpdateAutoUpdateVersionRequest{
Version: version,
})
if err != nil {
return nil, trace.Wrap(err)
}
return resp, nil
}

// UpsertAutoUpdateVersion updates or creates AutoUpdateVersion resource.
func (c *Client) UpsertAutoUpdateVersion(ctx context.Context, version *autoupdatev1pb.AutoUpdateVersion) (*autoupdatev1pb.AutoUpdateVersion, error) {
client := autoupdatev1pb.NewAutoUpdateServiceClient(c.conn)
resp, err := client.UpsertAutoUpdateVersion(ctx, &autoupdatev1pb.UpsertAutoUpdateVersionRequest{
Version: version,
})
if err != nil {
return nil, trace.Wrap(err)
}
return resp, nil
}

// DeleteAutoUpdateVersion deletes AutoUpdateVersion resource.
func (c *Client) DeleteAutoUpdateVersion(ctx context.Context) error {
client := autoupdatev1pb.NewAutoUpdateServiceClient(c.conn)
_, err := client.DeleteAutoUpdateVersion(ctx, &autoupdatev1pb.DeleteAutoUpdateVersionRequest{})
return trace.Wrap(err)
}

// GetClusterAccessGraphConfig retrieves the Cluster Access Graph configuration from Auth server.
func (c *Client) GetClusterAccessGraphConfig(ctx context.Context) (*clusterconfigpb.AccessGraphConfig, error) {
rsp, err := c.ClusterConfigClient().GetClusterAccessGraphConfig(ctx, &clusterconfigpb.GetClusterAccessGraphConfigRequest{})
Expand Down
4 changes: 4 additions & 0 deletions lib/services/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,10 @@ func ParseShortcut(in string) (string, error) {
return types.KindAccessGraphSettings, nil
case types.KindSPIFFEFederation, types.KindSPIFFEFederation + "s":
return types.KindSPIFFEFederation, nil
case types.KindAutoUpdateConfig:
return types.KindAutoUpdateConfig, nil
case types.KindAutoUpdateVersion:
return types.KindAutoUpdateVersion, nil
}
return "", trace.BadParameter("unsupported resource: %q - resources should be expressed as 'type/name', for example 'connector/github'", in)
}
Expand Down
37 changes: 37 additions & 0 deletions tool/tctl/common/collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"github.com/gravitational/trace"

"github.com/gravitational/teleport/api/constants"
autoupdatev1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1"
crownjewelv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/crownjewel/v1"
dbobjectv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobject/v1"
dbobjectimportrulev1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobjectimportrule/v1"
Expand Down Expand Up @@ -1677,3 +1678,39 @@ func (c *spiffeFederationCollection) writeText(w io.Writer, verbose bool) error
_, err := t.AsBuffer().WriteTo(w)
return trace.Wrap(err)
}

type autoUpdateConfigCollection struct {
config *autoupdatev1pb.AutoUpdateConfig
}

func (c *autoUpdateConfigCollection) resources() []types.Resource {
return []types.Resource{types.Resource153ToLegacy(c.config)}
}

func (c *autoUpdateConfigCollection) writeText(w io.Writer, verbose bool) error {
t := asciitable.MakeTable([]string{"Name", "Tools AutoUpdate Enabled"})
t.AddRow([]string{
c.config.GetMetadata().GetName(),
fmt.Sprintf("%v", c.config.GetSpec().GetToolsAutoupdate()),
})
_, err := t.AsBuffer().WriteTo(w)
return trace.Wrap(err)
}

type autoUpdateVersionCollection struct {
version *autoupdatev1pb.AutoUpdateVersion
}

func (c *autoUpdateVersionCollection) resources() []types.Resource {
return []types.Resource{types.Resource153ToLegacy(c.version)}
}

func (c *autoUpdateVersionCollection) writeText(w io.Writer, verbose bool) error {
t := asciitable.MakeTable([]string{"Name", "Tools AutoUpdate Version"})
t.AddRow([]string{
c.version.GetMetadata().GetName(),
fmt.Sprintf("%v", c.version.GetSpec().GetToolsVersion()),
})
_, err := t.AsBuffer().WriteTo(w)
return trace.Wrap(err)
}
78 changes: 78 additions & 0 deletions tool/tctl/common/edit_command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ import (
"github.com/stretchr/testify/require"

"github.com/gravitational/teleport/api/constants"
autoupdatev1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/api/types/autoupdate"
"github.com/gravitational/teleport/lib/auth/authclient"
"github.com/gravitational/teleport/lib/backend"
"github.com/gravitational/teleport/lib/modules"
Expand Down Expand Up @@ -72,6 +74,14 @@ func TestEditResources(t *testing.T) {
kind: types.KindSessionRecordingConfig,
edit: testEditSessionRecordingConfig,
},
{
kind: types.KindAutoUpdateConfig,
edit: testEditAutoUpdateConfig,
},
{
kind: types.KindAutoUpdateVersion,
edit: testEditAutoUpdateVersion,
},
}

for _, test := range tests {
Expand Down Expand Up @@ -482,3 +492,71 @@ func testEditSAMLConnector(t *testing.T, clt *authclient.Client) {
assert.Error(t, err, "stale connector was allowed to be updated")
require.ErrorIs(t, err, backend.ErrIncorrectRevision, "expected an incorrect revision error, got %T", err)
}

func testEditAutoUpdateConfig(t *testing.T, clt *authclient.Client) {
ctx := context.Background()

expected, err := autoupdate.NewAutoUpdateConfig(&autoupdatev1pb.AutoUpdateConfigSpec{ToolsAutoupdate: true})
require.NoError(t, err)

initial, err := autoupdate.NewAutoUpdateConfig(&autoupdatev1pb.AutoUpdateConfigSpec{ToolsAutoupdate: false})
require.NoError(t, err)

serviceClient := autoupdatev1pb.NewAutoUpdateServiceClient(clt.GetConnection())
_, err = serviceClient.CreateAutoUpdateConfig(ctx, &autoupdatev1pb.CreateAutoUpdateConfigRequest{Config: initial})
require.NoError(t, err, "creating initial autoupdate config")

editor := func(name string) error {
f, err := os.Create(name)
if err != nil {
return trace.Wrap(err, "opening file to edit")
}
expected.GetMetadata().Revision = initial.GetMetadata().GetRevision()
collection := &autoUpdateConfigCollection{config: expected}
return trace.NewAggregate(writeYAML(collection, f), f.Close())
}

// Edit the AutoUpdateConfig resource.
_, err = runEditCommand(t, clt, []string{"edit", "autoupdate_config"}, withEditor(editor))
require.NoError(t, err, "expected editing autoupdate config to succeed")

actual, err := clt.GetAutoUpdateConfig(ctx)
require.NoError(t, err, "failed to get autoupdate config after edit")
assert.NotEqual(t, initial.GetSpec().GetToolsAutoupdate(), actual.GetSpec().GetToolsAutoupdate(),
"tools_autoupdate should have been modified by edit")
assert.Equal(t, expected.GetSpec().GetToolsAutoupdate(), actual.GetSpec().GetToolsAutoupdate())
}

func testEditAutoUpdateVersion(t *testing.T, clt *authclient.Client) {
ctx := context.Background()

expected, err := autoupdate.NewAutoUpdateVersion(&autoupdatev1pb.AutoUpdateVersionSpec{ToolsVersion: "3.2.1"})
require.NoError(t, err)

initial, err := autoupdate.NewAutoUpdateVersion(&autoupdatev1pb.AutoUpdateVersionSpec{ToolsVersion: "1.2.3"})
require.NoError(t, err)

serviceClient := autoupdatev1pb.NewAutoUpdateServiceClient(clt.GetConnection())
_, err = serviceClient.CreateAutoUpdateVersion(ctx, &autoupdatev1pb.CreateAutoUpdateVersionRequest{Version: initial})
require.NoError(t, err, "creating initial autoupdate version")

editor := func(name string) error {
f, err := os.Create(name)
if err != nil {
return trace.Wrap(err, "opening file to edit")
}
expected.GetMetadata().Revision = initial.GetMetadata().GetRevision()
collection := &autoUpdateVersionCollection{version: expected}
return trace.NewAggregate(writeYAML(collection, f), f.Close())
}

// Edit the AutoUpdateVersion resource.
_, err = runEditCommand(t, clt, []string{"edit", "autoupdate_version"}, withEditor(editor))
require.NoError(t, err, "expected editing autoupdate version to succeed")

actual, err := clt.GetAutoUpdateVersion(ctx)
require.NoError(t, err, "failed to get autoupdate version after edit")
assert.NotEqual(t, initial.GetSpec().GetToolsVersion(), actual.GetSpec().GetToolsVersion(),
"tools_autoupdate should have been modified by edit")
assert.Equal(t, expected.GetSpec().GetToolsVersion(), actual.GetSpec().GetToolsVersion())
}
79 changes: 79 additions & 0 deletions tool/tctl/common/resource_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import (
apiclient "github.com/gravitational/teleport/api/client"
"github.com/gravitational/teleport/api/client/proto"
apidefaults "github.com/gravitational/teleport/api/defaults"
autoupdatev1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1"
clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1"
crownjewelv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/crownjewel/v1"
dbobjectv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobject/v1"
Expand Down Expand Up @@ -164,6 +165,8 @@ func (rc *ResourceCommand) Initialize(app *kingpin.Application, config *servicec
types.KindAccessGraphSettings: rc.upsertAccessGraphSettings,
types.KindPlugin: rc.createPlugin,
types.KindSPIFFEFederation: rc.createSPIFFEFederation,
types.KindAutoUpdateConfig: rc.createAutoUpdateConfig,
types.KindAutoUpdateVersion: rc.createAutoUpdateVersion,
}
rc.UpdateHandlers = map[ResourceKind]ResourceCreateHandler{
types.KindUser: rc.updateUser,
Expand All @@ -178,6 +181,8 @@ func (rc *ResourceCommand) Initialize(app *kingpin.Application, config *servicec
types.KindCrownJewel: rc.updateCrownJewel,
types.KindAccessGraphSettings: rc.updateAccessGraphSettings,
types.KindPlugin: rc.updatePlugin,
types.KindAutoUpdateConfig: rc.updateAutoUpdateConfig,
types.KindAutoUpdateVersion: rc.updateAutoUpdateVersion,
}
rc.config = config

Expand Down Expand Up @@ -2885,6 +2890,18 @@ func (rc *ResourceCommand) getCollection(ctx context.Context, client *authclient
}

return &spiffeFederationCollection{items: resources}, nil
case types.KindAutoUpdateConfig:
config, err := client.GetAutoUpdateConfig(ctx)
if err != nil {
return nil, trace.Wrap(err)
}
return &autoUpdateConfigCollection{config}, nil
case types.KindAutoUpdateVersion:
version, err := client.GetAutoUpdateVersion(ctx)
if err != nil {
return nil, trace.Wrap(err)
}
return &autoUpdateVersionCollection{version}, nil
}
return nil, trace.BadParameter("getting %q is not supported", rc.ref.String())
}
Expand Down Expand Up @@ -3199,3 +3216,65 @@ func (rc *ResourceCommand) updateAccessGraphSettings(ctx context.Context, client
fmt.Println("access_graph_settings has been updated")
return nil
}

func (rc *ResourceCommand) createAutoUpdateConfig(ctx context.Context, client *authclient.Client, raw services.UnknownResource) error {
config, err := services.UnmarshalProtoResource[*autoupdatev1pb.AutoUpdateConfig](raw.Raw)
if err != nil {
return trace.Wrap(err)
}

if rc.IsForced() {
_, err = client.UpsertAutoUpdateConfig(ctx, config)
} else {
_, err = client.CreateAutoUpdateConfig(ctx, config)
}
if err != nil {
return trace.Wrap(err)
}

fmt.Println("autoupdate_config has been created")
return nil
}

func (rc *ResourceCommand) updateAutoUpdateConfig(ctx context.Context, client *authclient.Client, raw services.UnknownResource) error {
config, err := services.UnmarshalProtoResource[*autoupdatev1pb.AutoUpdateConfig](raw.Raw)
if err != nil {
return trace.Wrap(err)
}
if _, err := client.UpdateAutoUpdateConfig(ctx, config); err != nil {
return trace.Wrap(err)
}
fmt.Println("autoupdate_config has been updated")
return nil
}

func (rc *ResourceCommand) createAutoUpdateVersion(ctx context.Context, client *authclient.Client, raw services.UnknownResource) error {
version, err := services.UnmarshalProtoResource[*autoupdatev1pb.AutoUpdateVersion](raw.Raw)
if err != nil {
return trace.Wrap(err)
}

if rc.IsForced() {
_, err = client.UpsertAutoUpdateVersion(ctx, version)
} else {
_, err = client.CreateAutoUpdateVersion(ctx, version)
}
if err != nil {
return trace.Wrap(err)
}

fmt.Println("autoupdate_version has been created")
return nil
}

func (rc *ResourceCommand) updateAutoUpdateVersion(ctx context.Context, client *authclient.Client, raw services.UnknownResource) error {
version, err := services.UnmarshalProtoResource[*autoupdatev1pb.AutoUpdateVersion](raw.Raw)
if err != nil {
return trace.Wrap(err)
}
if _, err := client.UpdateAutoUpdateVersion(ctx, version); err != nil {
return trace.Wrap(err)
}
fmt.Println("autoupdate_version has been updated")
return nil
}
Loading
Loading