Skip to content

Commit

Permalink
add proxy version getter and maintenance trigger
Browse files Browse the repository at this point in the history
  • Loading branch information
hugoShaka committed Nov 27, 2024
1 parent fb26137 commit 2c9e564
Show file tree
Hide file tree
Showing 2 changed files with 153 additions and 0 deletions.
80 changes: 80 additions & 0 deletions lib/automaticupgrades/maintenance/proxy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Teleport
* Copyright (C) 2023 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 maintenance

import (
"context"
"github.com/gravitational/teleport/api/client/webclient"
"github.com/gravitational/teleport/lib/automaticupgrades/cache"
"github.com/gravitational/teleport/lib/automaticupgrades/constants"
"github.com/gravitational/trace"
"sigs.k8s.io/controller-runtime/pkg/client"
)

type proxyMaintenanceClient struct {
client *webclient.ReusableClient
}

func (b *proxyMaintenanceClient) Get(ctx context.Context) (bool, error) {
resp, err := b.client.Find()
if err != nil {
return false, trace.Wrap(err)
}
// We check if a version is advertised to know if the proxy implements RFD-184 or not.
if resp.AutoUpdate.AgentVersion == "" {
return false, trace.NotImplemented("proxy does not seem to implement RFD-184")
}
return resp.AutoUpdate.AgentAutoUpdate, nil
}

// ProxyMaintenanceTrigger checks if the maintenance should be triggered from the Teleport Proxy service /find endpoint,
// as specified in the RFD-184: https://github.com/gravitational/teleport/blob/master/rfd/0184-agent-auto-updates.md
// The Trigger returns trace.NotImplementedErr when running against a proxy that does not seem to
// expose automatic update instructions over the /find endpoint (proxy too old).
type ProxyMaintenanceTrigger struct {
name string
cachedGetter func(context.Context) (bool, error)
}

// Name implements maintenance.Trigger returns the trigger name for logging
// and debugging purposes.
func (g ProxyMaintenanceTrigger) Name() string {
return g.name
}

// Default implements maintenance.Trigger and returns what to do if the trigger can't be evaluated.
// ProxyMaintenanceTrigger should fail open, so the function returns true.
func (g ProxyMaintenanceTrigger) Default() bool {
return false
}

// CanStart implements maintenance.Trigger.
func (g ProxyMaintenanceTrigger) CanStart(ctx context.Context, _ client.Object) (bool, error) {
result, err := g.cachedGetter(ctx)
return result, trace.Wrap(err)
}

// NewProxyMaintenanceTrigger builds and return a Trigger checking a public HTTP endpoint.
func NewProxyMaintenanceTrigger(name string, clt *webclient.ReusableClient) Trigger {
maintenanceClient := &proxyMaintenanceClient{
client: clt,
}

return ProxyMaintenanceTrigger{name, cache.NewTimedMemoize[bool](maintenanceClient.Get, constants.CacheDuration).Get}
}
73 changes: 73 additions & 0 deletions lib/automaticupgrades/version/proxy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Teleport
* Copyright (C) 2023 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 version

import (
"context"
"github.com/gravitational/teleport/api/client/webclient"
"github.com/gravitational/teleport/lib/automaticupgrades/cache"
"github.com/gravitational/teleport/lib/automaticupgrades/constants"
"github.com/gravitational/trace"
)

type proxyVersionClient struct {
client *webclient.ReusableClient
}

func (b *proxyVersionClient) Get(ctx context.Context) (string, error) {
resp, err := b.client.Find()
if err != nil {
return "", trace.Wrap(err)
}
// We check if a version is advertised to know if the proxy implements RFD-184 or not.
if resp.AutoUpdate.AgentVersion == "" {
return "", trace.NotImplemented("proxy does not seem to implement RFD-184")
}
return resp.AutoUpdate.AgentVersion, nil
}

// ProxyVersionGetter gets the target version from the Teleport Proxy Service /find endpoint, as
// specified in the RFD-184: https://github.com/gravitational/teleport/blob/master/rfd/0184-agent-auto-updates.md
// The Getter returns trace.NotImplementedErr when running against a proxy that does not seem to
// expose automatic update instructions over the /find endpoint (proxy too old).
type ProxyVersionGetter struct {
name string
cachedGetter func(context.Context) (string, error)
}

// Name implements Getter
func (g ProxyVersionGetter) Name() string {
return g.name
}

// GetVersion implements Getter
func (g ProxyVersionGetter) GetVersion(ctx context.Context) (string, error) {
result, err := g.cachedGetter(ctx)
return result, trace.Wrap(err)
}

// NewProxyVersionGetter creates a ProxyVersionGetter from a webclient.
// The answer is cached for a minute.
func NewProxyVersionGetter(name string, clt *webclient.ReusableClient) Getter {
versionClient := &proxyVersionClient{
client: clt,
}

return ProxyVersionGetter{name, cache.NewTimedMemoize[string](versionClient.Get, constants.CacheDuration).Get}
}

0 comments on commit 2c9e564

Please sign in to comment.