Skip to content

Commit

Permalink
Add save config resource
Browse files Browse the repository at this point in the history
  • Loading branch information
danischm committed Mar 24, 2024
1 parent 4524b8c commit 6f2c415
Show file tree
Hide file tree
Showing 8 changed files with 228 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- Add `nxos_vpc_peerlink` resource and data source
- Fix `bandwidth_reference_unit` of `nxos_ospf_vrf` resource and data source
- Add `force` attribute to `nxos_port_channel_interface_member` resource and data source
- Add `nxos_save_config` resource

## 0.5.1

Expand Down
1 change: 1 addition & 0 deletions docs/guides/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ description: |-
- Add `nxos_vpc_peerlink` resource and data source
- Fix `bandwidth_reference_unit` of `nxos_ospf_vrf` resource and data source
- Add `force` attribute to `nxos_port_channel_interface_member` resource and data source
- Add `nxos_save_config` resource

## 0.5.1

Expand Down
21 changes: 21 additions & 0 deletions docs/resources/save_config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "nxos_save_config Resource - terraform-provider-nxos"
subcategory: ""
description: |-
This resources is used to save the config which is the equivalent of doing a copy running-config startup-config in the device CLI.
---

# nxos_save_config (Resource)

This resources is used to save the config which is the equivalent of doing a `copy running-config startup-config` in the device CLI.



<!-- schema generated by tfplugindocs -->
## Schema

### Optional

- `device` (String) A device name from the provider configuration.
- `save` (Boolean) This attribute is only used internally.
1 change: 1 addition & 0 deletions gen/templates/provider.go

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

1 change: 1 addition & 0 deletions internal/provider/provider.go

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

158 changes: 158 additions & 0 deletions internal/provider/resource_nxos_save_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
// Copyright © 2023 Cisco Systems, Inc. and its affiliates.
// All rights reserved.
//
// Licensed under the Mozilla Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://mozilla.org/MPL/2.0/
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: MPL-2.0

package provider

import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/netascode/go-nxos"
"github.com/tidwall/sjson"
)

// Ensure provider defined types fully satisfy framework interfaces
var _ resource.Resource = &SaveConfigResource{}

func NewSaveConfigResource() resource.Resource {
return &SaveConfigResource{}
}

type SaveConfigResource struct {
clients map[string]*nxos.Client
}

func (r *SaveConfigResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_save_config"
}

func (r *SaveConfigResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
// This description is used by the documentation generator and the language server.
MarkdownDescription: "This resources is used to save the config which is the equivalent of doing a `copy running-config startup-config` in the device CLI.",

Attributes: map[string]schema.Attribute{
"device": schema.StringAttribute{
MarkdownDescription: "A device name from the provider configuration.",
Optional: true,
},
"save": schema.BoolAttribute{
MarkdownDescription: "This attribute is only used internally.",
Optional: true,
Computed: true,
Default: booldefault.StaticBool(true),
},
},
}
}

func (r *SaveConfigResource) Configure(_ context.Context, req resource.ConfigureRequest, _ *resource.ConfigureResponse) {
if req.ProviderData == nil {
return
}

r.clients = req.ProviderData.(map[string]*nxos.Client)
}

func (r *SaveConfigResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
var device types.String
var save types.Bool

diags := req.Plan.GetAttribute(ctx, path.Root("device"), &device)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
diags = req.Plan.GetAttribute(ctx, path.Root("save"), &save)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

tflog.Debug(ctx, "Beginning to save config")

// Post object
dn := "sys/action"
body, _ := sjson.Set("", "actionLSubj.attributes.dn", "sys/action/lsubj-[sys]")
body, _ = sjson.Set(body, "actionLSubj.children.0.topSystemCopyRSLTask.attributes.adminSt", "start")
body, _ = sjson.Set(body, "actionLSubj.children.0.topSystemCopyRSLTask.attributes.dn", "sys/action/lsubj-[sys]/topSystemCopyRSLTask")
body, _ = sjson.Set(body, "actionLSubj.children.0.topSystemCopyRSLTask.attributes.freq", "one-shot")

_, err := r.clients[device.ValueString()].Post(dn, body)
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to post object, got error: %s", err))
return
}

tflog.Debug(ctx, "Save config finished successfully")

diags = resp.State.SetAttribute(ctx, path.Root("device"), device)
resp.Diagnostics.Append(diags...)
diags = resp.State.SetAttribute(ctx, path.Root("save"), save)
resp.Diagnostics.Append(diags...)
}

func (r *SaveConfigResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
resp.State.SetAttribute(ctx, path.Root("save"), false)
}

func (r *SaveConfigResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
var device types.String
var save types.Bool

diags := req.Plan.GetAttribute(ctx, path.Root("device"), &device)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
diags = req.Plan.GetAttribute(ctx, path.Root("save"), &save)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

tflog.Debug(ctx, "Beginning to save config")

// Post object
dn := "sys/action"
body, _ := sjson.Set("", "actionLSubj.attributes.dn", "sys/action/lsubj-[sys]")
body, _ = sjson.Set(body, "actionLSubj.children.0.topSystemCopyRSLTask.attributes.adminSt", "start")
body, _ = sjson.Set(body, "actionLSubj.children.0.topSystemCopyRSLTask.attributes.dn", "sys/action/lsubj-[sys]/topSystemCopyRSLTask")
body, _ = sjson.Set(body, "actionLSubj.children.0.topSystemCopyRSLTask.attributes.freq", "one-shot")

_, err := r.clients[device.ValueString()].Post(dn, body)
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to post object, got error: %s", err))
return
}

tflog.Debug(ctx, "Save config finished successfully")

diags = resp.State.SetAttribute(ctx, path.Root("device"), device)
resp.Diagnostics.Append(diags...)
diags = resp.State.SetAttribute(ctx, path.Root("save"), save)
resp.Diagnostics.Append(diags...)
}

func (r *SaveConfigResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
}
44 changes: 44 additions & 0 deletions internal/provider/resource_nxos_save_config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright © 2023 Cisco Systems, Inc. and its affiliates.
// All rights reserved.
//
// Licensed under the Mozilla Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://mozilla.org/MPL/2.0/
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: MPL-2.0

package provider

import (
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
)

func TestAccNxosSaveConfig(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccNxosSaveConfig(),
},
},
})
}

func testAccNxosSaveConfig() string {
return `
resource "nxos_save_config" "test" {
save = false
}
`
}
1 change: 1 addition & 0 deletions templates/guides/changelog.md.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ description: |-
- Add `nxos_vpc_peerlink` resource and data source
- Fix `bandwidth_reference_unit` of `nxos_ospf_vrf` resource and data source
- Add `force` attribute to `nxos_port_channel_interface_member` resource and data source
- Add `nxos_save_config` resource

## 0.5.1

Expand Down

0 comments on commit 6f2c415

Please sign in to comment.