Skip to content

Commit

Permalink
feat(lh-89807): add new cdo_ftd_device_version resource (#156)
Browse files Browse the repository at this point in the history
* feat(lh-89807): add new cdo_ftd_device_version resource

Add a new resource that allows the user to upgrade an online, onboarded cdFMC managed FTD

* revert this before merging; running acceptance tests on branch

* Revert "revert this before merging; running acceptance tests on branch"

This reverts commit 2237d51.

* test(lh-89810): add more test

* test(lh-89807): add more tests
  • Loading branch information
siddhuwarrier authored Jan 28, 2025
1 parent fb461f6 commit 0b8bbc5
Show file tree
Hide file tree
Showing 21 changed files with 1,111 additions and 78 deletions.
142 changes: 71 additions & 71 deletions client/client.go

Large diffs are not rendered by default.

15 changes: 10 additions & 5 deletions client/device/cloudftd/read_by_uid.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,18 @@ func NewReadByUidInput(uid string) ReadByUidInput {
}

type ReadOutput struct {
Uid string `json:"uid"`
Name string `json:"name"`
Metadata Metadata `json:"metadata,omitempty"`
State string `json:"state"`
Tags tags.Type `json:"tags"`
Uid string `json:"uid"`
DeviceType string `json:"deviceType"`
Name string `json:"name"`
Metadata Metadata `json:"metadata,omitempty"`
State string `json:"state"`
ConnectivityState int `json:"connectivityState"`
Tags tags.Type `json:"tags"`
SoftwareVersion string `json:"softwareVersion"`
}

type FtdDevice = ReadOutput

func ReadByUid(ctx context.Context, client http.Client, readInp ReadByUidInput) (*ReadOutput, error) {

readUrl := url.ReadDevice(client.BaseUrl(), readInp.Uid)
Expand Down
25 changes: 25 additions & 0 deletions client/device/cloudftd/read_upgrade_packages.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package cloudftd

import (
"context"
"github.com/CiscoDevnet/terraform-provider-cdo/go-client/internal/http"
"github.com/CiscoDevnet/terraform-provider-cdo/go-client/internal/url"
"github.com/CiscoDevnet/terraform-provider-cdo/go-client/model"
)

type UpgradePackage struct {
UpgradePackageUid string `json:"upgradePackageUid"`
SoftwareVersion string `json:"softwareVersion"`
}

func ReadUpgradePackages(ctx context.Context, client http.Client, deviceUid string) (*[]UpgradePackage, error) {
readUrl := url.GetFtdUpgradePackagesUrl(client.BaseUrl(), deviceUid)
req := client.NewGet(ctx, readUrl)

upgradePackageResponse := model.CdoListResponse[UpgradePackage]{}
if err := req.Send(&upgradePackageResponse); err != nil {
return nil, err
}

return &upgradePackageResponse.Items, nil
}
118 changes: 118 additions & 0 deletions client/device/cloudftd/upgrade.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package cloudftd

import (
"context"
"errors"
"fmt"
"github.com/CiscoDevnet/terraform-provider-cdo/go-client/internal/http"
"github.com/CiscoDevnet/terraform-provider-cdo/go-client/model/ftd"
"github.com/hashicorp/terraform-plugin-log/tflog"
)

type FtdUpgradeInput struct {
Uid string `json:"uid"`
SoftwareVersion string `json:"softwareVersion"`
}

type FtdUpgradeService interface {
Upgrade(uid string, softwareVersion string) (*FtdDevice, error)
}

type ftdUpgradeService struct {
Ctx context.Context
Client *http.Client
}

func NewFtdUpgradeService(ctx context.Context, client *http.Client) FtdUpgradeService {
return &ftdUpgradeService{
Ctx: ctx,
Client: client,
}
}

func (f *ftdUpgradeService) Upgrade(uid string, softwareVersion string) (*FtdDevice, error) {
ftdDevice, err := ReadByUid(f.Ctx, *f.Client, ReadByUidInput{Uid: uid})
if err != nil {
return nil, err
}
tflog.Debug(f.Ctx, fmt.Sprintf("FTD device found: %v", ftdDevice))

tflog.Debug(f.Ctx, "Validating if FTD device is suitable for upgrade...")
err = f.validateDeviceType(ftdDevice)
if err != nil {
return nil, err
}
err = f.validateConnectivityState(ftdDevice)
if err != nil {
return nil, err
}
err = f.validateFtdVersion(ftdDevice, softwareVersion)
if err != nil {
return nil, err
}

return ftdDevice, nil
}

func (f *ftdUpgradeService) validateDeviceType(ftdDevice *FtdDevice) error {
if ftdDevice.DeviceType != "FTDC" {
return errors.New("this resource only supports cdFMC managed FTDs")
}

return nil
}

func (f *ftdUpgradeService) validateConnectivityState(ftdDevice *FtdDevice) error {
if ftdDevice.ConnectivityState != 1 {
return errors.New("FTD device connectivity state is not ONLINE. Only ONLINE devices can be upgraded")
}

return nil
}

func (f *ftdUpgradeService) validateFtdVersion(ftdDevice *FtdDevice, softwareVersionToUpgradeToStr string) error {
versionOnDevice, err := ftd.NewVersion(ftdDevice.SoftwareVersion)
if err != nil {
f.Client.Logger.Printf("error parsing software version %s on device\n", ftdDevice.SoftwareVersion)
return err
}
versionToUpgradeTo, err := ftd.NewVersion(softwareVersionToUpgradeToStr)
if err != nil {
f.Client.Logger.Printf("error parsing software version %s to upgrade to\n", softwareVersionToUpgradeToStr)
return err
}

if versionOnDevice.GreaterThan(versionToUpgradeTo) {
return errors.New(fmt.Sprintf("FTD device is on version %s, which is newer than the"+
" version to upgrade to: %s", ftdDevice.SoftwareVersion, softwareVersionToUpgradeToStr))
}
if versionOnDevice.LessThan(versionToUpgradeTo) {
err = f.validateUpgradePathExistsTo(ftdDevice, versionToUpgradeTo)
if err != nil {
return err
}
return errors.New("upgrade implementation coming soon")
}

return nil
}

func (f *ftdUpgradeService) validateUpgradePathExistsTo(ftdDevice *FtdDevice, toVersion *ftd.Version) error {
upgradePackages, err := ReadUpgradePackages(f.Ctx, *f.Client, ftdDevice.Uid)
if err != nil {
return err
}
for _, upgradePackage := range *upgradePackages {
tflog.Debug(f.Ctx, fmt.Sprintf("Checking upgrade package: %s", upgradePackage.SoftwareVersion))
softwareVersion, err := ftd.NewVersion(upgradePackage.SoftwareVersion)
if err != nil {
f.Client.Logger.Printf("error parsing software version %s in upgrade package\n", upgradePackage.SoftwareVersion)
return err
}
if softwareVersion.Equal(toVersion) {
return nil
}
}

return errors.New(fmt.Sprintf("%s is not a valid version to upgrade FTD device %s to", toVersion.String(), ftdDevice.Name))
}
Loading

0 comments on commit 0b8bbc5

Please sign in to comment.