-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add rancher_certificate resource type (#12717)
- Loading branch information
Showing
4 changed files
with
347 additions
and
0 deletions.
There are no files selected for viewing
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
277 changes: 277 additions & 0 deletions
277
builtin/providers/rancher/resource_rancher_certificate.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,277 @@ | ||
package rancher | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"time" | ||
|
||
"github.com/hashicorp/terraform/helper/resource" | ||
"github.com/hashicorp/terraform/helper/schema" | ||
rancher "github.com/rancher/go-rancher/client" | ||
) | ||
|
||
func resourceRancherCertificate() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceRancherCertificateCreate, | ||
Read: resourceRancherCertificateRead, | ||
Update: resourceRancherCertificateUpdate, | ||
Delete: resourceRancherCertificateDelete, | ||
Importer: &schema.ResourceImporter{ | ||
State: resourceRancherCertificateImport, | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"id": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"name": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
"description": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
"environment_id": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
"cert": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
"cert_chain": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
"key": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
"cn": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"algorithm": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"cert_fingerprint": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"expires_at": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"issued_at": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"issuer": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"key_size": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"serial_number": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"subject_alternative_names": &schema.Schema{ | ||
Type: schema.TypeSet, | ||
Elem: &schema.Schema{Type: schema.TypeString}, | ||
Computed: true, | ||
}, | ||
"version": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceRancherCertificateCreate(d *schema.ResourceData, meta interface{}) error { | ||
log.Printf("[INFO][rancher] Creating Certificate: %s", d.Id()) | ||
client, err := meta.(*Config).EnvironmentClient(d.Get("environment_id").(string)) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
name := d.Get("name").(string) | ||
description := d.Get("description").(string) | ||
cert := d.Get("cert").(string) | ||
certChain := d.Get("cert_chain").(string) | ||
key := d.Get("key").(string) | ||
|
||
certificate := rancher.Certificate{ | ||
Name: name, | ||
Description: description, | ||
Cert: cert, | ||
CertChain: certChain, | ||
Key: key, | ||
} | ||
newCertificate, err := client.Certificate.Create(&certificate) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
stateConf := &resource.StateChangeConf{ | ||
Pending: []string{"active", "removed", "removing"}, | ||
Target: []string{"active"}, | ||
Refresh: CertificateStateRefreshFunc(client, newCertificate.Id), | ||
Timeout: 10 * time.Minute, | ||
Delay: 1 * time.Second, | ||
MinTimeout: 3 * time.Second, | ||
} | ||
_, waitErr := stateConf.WaitForState() | ||
if waitErr != nil { | ||
return fmt.Errorf( | ||
"Error waiting for registry credential (%s) to be created: %s", newCertificate.Id, waitErr) | ||
} | ||
|
||
d.SetId(newCertificate.Id) | ||
log.Printf("[INFO] Certificate ID: %s", d.Id()) | ||
|
||
return resourceRancherCertificateUpdate(d, meta) | ||
} | ||
|
||
func resourceRancherCertificateRead(d *schema.ResourceData, meta interface{}) error { | ||
log.Printf("[INFO] Refreshing Certificate: %s", d.Id()) | ||
client, err := meta.(*Config).EnvironmentClient(d.Get("environment_id").(string)) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
certificate, err := client.Certificate.ById(d.Id()) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
log.Printf("[INFO] Certificate Name: %s", certificate.Name) | ||
|
||
d.Set("description", certificate.Description) | ||
d.Set("name", certificate.Name) | ||
|
||
// Computed values | ||
d.Set("cn", certificate.CN) | ||
d.Set("algorithm", certificate.Algorithm) | ||
d.Set("cert_fingerprint", certificate.CertFingerprint) | ||
d.Set("expires_at", certificate.ExpiresAt) | ||
d.Set("issued_at", certificate.IssuedAt) | ||
d.Set("issuer", certificate.Issuer) | ||
d.Set("key_size", certificate.KeySize) | ||
d.Set("serial_number", certificate.SerialNumber) | ||
d.Set("subject_alternative_names", certificate.SubjectAlternativeNames) | ||
d.Set("version", certificate.Version) | ||
|
||
return nil | ||
} | ||
|
||
func resourceRancherCertificateUpdate(d *schema.ResourceData, meta interface{}) error { | ||
log.Printf("[INFO] Updating Certificate: %s", d.Id()) | ||
client, err := meta.(*Config).EnvironmentClient(d.Get("environment_id").(string)) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
certificate, err := client.Certificate.ById(d.Id()) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
name := d.Get("name").(string) | ||
description := d.Get("description").(string) | ||
cert := d.Get("cert").(string) | ||
certChain := d.Get("cert_chain").(string) | ||
key := d.Get("key").(string) | ||
|
||
data := map[string]interface{}{ | ||
"name": &name, | ||
"description": &description, | ||
"cert": &cert, | ||
"cert_chain": &certChain, | ||
"key": &key, | ||
} | ||
|
||
var newCertificate rancher.Certificate | ||
if err := client.Update("certificate", &certificate.Resource, data, &newCertificate); err != nil { | ||
return err | ||
} | ||
|
||
return resourceRancherCertificateRead(d, meta) | ||
} | ||
|
||
func resourceRancherCertificateDelete(d *schema.ResourceData, meta interface{}) error { | ||
log.Printf("[INFO] Deleting Certificate: %s", d.Id()) | ||
id := d.Id() | ||
client, err := meta.(*Config).EnvironmentClient(d.Get("environment_id").(string)) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
certificate, err := client.Certificate.ById(id) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if err := client.Certificate.Delete(certificate); err != nil { | ||
return fmt.Errorf("Error deleting Certificate: %s", err) | ||
} | ||
|
||
log.Printf("[DEBUG] Waiting for certificate (%s) to be removed", id) | ||
|
||
stateConf := &resource.StateChangeConf{ | ||
Pending: []string{"active", "removed", "removing"}, | ||
Target: []string{"removed"}, | ||
Refresh: CertificateStateRefreshFunc(client, id), | ||
Timeout: 10 * time.Minute, | ||
Delay: 1 * time.Second, | ||
MinTimeout: 3 * time.Second, | ||
} | ||
|
||
_, waitErr := stateConf.WaitForState() | ||
if waitErr != nil { | ||
return fmt.Errorf( | ||
"Error waiting for certificate (%s) to be removed: %s", id, waitErr) | ||
} | ||
|
||
d.SetId("") | ||
return nil | ||
} | ||
|
||
func resourceRancherCertificateImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { | ||
envID, resourceID := splitID(d.Id()) | ||
d.SetId(resourceID) | ||
if envID != "" { | ||
d.Set("environment_id", envID) | ||
} else { | ||
client, err := meta.(*Config).GlobalClient() | ||
if err != nil { | ||
return []*schema.ResourceData{}, err | ||
} | ||
stack, err := client.Environment.ById(d.Id()) | ||
if err != nil { | ||
return []*schema.ResourceData{}, err | ||
} | ||
d.Set("environment_id", stack.AccountId) | ||
} | ||
return []*schema.ResourceData{d}, nil | ||
} | ||
|
||
// CertificateStateRefreshFunc returns a resource.StateRefreshFunc that is used to watch | ||
// a Rancher Certificate. | ||
func CertificateStateRefreshFunc(client *rancher.RancherClient, certificateID string) resource.StateRefreshFunc { | ||
return func() (interface{}, string, error) { | ||
cert, err := client.Certificate.ById(certificateID) | ||
|
||
if err != nil { | ||
return nil, "", err | ||
} | ||
|
||
return cert, cert.State, nil | ||
} | ||
} |
66 changes: 66 additions & 0 deletions
66
website/source/docs/providers/rancher/r/certificate.html.markdown
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,66 @@ | ||
--- | ||
layout: "rancher" | ||
page_title: "Rancher: rancher_certificate" | ||
sidebar_current: "docs-rancher-resource-certificate" | ||
description: |- | ||
Provides a Rancher Certificate resource. This can be used to create certificates for rancher environments and retrieve their information. | ||
--- | ||
|
||
# rancher\_certificate | ||
|
||
Provides a Rancher Certificate resource. This can be used to create certificates for rancher environments and retrieve their information. | ||
|
||
## Example Usage | ||
|
||
```hcl | ||
# Create a new Rancher Certificate | ||
resource rancher_certificate "foo" { | ||
name = "foo" | ||
description = "my foo certificate" | ||
environment_id = "${rancher_environment.test.id}" | ||
cert = "${file("server.crt")}" | ||
key = "${file("server.key")}" | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
* `name` - (Required) The name of the registry credential. | ||
* `description` - (Optional) A registry credential description. | ||
* `environment_id` - (Required) The ID of the environment to create the certificate for. | ||
* `cert` - (Required) The certificate content. | ||
* `cert_chain` - (Optional) The certificate chain. | ||
* `key` - (Required) The certificate key. | ||
|
||
## Attributes Reference | ||
|
||
The following attributes are exported: | ||
|
||
* `cn` - The certificate CN. | ||
* `algorithm` - The certificate algorithm. | ||
* `cert_fingerprint` - The certificate fingerprint. | ||
* `expires_at` - The certificate expiration date. | ||
* `issued_at` - The certificate creation date. | ||
* `issuer` - The certificate issuer. | ||
* `key_size` - The certificate key size. | ||
* `serial_number` - The certificate serial number. | ||
* `subject_alternative_names` - The list of certificate Subject Alternative Names. | ||
* `version` - The certificate version. | ||
|
||
## Import | ||
|
||
Registry credentials can be imported using the Registry and credentials | ||
IDs in the format `<environment_id>/<certificate_id>` | ||
|
||
``` | ||
$ terraform import rancher_certificate.mycert 1sp31/1c605 | ||
``` | ||
|
||
If the credentials for the Rancher provider have access to the global API, | ||
then `environment_id` can be omitted e.g. | ||
|
||
``` | ||
$ terraform import rancher_certificate.mycert 1c605 | ||
``` |
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