Skip to content

Commit

Permalink
[v15] Add backend storage service for auto updates (#46517)
Browse files Browse the repository at this point in the history
* Add backend storage service for auto updates

* Add validation for metadata name

* CR change

* Use KeyFunc and ValidateFunc
  • Loading branch information
vapopov authored Sep 16, 2024
1 parent b4642f4 commit 8ddb139
Show file tree
Hide file tree
Showing 8 changed files with 777 additions and 0 deletions.
63 changes: 63 additions & 0 deletions api/types/autoupdate/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Teleport
* Copyright (C) 2024 Gravitational, Inc.
*
* 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 <http://www.gnu.org/licenses/>.
*/

package autoupdate

import (
"github.com/gravitational/trace"

"github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1"
headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1"
"github.com/gravitational/teleport/api/types"
)

// NewAutoUpdateConfig creates a new auto update configuration resource.
func NewAutoUpdateConfig(spec *autoupdate.AutoUpdateConfigSpec) (*autoupdate.AutoUpdateConfig, error) {
config := &autoupdate.AutoUpdateConfig{
Kind: types.KindAutoUpdateConfig,
Version: types.V1,
Metadata: &headerv1.Metadata{
Name: types.MetaNameAutoUpdateConfig,
},
Spec: spec,
}
if err := ValidateAutoUpdateConfig(config); err != nil {
return nil, trace.Wrap(err)
}

return config, nil
}

// ValidateAutoUpdateConfig checks that required parameters are set
// for the specified AutoUpdateConfig.
func ValidateAutoUpdateConfig(c *autoupdate.AutoUpdateConfig) error {
if c == nil {
return trace.BadParameter("AutoUpdateConfig is nil")
}
if c.Metadata == nil {
return trace.BadParameter("Metadata is nil")
}
if c.Metadata.Name != types.MetaNameAutoUpdateConfig {
return trace.BadParameter("Name is not valid")
}
if c.Spec == nil {
return trace.BadParameter("Spec is nil")
}

return nil
}
94 changes: 94 additions & 0 deletions api/types/autoupdate/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Teleport
* Copyright (C) 2024 Gravitational, Inc.
*
* 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 <http://www.gnu.org/licenses/>.
*/

package autoupdate

import (
"testing"

"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/testing/protocmp"

"github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1"
headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1"
"github.com/gravitational/teleport/api/types"
)

// TestNewAutoUpdateConfig verifies validation for auto update config resource.
func TestNewAutoUpdateConfig(t *testing.T) {
tests := []struct {
name string
spec *autoupdate.AutoUpdateConfigSpec
want *autoupdate.AutoUpdateConfig
assertErr func(*testing.T, error, ...any)
}{
{
name: "success tools autoupdate disabled",
spec: &autoupdate.AutoUpdateConfigSpec{
ToolsAutoupdate: false,
},
assertErr: func(t *testing.T, err error, a ...any) {
require.NoError(t, err)
},
want: &autoupdate.AutoUpdateConfig{
Kind: types.KindAutoUpdateConfig,
Version: types.V1,
Metadata: &headerv1.Metadata{
Name: types.MetaNameAutoUpdateConfig,
},
Spec: &autoupdate.AutoUpdateConfigSpec{
ToolsAutoupdate: false,
},
},
},
{
name: "success tools autoupdate enabled",
spec: &autoupdate.AutoUpdateConfigSpec{
ToolsAutoupdate: true,
},
assertErr: func(t *testing.T, err error, a ...any) {
require.NoError(t, err)
},
want: &autoupdate.AutoUpdateConfig{
Kind: types.KindAutoUpdateConfig,
Version: types.V1,
Metadata: &headerv1.Metadata{
Name: types.MetaNameAutoUpdateConfig,
},
Spec: &autoupdate.AutoUpdateConfigSpec{
ToolsAutoupdate: true,
},
},
},
{
name: "invalid spec",
spec: nil,
assertErr: func(t *testing.T, err error, a ...any) {
require.ErrorContains(t, err, "Spec is nil")
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := NewAutoUpdateConfig(tt.spec)
tt.assertErr(t, err)
require.Empty(t, cmp.Diff(got, tt.want, protocmp.Transform()))
})
}
}
71 changes: 71 additions & 0 deletions api/types/autoupdate/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Teleport
* Copyright (C) 2024 Gravitational, Inc.
*
* 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 <http://www.gnu.org/licenses/>.
*/

package autoupdate

import (
"github.com/coreos/go-semver/semver"
"github.com/gravitational/trace"

"github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1"
headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1"
"github.com/gravitational/teleport/api/types"
)

// NewAutoUpdateVersion creates a new auto update version resource.
func NewAutoUpdateVersion(spec *autoupdate.AutoUpdateVersionSpec) (*autoupdate.AutoUpdateVersion, error) {
version := &autoupdate.AutoUpdateVersion{
Kind: types.KindAutoUpdateVersion,
Version: types.V1,
Metadata: &headerv1.Metadata{
Name: types.MetaNameAutoUpdateVersion,
},
Spec: spec,
}
if err := ValidateAutoUpdateVersion(version); err != nil {
return nil, trace.Wrap(err)
}

return version, nil
}

// ValidateAutoUpdateVersion checks that required parameters are set
// for the specified AutoUpdateVersion.
func ValidateAutoUpdateVersion(v *autoupdate.AutoUpdateVersion) error {
if v == nil {
return trace.BadParameter("AutoUpdateVersion is nil")
}
if v.Metadata == nil {
return trace.BadParameter("Metadata is nil")
}
if v.Metadata.Name != types.MetaNameAutoUpdateVersion {
return trace.BadParameter("Name is not valid")
}
if v.Spec == nil {
return trace.BadParameter("Spec is nil")
}

if v.Spec.ToolsVersion == "" {
return trace.BadParameter("ToolsVersion is unset")
}
if _, err := semver.NewVersion(v.Spec.ToolsVersion); err != nil {
return trace.BadParameter("ToolsVersion is not a valid semantic version")
}

return nil
}
93 changes: 93 additions & 0 deletions api/types/autoupdate/version_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* Teleport
* Copyright (C) 2024 Gravitational, Inc.
*
* 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 <http://www.gnu.org/licenses/>.
*/

package autoupdate

import (
"testing"

"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/testing/protocmp"

"github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1"
headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1"
"github.com/gravitational/teleport/api/types"
)

// TestNewAutoUpdateVersion verifies validation for auto update version resource.
func TestNewAutoUpdateVersion(t *testing.T) {
tests := []struct {
name string
spec *autoupdate.AutoUpdateVersionSpec
want *autoupdate.AutoUpdateVersion
assertErr func(*testing.T, error, ...any)
}{
{
name: "success tools autoupdate version",
spec: &autoupdate.AutoUpdateVersionSpec{
ToolsVersion: "1.2.3-dev",
},
assertErr: func(t *testing.T, err error, a ...any) {
require.NoError(t, err)
},
want: &autoupdate.AutoUpdateVersion{
Kind: types.KindAutoUpdateVersion,
Version: types.V1,
Metadata: &headerv1.Metadata{
Name: types.MetaNameAutoUpdateVersion,
},
Spec: &autoupdate.AutoUpdateVersionSpec{
ToolsVersion: "1.2.3-dev",
},
},
},
{
name: "invalid empty tools version",
spec: &autoupdate.AutoUpdateVersionSpec{
ToolsVersion: "",
},
assertErr: func(t *testing.T, err error, a ...any) {
require.ErrorContains(t, err, "ToolsVersion is unset")
},
},
{
name: "invalid semantic tools version",
spec: &autoupdate.AutoUpdateVersionSpec{
ToolsVersion: "17-0-0",
},
assertErr: func(t *testing.T, err error, a ...any) {
require.ErrorContains(t, err, "ToolsVersion is not a valid semantic version")
},
},
{
name: "invalid spec",
spec: nil,
assertErr: func(t *testing.T, err error, a ...any) {
require.ErrorContains(t, err, "Spec is nil")
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := NewAutoUpdateVersion(tt.spec)
tt.assertErr(t, err)
require.Empty(t, cmp.Diff(got, tt.want, protocmp.Transform()))
})
}
}
12 changes: 12 additions & 0 deletions api/types/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,18 @@ const (
// alternative to their individual resource kinds.
KindClusterConfig = "cluster_config"

// KindAutoUpdateConfig is the resource with autoupdate configuration.
KindAutoUpdateConfig = "autoupdate_config"

// KindAutoUpdateVersion is the resource with autoupdate versions.
KindAutoUpdateVersion = "autoupdate_version"

// MetaNameAutoUpdateConfig is the name of a configuration resource for autoupdate config.
MetaNameAutoUpdateConfig = "autoupdate-config"

// MetaNameAutoUpdateVersion is the name of a resource for autoupdate version.
MetaNameAutoUpdateVersion = "autoupdate-version"

// KindClusterAuditConfig is the resource that holds cluster audit configuration.
KindClusterAuditConfig = "cluster_audit_config"

Expand Down
Loading

0 comments on commit 8ddb139

Please sign in to comment.