Skip to content

Commit

Permalink
Merge pull request #5 from on2itsecurity/migrate-to-plugin-framework
Browse files Browse the repository at this point in the history
Migrate to plugin framework
  • Loading branch information
RobM83 committed May 27, 2023
2 parents 64dac62 + 989bcb5 commit 367b87e
Show file tree
Hide file tree
Showing 37 changed files with 2,056 additions and 1,234 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
**/*.terraform*
**/*.tfstate*
**/*.hcl
vendor/
bin/
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ HOSTNAME=registry.terraform.io
NAMESPACE=on2itsecurity
NAME=auxo
BINARY=terraform-provider-${NAME}
VERSION=0.0.5
VERSION=0.0.6
OS_ARCH=darwin_arm64 #amd64

default: build
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,11 @@ scp ./terraform-provider-auxo <USER>@<DESTINATION.SERVER>:~/
mkdir -p ~/.terraform.d/plugins/on2itsecurity/auxo/0.1/linux_amd64
mv ~/terraform-provider-auxo ~/.terraform.d/plugins/on2itsecurity/auxo/0.1/linux_amd64/
```

### Documentation

The documentation can be build using [tfplugindocs](https://github.com/hashicorp/terraform-plugin-docs).

```shell
tfplugindocs generate
```
97 changes: 97 additions & 0 deletions auxo/configfile.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Description: This file contains functions for reading the (ztctl) config file

package auxo

import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os"

"github.com/mitchellh/go-homedir"
)

type ConfigFile struct {
Configs []ConfigEntry `json:"configs"`
}

type ConfigEntry struct {
Alias string `json:"alias"`
Description string `json:"description"`
Token string `json:"token"`
APIAddress string `json:"apiaddress"`
Debug bool `json:"debug"`
}

// Will return the default config file location
func getDefaultConfigLocation() string {
// Find home directory.
home, err := homedir.Dir()
if err != nil {
log.Fatal(err)
os.Exit(1)
}

location := home + "/.ztctl/" + "config.json"

return location
}

// GetConfigs will get all config entries from the specified file
// Specify filename for different location, leave empty for default.
// returns ConfigFile and error
func getConfigs(fileName string) (ConfigFile, error) {

//Read full config and select the Alias
cfgFile := ConfigFile{}
cfgFileAsByte, err := readFile(fileName)
if err != nil {
return ConfigFile{}, err
}

err = json.Unmarshal(cfgFileAsByte, &cfgFile)
if err != nil {
return ConfigFile{}, err
}

return cfgFile, nil
}

// Read file and return byte array or error
func readFile(fileName string) ([]byte, error) {
f, err := os.Open(fileName)

if err != nil {
return nil, err
}

defer f.Close()
fileContent, err := ioutil.ReadAll(f)

if err != nil {
return nil, err
}

return fileContent, nil
}

// GetConfig will get the config entry with the specified alias
// Specify filename for different location, leave empty for default.
// returns ConfigEntry and error
func getConfig(filename, alias string) (ConfigEntry, error) {
cfg, err := getConfigs(filename)

if err != nil {
return ConfigEntry{}, err
}

//Find the config entry with the alias
for _, ce := range cfg.Configs {
if ce.Alias == alias {
return ce, nil
}
}

return ConfigEntry{}, fmt.Errorf("Could not find config entry with alias %s", alias)
}
103 changes: 76 additions & 27 deletions auxo/datasource_contact.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,49 +3,98 @@ package auxo
import (
"context"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/on2itsecurity/go-auxo"
)

func dataSourceContact() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceContactRead,
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Computed: true,
// Ensure the implementation satisfies the expected interfaces.
var (
_ datasource.DataSource = &contactDataSource{}
_ datasource.DataSourceWithConfigure = &contactDataSource{}
)

type contactDataSource struct {
client *auxo.Client
}

type contactDataSourceModel struct {
ID types.String `tfsdk:"id"`
Email types.String `tfsdk:"email"`
}

// NewcontactDataSource is a helper function to simplify the provider implementation.
func NewcontactDataSource() datasource.DataSource {
return &contactDataSource{}
}

// Metadata returns the data source type name.
func (d *contactDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_contact"
}

func (d *contactDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, _ *datasource.ConfigureResponse) {
if req.ProviderData == nil {
return
}

// Retrieve the client from the provider config
d.client = req.ProviderData.(*auxo.Client)
}

// Schema defines the schema for the data source.
func (d *contactDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Description: "A contact which can be used a.o. as main- or securitycontact in a `protectsurface`.",
MarkdownDescription: "A contact which can be used a.o. as main- or securitycontact in a `protectsurface`.",
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Description: "Computed unique IDs of the contact",
MarkdownDescription: "Computed unique IDs of the contact",
Computed: true,
},
"email": {
Type: schema.TypeString,
Required: true,
"email": schema.StringAttribute{
Description: "Emails of the contact",
MarkdownDescription: "Emails of the contact",
Required: true,
},
},
}
}

func dataSourceContactRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics

provider := m.(*AuxoProvider)
apiClient := provider.APIClient
contacts, err := apiClient.CRM.GetContacts()
// Read refreshes the Terraform state with the latest data.
func (d *contactDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var state contactDataSourceModel

//Get contacts
contacts, err := d.client.CRM.GetContacts()
if err != nil {
return diag.FromErr(err)
resp.Diagnostics.AddError("Unable to retrieve contacts", err.Error())
return
}

//Get input
var input contactDataSourceModel
diags := req.Config.Get(ctx, &input)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

//Find the contact
for _, c := range contacts {
if c.Email == d.Get("email").(string) {
d.SetId(c.ID)
d.Set("id", c.ID)
d.Set("email", c.Email)
if c.Email == input.Email.ValueString() {
state.ID = types.StringValue(c.ID)
state.Email = types.StringValue(c.Email)
break
}
}

if d.Id() == "" {
return diag.Errorf("Contact not found [%s]", d.Get("email").(string))
//set state
diags = resp.State.Set(ctx, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

return diags
}
Loading

0 comments on commit 367b87e

Please sign in to comment.