-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add harvester_cloudinit_secret
Signed-off-by: Frank Yang <[email protected]>
- Loading branch information
1 parent
2444e48
commit c3b9fdb
Showing
7 changed files
with
343 additions
and
16 deletions.
There are no files selected for viewing
30 changes: 30 additions & 0 deletions
30
internal/provider/cloudinitsecret/datasource_cloudinitsecret.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package cloudinitsecret | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
|
||
"github.com/harvester/terraform-provider-harvester/pkg/client" | ||
"github.com/harvester/terraform-provider-harvester/pkg/constants" | ||
) | ||
|
||
func DataSourceCloudInitSecret() *schema.Resource { | ||
return &schema.Resource{ | ||
ReadContext: dataSourceCloudInitSecretRead, | ||
Schema: DataSourceSchema(), | ||
} | ||
} | ||
|
||
func dataSourceCloudInitSecretRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
c := meta.(*client.Client) | ||
namespace := d.Get(constants.FieldCommonNamespace).(string) | ||
name := d.Get(constants.FieldCommonName).(string) | ||
secret, err := c.KubeClient.CoreV1().Secrets(namespace).Get(ctx, name, metav1.GetOptions{}) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
return diag.FromErr(resourceCloudInitSecretImport(d, secret)) | ||
} |
131 changes: 131 additions & 0 deletions
131
internal/provider/cloudinitsecret/resource_cloudinitsecret.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
package cloudinitsecret | ||
|
||
import ( | ||
"context" | ||
"encoding/base64" | ||
"fmt" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
corev1 "k8s.io/api/core/v1" | ||
apierrors "k8s.io/apimachinery/pkg/api/errors" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
|
||
"github.com/harvester/terraform-provider-harvester/internal/util" | ||
"github.com/harvester/terraform-provider-harvester/pkg/client" | ||
"github.com/harvester/terraform-provider-harvester/pkg/constants" | ||
"github.com/harvester/terraform-provider-harvester/pkg/helper" | ||
"github.com/harvester/terraform-provider-harvester/pkg/importer" | ||
) | ||
|
||
func ResourceCloudInitSecret() *schema.Resource { | ||
return &schema.Resource{ | ||
CreateContext: resourceCloudInitSecretCreate, | ||
ReadContext: resourceCloudInitSecretRead, | ||
DeleteContext: resourceCloudInitSecretDelete, | ||
UpdateContext: resourceCloudInitSecretUpdate, | ||
Importer: &schema.ResourceImporter{ | ||
StateContext: schema.ImportStatePassthroughContext, | ||
}, | ||
Schema: Schema(), | ||
} | ||
} | ||
|
||
func resourceCloudInitSecretCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
c := meta.(*client.Client) | ||
namespace := d.Get(constants.FieldCommonNamespace).(string) | ||
name := d.Get(constants.FieldCommonName).(string) | ||
toCreate, err := util.ResourceConstruct(d, Creator(namespace, name)) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
obj, err := c.KubeClient.CoreV1().Secrets(namespace).Create(ctx, toCreate.(*corev1.Secret), metav1.CreateOptions{}) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
return diag.FromErr(resourceCloudInitSecretImport(d, obj)) | ||
} | ||
|
||
func resourceCloudInitSecretUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
c := meta.(*client.Client) | ||
namespace, name, err := helper.IDParts(d.Id()) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
obj, err := c.KubeClient.CoreV1().Secrets(namespace).Get(ctx, name, metav1.GetOptions{}) | ||
if err != nil { | ||
if apierrors.IsNotFound(err) { | ||
d.SetId("") | ||
return nil | ||
} | ||
return diag.FromErr(err) | ||
} | ||
toUpdate, err := util.ResourceConstruct(d, Updater(obj)) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
_, err = c.KubeClient.CoreV1().Secrets(namespace).Update(ctx, toUpdate.(*corev1.Secret), metav1.UpdateOptions{}) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
return resourceCloudInitSecretRead(ctx, d, meta) | ||
} | ||
|
||
func resourceCloudInitSecretRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
c := meta.(*client.Client) | ||
namespace, name, err := helper.IDParts(d.Id()) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
obj, err := c.KubeClient.CoreV1().Secrets(namespace).Get(ctx, name, metav1.GetOptions{}) | ||
if err != nil { | ||
if apierrors.IsNotFound(err) { | ||
d.SetId("") | ||
return nil | ||
} | ||
return diag.FromErr(err) | ||
} | ||
return diag.FromErr(resourceCloudInitSecretImport(d, obj)) | ||
} | ||
|
||
func resourceCloudInitSecretDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
c := meta.(*client.Client) | ||
namespace, name, err := helper.IDParts(d.Id()) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
err = c.KubeClient.CoreV1().Secrets(namespace).Delete(ctx, name, metav1.DeleteOptions{}) | ||
if err != nil && !apierrors.IsNotFound(err) { | ||
return diag.FromErr(err) | ||
} | ||
d.SetId("") | ||
return nil | ||
} | ||
|
||
func resourceCloudInitSecretImport(d *schema.ResourceData, obj *corev1.Secret) error { | ||
stateGetter, err := importer.ResourceCloudInitSecretStateGetter(obj) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if d.Get(constants.FieldCloudInitSecretUserData) != "" && d.Get(constants.FieldCloudInitSecretUserDataBase64) == "" { | ||
userdata, err := base64.StdEncoding.DecodeString(stateGetter.States[constants.FieldCloudInitSecretUserDataBase64].(string)) | ||
if err != nil { | ||
return fmt.Errorf("can't decode userdata: %v", err) | ||
} | ||
stateGetter.States[constants.FieldCloudInitSecretUserData] = string(userdata) | ||
stateGetter.States[constants.FieldCloudInitSecretUserDataBase64] = "" | ||
} | ||
if d.Get(constants.FieldCloudInitSecretNetworkData) != "" && d.Get(constants.FieldCloudInitSecretNetworkDataBase64) == "" { | ||
networkdata, err := base64.StdEncoding.DecodeString(stateGetter.States[constants.FieldCloudInitSecretNetworkDataBase64].(string)) | ||
if err != nil { | ||
return fmt.Errorf("can't decode userdata: %v", err) | ||
} | ||
stateGetter.States[constants.FieldCloudInitSecretUserData] = string(networkdata) | ||
stateGetter.States[constants.FieldCloudInitSecretUserDataBase64] = "" | ||
} | ||
|
||
return util.ResourceStatesSet(d, stateGetter) | ||
} |
90 changes: 90 additions & 0 deletions
90
internal/provider/cloudinitsecret/resource_cloudinitsecret_constructor.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package cloudinitsecret | ||
|
||
import ( | ||
"encoding/base64" | ||
"fmt" | ||
|
||
corev1 "k8s.io/api/core/v1" | ||
|
||
"github.com/harvester/terraform-provider-harvester/internal/util" | ||
"github.com/harvester/terraform-provider-harvester/pkg/constants" | ||
) | ||
|
||
var ( | ||
_ util.Constructor = &Constructor{} | ||
) | ||
|
||
type Constructor struct { | ||
CloudInitSecret *corev1.Secret | ||
} | ||
|
||
func (c *Constructor) Setup() util.Processors { | ||
if c.CloudInitSecret.StringData == nil { | ||
c.CloudInitSecret.StringData = map[string]string{} | ||
} | ||
processors := util.NewProcessors().Tags(&c.CloudInitSecret.Labels).Description(&c.CloudInitSecret.Annotations) | ||
customProcessors := []util.Processor{ | ||
{ | ||
Field: constants.FieldCloudInitSecretUserData, | ||
Parser: func(i interface{}) error { | ||
c.CloudInitSecret.StringData["userdata"] = i.(string) | ||
return nil | ||
}, | ||
}, | ||
{ | ||
Field: constants.FieldCloudInitSecretUserDataBase64, | ||
Parser: func(i interface{}) error { | ||
value, err := base64.StdEncoding.DecodeString(i.(string)) | ||
if err != nil { | ||
return fmt.Errorf("failed to decode %s string: %w", constants.FieldCloudInitSecretUserDataBase64, err) | ||
} | ||
c.CloudInitSecret.StringData["userdata"] = string(value) | ||
return nil | ||
}, | ||
}, | ||
{ | ||
Field: constants.FieldCloudInitSecretNetworkData, | ||
Parser: func(i interface{}) error { | ||
c.CloudInitSecret.StringData["networkdata"] = i.(string) | ||
return nil | ||
}, | ||
}, | ||
{ | ||
Field: constants.FieldCloudInitSecretNetworkDataBase64, | ||
Parser: func(i interface{}) error { | ||
value, err := base64.StdEncoding.DecodeString(i.(string)) | ||
if err != nil { | ||
return fmt.Errorf("failed to decode %s string: %w", constants.FieldCloudInitSecretNetworkDataBase64, err) | ||
} | ||
c.CloudInitSecret.StringData["networkdata"] = string(value) | ||
return nil | ||
}, | ||
}, | ||
} | ||
return append(processors, customProcessors...) | ||
} | ||
|
||
func (c *Constructor) Validate() error { | ||
return nil | ||
} | ||
|
||
func (c *Constructor) Result() (interface{}, error) { | ||
return c.CloudInitSecret, nil | ||
} | ||
|
||
func newCloudInitSecretConstructor(cloudInitSecret *corev1.Secret) util.Constructor { | ||
return &Constructor{ | ||
CloudInitSecret: cloudInitSecret, | ||
} | ||
} | ||
|
||
func Creator(namespace, name string) util.Constructor { | ||
cloudInitSecret := &corev1.Secret{ | ||
ObjectMeta: util.NewObjectMeta(namespace, name), | ||
} | ||
return newCloudInitSecretConstructor(cloudInitSecret) | ||
} | ||
|
||
func Updater(cloudInitSecret *corev1.Secret) util.Constructor { | ||
return newCloudInitSecretConstructor(cloudInitSecret) | ||
} |
35 changes: 35 additions & 0 deletions
35
internal/provider/cloudinitsecret/schema_cloudinitsecret.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package cloudinitsecret | ||
|
||
import ( | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
|
||
"github.com/harvester/terraform-provider-harvester/internal/util" | ||
"github.com/harvester/terraform-provider-harvester/pkg/constants" | ||
) | ||
|
||
func Schema() map[string]*schema.Schema { | ||
s := map[string]*schema.Schema{ | ||
constants.FieldCloudInitSecretUserData: { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
constants.FieldCloudInitSecretUserDataBase64: { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
constants.FieldCloudInitSecretNetworkData: { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
constants.FieldCloudInitSecretNetworkDataBase64: { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
} | ||
util.NamespacedSchemaWrap(s, false) | ||
return s | ||
} | ||
|
||
func DataSourceSchema() map[string]*schema.Schema { | ||
return util.DataSourceSchemaWrap(Schema()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package constants | ||
|
||
const ( | ||
ResourceTypeCloudInitSecret = "harvester_cloudinit_secret" | ||
|
||
FieldCloudInitSecretUserData = "user_data" | ||
FieldCloudInitSecretNetworkData = "network_data" | ||
FieldCloudInitSecretUserDataBase64 = "user_data_base64" // #nosec G101 | ||
FieldCloudInitSecretNetworkDataBase64 = "network_data_base64" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package importer | ||
|
||
import ( | ||
"encoding/base64" | ||
|
||
corev1 "k8s.io/api/core/v1" | ||
|
||
"github.com/harvester/terraform-provider-harvester/pkg/constants" | ||
"github.com/harvester/terraform-provider-harvester/pkg/helper" | ||
) | ||
|
||
func ResourceCloudInitSecretStateGetter(obj *corev1.Secret) (*StateGetter, error) { | ||
states := map[string]interface{}{ | ||
constants.FieldCommonNamespace: obj.Namespace, | ||
constants.FieldCommonName: obj.Name, | ||
constants.FieldCommonDescription: GetDescriptions(obj.Annotations), | ||
constants.FieldCommonTags: GetTags(obj.Labels), | ||
constants.FieldCloudInitSecretUserDataBase64: base64.StdEncoding.EncodeToString(obj.Data["userdata"]), | ||
constants.FieldCloudInitSecretNetworkDataBase64: base64.StdEncoding.EncodeToString(obj.Data["networkdata"]), | ||
} | ||
|
||
return &StateGetter{ | ||
ID: helper.BuildID(obj.Namespace, obj.Name), | ||
Name: obj.Name, | ||
ResourceType: constants.ResourceTypeCloudInitSecret, | ||
States: states, | ||
}, nil | ||
} |