Skip to content

Commit

Permalink
feat: mcli integration (#536)
Browse files Browse the repository at this point in the history
  • Loading branch information
gssbzn authored Aug 27, 2021
1 parent de6a15f commit e8944c5
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 71 deletions.
28 changes: 15 additions & 13 deletions mongodbatlas/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,24 @@ package mongodbatlas

import (
"context"
"fmt"
"errors"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/logging"
"github.com/mongodb-forks/digest"
"github.com/mongodb/terraform-provider-mongodbatlas/version"
"github.com/spf13/cast"
realmAuth "go.mongodb.org/realm/auth"

"github.com/mongodb-forks/digest"
matlasClient "go.mongodb.org/atlas/mongodbatlas"
realmAuth "go.mongodb.org/realm/auth"
"go.mongodb.org/realm/realm"
)

// Config struct ...
type Config struct {
PublicKey string
PrivateKey string
BaseURL string
PublicKey string
PrivateKey string
BaseURL string
RealmBaseURL string
}

// MongoDBClient client
Expand All @@ -28,6 +28,8 @@ type MongoDBClient struct {
Config *Config
}

var ua = "terraform-provider-mongodbatlas/" + version.ProviderVersion

// NewClient func...
func (c *Config) NewClient(ctx context.Context) (interface{}, diag.Diagnostics) {
// setup a transport to handle digest
Expand All @@ -41,8 +43,8 @@ func (c *Config) NewClient(ctx context.Context) (interface{}, diag.Diagnostics)

client.Transport = logging.NewTransport("MongoDB Atlas", transport)

optsAtlas := []matlasClient.ClientOpt{matlasClient.SetUserAgent("terraform-provider-mongodbatlas/" + version.ProviderVersion)}
if len(c.BaseURL) > 0 {
optsAtlas := []matlasClient.ClientOpt{matlasClient.SetUserAgent(ua)}
if c.BaseURL != "" {
optsAtlas = append(optsAtlas, matlasClient.SetBaseURL(c.BaseURL))
}

Expand All @@ -63,12 +65,12 @@ func (c *Config) NewClient(ctx context.Context) (interface{}, diag.Diagnostics)
func (c *MongoDBClient) GetRealmClient(ctx context.Context) (*realm.Client, error) {
// Realm
if c.Config.PublicKey == "" && c.Config.PrivateKey == "" {
return nil, fmt.Errorf("please set `public_key` and `private_key` in order to use the realm client")
return nil, errors.New("please set `public_key` and `private_key` in order to use the realm client")
}

optsRealm := []realm.ClientOpt{realm.SetUserAgent("terraform-provider-mongodbatlas/" + version.ProviderVersion)}
if len(c.Config.BaseURL) > 0 {
optsRealm = append(optsRealm, realm.SetBaseURL(c.Config.BaseURL))
optsRealm := []realm.ClientOpt{realm.SetUserAgent(ua)}
if c.Config.BaseURL != "" && c.Config.RealmBaseURL != "" {
optsRealm = append(optsRealm, realm.SetBaseURL(c.Config.RealmBaseURL))
}
authConfig := realmAuth.NewConfig(nil)
token, err := authConfig.NewTokenFromCredentials(ctx, c.Config.PublicKey, c.Config.PrivateKey)
Expand Down
54 changes: 28 additions & 26 deletions mongodbatlas/provider.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package mongodbatlas

import (
"bytes"
"context"
"encoding/base64"
"fmt"
Expand All @@ -22,22 +21,38 @@ func Provider() *schema.Provider {
return &schema.Provider{
Schema: map[string]*schema.Schema{
"public_key": {
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("MONGODB_ATLAS_PUBLIC_KEY", ""),
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.MultiEnvDefaultFunc([]string{
"MONGODB_ATLAS_PUBLIC_KEY",
"MCLI_PUBLIC_API_KEY",
}, ""),
Description: "MongoDB Atlas Programmatic Public Key",
},
"private_key": {
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("MONGODB_ATLAS_PRIVATE_KEY", ""),
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.MultiEnvDefaultFunc([]string{
"MONGODB_ATLAS_PRIVATE_KEY",
"MCLI_PRIVATE_API_KEY",
}, ""),
Description: "MongoDB Atlas Programmatic Private Key",
Sensitive: true,
},
"base_url": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.MultiEnvDefaultFunc([]string{
"MONGODB_ATLAS_BASE_URL",
"MCLI_OPS_MANAGER_URL",
}, ""),
Description: "MongoDB Atlas Base URL",
},
"realm_base_url": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("MONGODB_ATLAS_BASE_URL", ""),
Description: "MongoDB Atlas Base URL",
DefaultFunc: schema.EnvDefaultFunc("MONGODB_REALM_BASE_URL", ""),
Description: "MongoDB Realm Base URL",
},
},

Expand Down Expand Up @@ -129,12 +144,10 @@ func Provider() *schema.Provider {

func providerConfigure(ctx context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) {
config := Config{
PublicKey: d.Get("public_key").(string),
PrivateKey: d.Get("private_key").(string),
}

if baseURL, ok := d.GetOk("base_url"); ok {
config.BaseURL = baseURL.(string)
PublicKey: d.Get("public_key").(string),
PrivateKey: d.Get("private_key").(string),
BaseURL: d.Get("base_url").(string),
RealmBaseURL: d.Get("realm_base_url").(string),
}

return config.NewClient(ctx)
Expand Down Expand Up @@ -302,14 +315,3 @@ func HashCodeString(s string) int {
// v == MinInt
return 0
}

// HashCodeStrings hashes a list of strings to a unique hashcode.
func HashCodeStrings(hashStrings []string) string {
var buf bytes.Buffer

for _, s := range hashStrings {
buf.WriteString(fmt.Sprintf("%s-", s))
}

return fmt.Sprintf("%d", HashCodeString(buf.String()))
}
74 changes: 42 additions & 32 deletions website/docs/index.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ description: |-

# MongoDB Atlas Provider

The MongoDB Atlas provider is used to interact with the resources supported by [MongoDB Atlas](https://www.mongodb.com/cloud/atlas). The provider needs to be configured with the proper credentials before it can be used.
You can use the MongoDB Atlas provider to interact with the resources supported by [MongoDB Atlas](https://www.mongodb.com/cloud/atlas).
The provider needs to be configured with the proper credentials before it can be used.

Use the navigation to the left to read about the available provider resources and data sources.

You may want to consider pinning the [provider version](https://www.terraform.io/docs/configuration/providers.html#provider-versions) to ensure you have a chance to review and prepare for changes. Speaking of changes, see [CHANGELOG](https://github.com/mongodb/terraform-provider-mongodbatlas/blob/master/CHANGELOG.md) for current version information.
You may want to consider pinning the [provider version](https://www.terraform.io/docs/configuration/providers.html#provider-versions) to ensure you have a chance to review and prepare for changes.
Speaking of changes, see [CHANGELOG](https://github.com/mongodb/terraform-provider-mongodbatlas/blob/master/CHANGELOG.md) for current version information.

## Example Usage

Expand All @@ -22,37 +24,25 @@ provider "mongodbatlas" {
public_key = var.mongodbatlas_public_key
private_key = var.mongodbatlas_private_key
}
#Create the resources
...
# Create the resources
```

## Configure Atlas Programmatic Access

In order to setup authentication with the MongoDB Atlas provider a programmatic API key must be generated for MongoDB Atlas with the appropriate permissions and IP access list entries. The [MongoDB Atlas documentation](https://docs.atlas.mongodb.com/tutorial/manage-programmatic-access/index.html) contains the most up-to-date instructions for creating and managing your key(s) and IP access. Be aware, not all API resources require an IP access list by default, but one can set Atlas to require IP access entries for all API resources, see the [organization settings documentation](https://docs.atlas.mongodb.com/tutorial/manage-organization-settings/#require-ip-access-list-for-public-api) for more info.
In order to set up authentication with the MongoDB Atlas provider a programmatic API key must be generated for MongoDB Atlas with the appropriate permissions and IP access list entries.
The [MongoDB Atlas documentation](https://docs.atlas.mongodb.com/tutorial/manage-programmatic-access/index.html) contains the most up-to-date instructions for creating and managing your key(s) and IP access.
Be aware, not all API resources require an IP access list by default, but one can set Atlas to require IP access entries for all API resources, see the [organization settings documentation](https://docs.atlas.mongodb.com/tutorial/manage-organization-settings/#require-ip-access-list-for-public-api) for more info.

## Authenticate the Provider

The MongoDB Atlas provider offers a flexible means of providing credentials for authentication. The following methods are supported and explained below:

### Static credentials

Static credentials can be provided by adding the following attributes in-line in the MongoDB Atlas provider block, either directly or via input variable/local value:

Usage:

```hcl
provider "mongodbatlas" {
public_key = "atlas_public_api_key" #required
private_key = "atlas_private_api_key" #required
}
```

~> *IMPORTANT* Hard-coding your MongoDB Atlas programmatic API key pair into a Terraform configuration is not recommended. Consider the risks, especially the inadvertent submission of a configuration file containing secrets to a public repository.
The MongoDB Atlas provider offers a flexible means of providing credentials for authentication.
You can use any the following methods:

### Environment variables
### Environment Variables

You can also provide your credentials via the environment variables, MONGODB_ATLAS_PUBLIC_KEY and MONGODB_ATLAS_PRIVATE_KEY, for your public and private MongoDB Atlas programmatic API key pair respectively:
You can also provide your credentials via the environment variables,
`MONGODB_ATLAS_PUBLIC_KEY` and `MONGODB_ATLAS_PRIVATE_KEY`,
for your public and private MongoDB Atlas programmatic API key pair respectively:

```hcl
provider "mongodbatlas" {}
Expand All @@ -66,19 +56,36 @@ $ export MONGODB_ATLAS_PRIVATE_KEY="xxxx"
$ terraform plan
```

As an alternative to `MONGODB_ATLAS_PUBLIC_KEY` and `MONGODB_ATLAS_PRIVATE_KEY`
if you are using [MongoDB CLI](https://docs.mongodb.com/mongocli/stable/)
then `MCLI_PUBLIC_API_KEY` and `MCLI_PRIVATE_API_KEY` are also supported.

### Static Credentials

Static credentials can be provided by adding the following attributes in-line in the MongoDB Atlas provider block,
either directly or via input variable/local value:

```hcl
provider "mongodbatlas" {
public_key = "atlas_public_api_key" #required
private_key = "atlas_private_api_key" #required
}
```

~> *IMPORTANT* Hard-coding your MongoDB Atlas programmatic API key pair into a Terraform configuration is not recommended.
Consider the risks, especially the inadvertent submission of a configuration file containing secrets to a public repository.

## Argument Reference

In addition to [generic `provider`
arguments](https://www.terraform.io/docs/configuration/providers.html) (e.g.
`alias` and `version`), the following arguments are supported in the MongoDB
Atlas `provider` block:
In addition to [generic `provider` arguments](https://www.terraform.io/docs/configuration/providers.html)
(e.g. `alias` and `version`), the MongoDB Atlas `provider` supports the following arguments:

* `public_key` - (Optional) This is the public key of your MongoDB Atlas API key pair. It must be
provided, but it can also be sourced from the `MONGODB_ATLAS_PUBLIC_KEY`
provided, but it can also be sourced from the `MONGODB_ATLAS_PUBLIC_KEY` or `MCLI_PUBLIC_API_KEY`
environment variable.

* `private_key` - (Optional) This is the private key of your MongoDB Atlas key pair. It must be
provided, but it can also be sourced from the `MONGODB_ATLAS_PRIVATE_KEY`
provided, but it can also be sourced from the `MONGODB_ATLAS_PRIVATE_KEY` or `MCLI_PRIVATE_API_KEY`
environment variable.

For more information on configuring and managing programmatic API Keys see the [MongoDB Atlas Documentation](https://docs.atlas.mongodb.com/tutorial/manage-programmatic-access/index.html).
Expand All @@ -97,7 +104,10 @@ For more information on configuring and managing programmatic API Keys see the [

## Examples from MongoDB and the Community

We have [example configurations](https://github.com/mongodb/terraform-provider-mongodbatlas/tree/master/examples) in our GitHub repo that will help both beginner and more advanced users.
We have [example configurations](https://github.com/mongodb/terraform-provider-mongodbatlas/tree/master/examples)
in our GitHub repo that will help both beginner and more advanced users.

Have a good example you've created and want to share? Let us know the details via an [issue](https://github.com/mongodb/terraform-provider-mongodbatlas/issues) or submit a PR of your work to add it to the examples directory in our [GitHub repo](https://github.com/mongodb/terraform-provider-mongodbatlas/).
Have a good example you've created and want to share?
Let us know the details via an [issue](https://github.com/mongodb/terraform-provider-mongodbatlas/issues)
or submit a PR of your work to add it to the `examples` directory in our [GitHub repo](https://github.com/mongodb/terraform-provider-mongodbatlas/).

0 comments on commit e8944c5

Please sign in to comment.