diff --git a/chainlink/data_source_chainlink_wallet.go b/chainlink/data_source_chainlink_wallet.go deleted file mode 100644 index 2f25811..0000000 --- a/chainlink/data_source_chainlink_wallet.go +++ /dev/null @@ -1,36 +0,0 @@ -package chainlink - -import ( - "github.com/hashicorp/terraform/helper/schema" - "github.com/linkpoolio/terraform-provider-chainlink/client" -) - -func DataSourceChainlinkWallet() *schema.Resource { - return &schema.Resource{ - Read: resourceDataWalletRead, - - Schema: mergeSchemaWithNodeProperties(map[string]*schema.Schema{ - "address": { - Type: schema.TypeString, - Computed: true, - }, - }), - } -} - -func resourceDataWalletRead(d *schema.ResourceData, m interface{}) error { - c, err := NewClientFromModel(d, m) - if err != nil { - return err - } - - if addr, err := c.ReadWallet(); err != nil { - return err - } else if err := d.Set("address", addr); err != nil { - return err - } else { - m := client.NewMatcher("wallet", addr) - d.SetId(m.Id()) - } - return nil -} diff --git a/chainlink/data_source_eth_key.go b/chainlink/data_source_eth_key.go new file mode 100644 index 0000000..b013538 --- /dev/null +++ b/chainlink/data_source_eth_key.go @@ -0,0 +1,47 @@ +package chainlink + +import ( + "fmt" + "github.com/hashicorp/terraform/helper/schema" +) + +func DataSourceETHKey() *schema.Resource { + return &schema.Resource{ + Read: resourceETHKeyRead, + + Schema: mergeSchemaWithNodeProperties(map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "index": { + Type: schema.TypeInt, + Optional: true, + Default: 0, + }, + }), + } +} + +func resourceETHKeyRead(d *schema.ResourceData, m interface{}) error { + c, err := NewClientFromModel(d, m) + if err != nil { + return err + } + + keys, err := c.ReadETHKeys() + if err != nil { + return err + } + + index, ok := d.Get("index").(int) + if !ok { + return fmt.Errorf("provided index of %s is not an integer", fmt.Sprint(index)) + } + if index >= len(keys.Data) { + return fmt.Errorf("provided index of %d exceeds %d amount of keys returned", index, len(keys.Data)) + } + + d.SetId(keys.Data[index].Attributes.Address) + return nil +} diff --git a/chainlink/resource_chainlink_bridge.go b/chainlink/resource_chainlink_bridge.go index 9f47674..c8b8a56 100644 --- a/chainlink/resource_chainlink_bridge.go +++ b/chainlink/resource_chainlink_bridge.go @@ -41,8 +41,7 @@ func resourceBridgeTypeCreate(d *schema.ResourceData, m interface{}) error { if err != nil { return err } - matcher := client.NewMatcher("bridge", name) - d.SetId(matcher.Id()) + d.SetId(name) return nil } diff --git a/chainlink/resource_chainlink_spec.go b/chainlink/resource_chainlink_spec.go index 86be719..811a8af 100644 --- a/chainlink/resource_chainlink_spec.go +++ b/chainlink/resource_chainlink_spec.go @@ -13,11 +13,6 @@ func ResourceChainlinkSpec() *schema.Resource { Update: resourceSpecUpdate, Schema: mergeSchemaWithNodeProperties(map[string]*schema.Schema{ - "spec_id": { - Type: schema.TypeString, - Computed: true, - ForceNew: true, - }, "json": { Type: schema.TypeString, Required: true, @@ -40,11 +35,7 @@ func resourceSpecCreate(d *schema.ResourceData, m interface{}) error { return err } - matcher := client.NewMatcher("spec", id) - d.SetId(matcher.Id()) - if err := d.Set("spec_id", id); err != nil { - return err - } + d.SetId(id) return nil } @@ -54,15 +45,12 @@ func resourceSpecRead(d *schema.ResourceData, m interface{}) error { return err } - spec, err := c.ReadSpec(d.Get("spec_id").(string)) - + _, err = c.ReadSpec(d.Id()) if err == client.ErrNotFound { d.SetId("") } else if err != nil { d.SetId("") return err - } else if err := d.Set("spec_id", spec.Data["id"]); err != nil { - return err } return nil } @@ -80,5 +68,5 @@ func resourceSpecDelete(d *schema.ResourceData, m interface{}) error { return err } - return c.DeleteSpec(d.Get("spec_id").(string)) + return c.DeleteSpec(d.Id()) } diff --git a/chainlink/resource_chainlink_spec_v2.go b/chainlink/resource_chainlink_spec_v2.go index e10f88f..6410391 100644 --- a/chainlink/resource_chainlink_spec_v2.go +++ b/chainlink/resource_chainlink_spec_v2.go @@ -13,11 +13,6 @@ func ResourceChainlinkSpecV2() *schema.Resource { Update: resourceSpecV2Update, Schema: mergeSchemaWithNodeProperties(map[string]*schema.Schema{ - "spec_id": { - Type: schema.TypeString, - Computed: true, - ForceNew: true, - }, "toml": { Type: schema.TypeString, Required: true, @@ -34,19 +29,26 @@ func resourceSpecV2Create(d *schema.ResourceData, m interface{}) error { } toml := d.Get("toml").(string) - id, err := c.CreateSpecV2(toml) + spec, err := c.CreateSpecV2(toml) if err != nil { return err } - matcher := client.NewMatcher("spec_v2", id) - d.SetId(matcher.Id()) - if err := d.Set("spec_id", id); err != nil { - return err - } + d.SetId(spec.Data.ID) return nil } -func resourceSpecV2Read(_ *schema.ResourceData, _ interface{}) error { +func resourceSpecV2Read(d *schema.ResourceData, m interface{}) error { + c, err := NewClientFromModel(d, m) + if err != nil { + return err + } + + if err := c.ReadSpecV2(d.Id()); err == client.ErrNotFound || err == client.ErrUnprocessableEntity { + d.SetId("") + return nil + } else if err != nil { + return err + } return nil } @@ -63,5 +65,5 @@ func resourceSpecV2Delete(d *schema.ResourceData, m interface{}) error { return err } - return c.DeleteSpecV2(d.Get("spec_id").(string)) + return c.DeleteSpecV2(d.Id()) } diff --git a/client/client.go b/client/client.go index 45b6f91..cdba2f1 100644 --- a/client/client.go +++ b/client/client.go @@ -10,6 +10,7 @@ import ( ) var ErrNotFound = errors.New("unexpected response code, got 404") +var ErrUnprocessableEntity = errors.New("unexpected response code, got 422") func NewChainlink(c *Config) (*Chainlink, error) { cl := &Chainlink{Config: c} @@ -22,21 +23,21 @@ func (c *Chainlink) CreateSpec(spec string) (string, error) { return fmt.Sprint(specResp.Data["id"]), err } -func (c *Chainlink) CreateSpecV2(spec string) (string, error) { - specV2Create := struct { - TOML string `json:"toml"` - }{ +func (c *Chainlink) CreateSpecV2(spec string) (*SpecV2, error) { + specV2 := &SpecV2{} + _, err := c.do(http.MethodPost, "/v2/jobs", &SpecV2Form{ TOML: spec, - } - specV2Resp := struct { - JobID int32 `json:"jobID"` - }{} - _, err := c.do(http.MethodPost, "/v2/ocr/specs", specV2Create, &specV2Resp, http.StatusOK) - return fmt.Sprint(specV2Resp.JobID), err + }, &specV2, http.StatusOK) + return specV2, err +} + +func (c *Chainlink) ReadSpecV2(id string) error { + _, err := c.do(http.MethodGet, fmt.Sprintf("/v2/jobs/%s", id), nil, nil, http.StatusOK) + return err } func (c *Chainlink) DeleteSpecV2(id string) error { - _, err := c.do(http.MethodDelete, fmt.Sprintf("/v2/ocr/specs/%s", id), nil, nil, http.StatusNoContent) + _, err := c.do(http.MethodDelete, fmt.Sprintf("/v2/jobs/%s", id), nil, nil, http.StatusNoContent) return err } @@ -67,50 +68,46 @@ func (c *Chainlink) DeleteBridge(name string) error { return err } -func (c *Chainlink) ReadWallet() (string, error) { - walletObj := &ResponseArray{} - if _, err := c.do(http.MethodGet, "/v2/user/balances", nil, &walletObj, http.StatusOK); err != nil { - return "", err - } else if len(walletObj.Data) == 0 { - return "", fmt.Errorf("unexpected response back from Chainlink, no wallets were given") - } - return fmt.Sprint(walletObj.Data[0]["id"]), nil -} - func (c *Chainlink) CreateOCRKey() (*OCRKey, error) { ocrKey := &OCRKey{} - _, err := c.do(http.MethodPost, "/v2/off_chain_reporting_keys", nil, ocrKey, http.StatusOK) + _, err := c.do(http.MethodPost, "/v2/keys/ocr", nil, ocrKey, http.StatusOK) return ocrKey, err } func (c *Chainlink) ReadOCRKeys() (*OCRKeys, error) { ocrKeys := &OCRKeys{} - _, err := c.do(http.MethodGet, "/v2/off_chain_reporting_keys", nil, ocrKeys, http.StatusOK) + _, err := c.do(http.MethodGet, "/v2/keys/ocr", nil, ocrKeys, http.StatusOK) return ocrKeys, err } func (c *Chainlink) DeleteOCRKey(id string) error { - _, err := c.do(http.MethodDelete, fmt.Sprintf("/v2/off_chain_reporting_keys/%s", id), nil, nil, http.StatusOK) + _, err := c.do(http.MethodDelete, fmt.Sprintf("/v2/keys/ocr/%s", id), nil, nil, http.StatusOK) return err } func (c *Chainlink) CreateP2PKey() (*P2PKey, error) { p2pKey := &P2PKey{} - _, err := c.do(http.MethodPost, "/v2/p2p_keys", nil, p2pKey, http.StatusOK) + _, err := c.do(http.MethodPost, "/v2/keys/p2p", nil, p2pKey, http.StatusOK) return p2pKey, err } func (c *Chainlink) ReadP2PKeys() (*P2PKeys, error) { p2pKeys := &P2PKeys{} - _, err := c.do(http.MethodGet, "/v2/p2p_keys", nil, p2pKeys, http.StatusOK) + _, err := c.do(http.MethodGet, "/v2/keys/p2p", nil, p2pKeys, http.StatusOK) return p2pKeys, err } func (c *Chainlink) DeleteP2PKey(id int) error { - _, err := c.do(http.MethodDelete, fmt.Sprintf("/v2/p2p_keys/%d", id), nil, nil, http.StatusOK) + _, err := c.do(http.MethodDelete, fmt.Sprintf("/v2/keys/p2p/%d", id), nil, nil, http.StatusOK) return err } +func (c *Chainlink) ReadETHKeys() (*ETHKeys, error) { + ethKeys := ÐKeys{} + _, err := c.do(http.MethodGet, "/v2/keys/eth", nil, ethKeys, http.StatusOK) + return ethKeys, err +} + func (c *Chainlink) doRaw( method, endpoint string, @@ -133,21 +130,23 @@ func (c *Chainlink) doRaw( resp, err := client.Do(req) if err != nil { return resp, err - } else if obj == nil { - return resp, err } b, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("error while reading response: %v\nURL: %s\nresponse received: %s", err, c.Config.URL, string(b)) } - - if resp.StatusCode == 404 { + if resp.StatusCode == http.StatusNotFound { return resp, ErrNotFound + } else if resp.StatusCode == http.StatusUnprocessableEntity { + return resp, ErrUnprocessableEntity } else if resp.StatusCode != expectedStatusCode { return resp, fmt.Errorf("unexpected response code, got %d, expected 200\nURL: %s\nresponse received: %s", resp.StatusCode, c.Config.URL, string(b)) } + if obj == nil { + return resp, err + } err = json.Unmarshal(b, &obj) if err != nil { return nil, fmt.Errorf("error while unmarshaling response: %v\nURL: %s\nresponse received: %s", err, c.Config.URL, string(b)) diff --git a/client/models.go b/client/models.go index e9e0166..a4eaf3c 100644 --- a/client/models.go +++ b/client/models.go @@ -1,9 +1,7 @@ package client import ( - "fmt" "net/http" - "strings" ) type Config struct { @@ -81,6 +79,34 @@ type P2PKeyAttributes struct { PublicKey string `json:"publicKey"` } +type ETHKeys struct { + Data []ETHKeyData `json:"data"` +} + +type ETHKey struct { + Data ETHKeyData `json:"data"` +} + +type ETHKeyData struct { + Attributes ETHKeyAttributes `json:"attributes"` +} + +type ETHKeyAttributes struct { + Address string `json:"address"` +} + +type SpecV2Form struct { + TOML string `json:"toml"` +} + +type SpecV2 struct { + Data SpecV2Data `json:"data"` +} + +type SpecV2Data struct { + ID string `json:"id"` +} + type Client interface { CreateBridge(addr, name, url string) error ReadBridge(id string) (*BridgeType, error) @@ -96,28 +122,3 @@ type Chainlink struct { type DataIdentifier interface { Id() string } - -type Matcher struct { - DataIdentifier - Object string - Data string -} - -func NewMatcher(obj, data string) Matcher { - return Matcher{ - Object: obj, - Data: data, - } -} - -func NewMatcherFromID(id string) Matcher { - s := strings.Split(id, Delimiter()) - return Matcher{ - Object: s[0], - Data: s[1], - } -} - -func (i *Matcher) Id() string { - return fmt.Sprintf("%s%s%s", i.Object, Delimiter(), i.Data) -} diff --git a/client/utils.go b/client/utils.go deleted file mode 100644 index dd84e7c..0000000 --- a/client/utils.go +++ /dev/null @@ -1,5 +0,0 @@ -package client - -func Delimiter() string { - return "-cl-" -} \ No newline at end of file diff --git a/docs/data-sources/wallet.md b/docs/data-sources/eth_key.md similarity index 65% rename from docs/data-sources/wallet.md rename to docs/data-sources/eth_key.md index ec71c45..11ec26a 100644 --- a/docs/data-sources/wallet.md +++ b/docs/data-sources/eth_key.md @@ -2,27 +2,30 @@ page_title: "chainlink_wallet Data Source - terraform-provider-chainlink" subcategory: "" description: |- - Get the active nodes wallet address as shown in Chainlink config + Get an active ETH key as shown within the keys page. --- -# Data Source `chainlink_wallet` +# Data Source `chainlink_eth_key` -Get the active wallet address as shown in config. +Get an ETH wallet address. ## Example Usage ```terraform -data "chainlink_wallet" "this" {} +data "chainlink_eth_key" "this" {} ``` ## Schema ### Optional +- **index** (Integer, Optional, Default: 0) the index within the returned keys to return + +--- - **chainlink_url** (String, Optional) equivalent to `url` in the provider configuration, takes precedence over the provider - **chainlink_email** (String, Optional) equivalent to `email` in the provider configuration, takes precedence over the provider - **chainlink_password** (String, Optional) equivalent to `password` in the provider configuration, takes precedence over the provider ### Read-only -- **address** (String, Read-only) the Ethereum address of the Chainlink node +- **id** (String, Read-only) the Ethereum address of the ETH key diff --git a/docs/resources/spec.md b/docs/resources/spec.md index 1119475..895c772 100644 --- a/docs/resources/spec.md +++ b/docs/resources/spec.md @@ -62,4 +62,4 @@ resource "chainlink_spec" "vrf" { ### Read-only -- **spec_id** (String, Read-only) the ID of the job spec +- **id** (String, Read-only) the ID of the job spec diff --git a/docs/resources/spec_v2.md b/docs/resources/spec_v2.md index fe60502..25a45cb 100644 --- a/docs/resources/spec_v2.md +++ b/docs/resources/spec_v2.md @@ -33,4 +33,4 @@ resource "chainlink_spec_v2" "bootstrap" { ### Read-only -- **spec_id** (String, Read-only) the ID of the v2 job spec +- **id** (String, Read-only) the ID of the v2 job spec diff --git a/provider.go b/provider.go index 40c2b12..f974e4a 100644 --- a/provider.go +++ b/provider.go @@ -36,7 +36,7 @@ func Provider() *schema.Provider { "chainlink_p2p_key": chainlink.ResourceChainlinkP2PKey(), }, DataSourcesMap: map[string]*schema.Resource{ - "chainlink_wallet": chainlink.DataSourceChainlinkWallet(), + "chainlink_eth_key": chainlink.DataSourceETHKey(), }, } }