Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: mcli integration #536

Merged
merged 1 commit into from
Aug 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

realm has a different base url, if I override the one for atlas I need to change the one for realm as well and they should not share it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh makes sense, thank you gustavo

}

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

var ua = "terraform-provider-mongodbatlas/" + version.ProviderVersion
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extracting the duplicated UA


// 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")
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to format as there's no interpolation

}

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 != "" {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for realm you should override both

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",
Comment on lines +27 to +28
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pick first non empty

}, ""),
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,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[q] any reason we were not setting this? can't find any docs that says not to do it when is a configuration

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question, I'm not aware of any blocker either but @abner-dou @coderGo93 or @thetonymaster - any issue?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good eye, yes for private key should be a sensitive, I wasn't aware of that part probably it was there that from the beginning

},
"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 {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to if here we already if to not use it if empty

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 {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deadcode

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).
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

avoiding passive voice

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
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

env first, static later, lazy readers will stop after first example and may skip the warning is not secure


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/).