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

Implement support for DeletionProtection #50

Merged
merged 8 commits into from
Jul 27, 2024

Conversation

austin-denoble
Copy link
Contributor

@austin-denoble austin-denoble commented Jul 24, 2024

Problem

Our other SDKs support the deletion protection feature with the latest major releases tied to the 2024-07 API version. We need to implement deletion protection in the Go SDK.

Solution

  • Add new DeletionProtection enum type to models.go.
  • Update CreatePodIndexRequest, CreateServerlessIndexRequest, and Index to include DeletionProtection.
  • Update ConfigureIndex to support a ConfigureIndexParams struct argument. This aligns more closely with our other SDKs, and makes it easier to pass configurations of arguments without needing to explicitly pass nil.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • [] New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update
  • Infrastructure change (CI configs, etc)
  • Non-code change (docs, etc)
  • None of the above: (explain here)

Test Plan

Test serverless and pod creation functions to make sure DeletionProtection defaults to disabled, and vice versa when provided. Test ConfigureIndex to make sure configuring an index without passing DeletionProtection doesn't override things.


@austin-denoble austin-denoble force-pushed the adenoble/implement-deletion-protection branch from 9d5e110 to 45b6a71 Compare July 24, 2024 21:06
@@ -548,6 +552,7 @@ func (c *Client) CreatePodIndex(ctx context.Context, in *CreatePodIndexRequest)
// and consist only of lower case alphanumeric characters or '-'.
// - Dimension: The [dimensionality] of the vectors to be inserted in the Index.
// - Metric: The metric used to measure the [similarity] between vectors ('euclidean', 'cosine', or 'dotproduct').
// - DeletionProtection:
Copy link
Contributor

@aulorbe aulorbe Jul 25, 2024

Choose a reason for hiding this comment

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

Is this supposed to be filled in with a definition?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup, whoops missed updating the struct comments. Thanks!

// ConfigureIndexParams contains parameters for configuring an index. For both pod-based
// and serverless indexes you can configure the DeletionProtection status for an index.
// For pod-based indexes you can also configure the number of Replicas and the PodType.
// Each of the fields are optional, but at least one field must be set.
Copy link
Contributor

@aulorbe aulorbe Jul 25, 2024

Choose a reason for hiding this comment

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

When you say "each of the fields" here, do you mean btwn replicas and podtype or btwn those 2 + also deletion protection? It's not entirely clear to me from how this sentence is worded.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Between all 3, you can still pass Replicas or PodType to the server, it'll just respond with an error if it's a serverless index.

We enforce sending at least one argument in the struct on the client-side.

// - Replicas: (Optional) The number of replicas to scale the index to. This is capped by
// the maximum number of replicas allowed in your Pinecone project. To configure this number,
// go to [app.pinecone.io], select your project, and configure the maximum number of pods.
// - DeletionProtection: (Optional) // DeletionProtection determines whether [deletion protection]
Copy link
Contributor

Choose a reason for hiding this comment

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

Should the sentence here start with //?

Copy link
Contributor

Choose a reason for hiding this comment

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

Might be nice to also hyperlink this to documentation

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah I meant to add it as a link in the bottom with the references. Nice catch.

// ConfigureIndex is used to [scale a pods-based index] up or down by changing the size of the pods or the number of
// replicas.
// replicas, or to enable and disable deletion protection for an index.
Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry for being behind the times, but so now you can call ConfigureIndex on a serverless index?

Copy link
Contributor

@aulorbe aulorbe Jul 25, 2024

Choose a reason for hiding this comment

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

Should we add a test that tries to call ConfigureIndex on a serverless index, but passes in replicas and pods (which obvi aren't things on serverless indexes), and assert a failure? I think we should!

Could also just assert that we can call ConfigureIndex on a serverless index while only passing in DeletionProtection and everything goes well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, let me add a couple tests.

// [app.pinecone.io]: https://app.pinecone.io
func (c *Client) ConfigureIndex(ctx context.Context, name string, podType *string,
replicas *int32) (*Index, error) {
func (c *Client) ConfigureIndex(ctx context.Context, name string, in *ConfigureIndexParams) (*Index, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I like passing in a params struct here, nice thinking

@@ -1153,13 +1209,16 @@ func toIndex(idx *control.IndexModel) *Index {
Ready: idx.Status.Ready,
State: IndexStatusState(idx.Status.State),
}
deletionProtection := derefOrDefault(idx.DeletionProtection, "")
Copy link
Contributor

@aulorbe aulorbe Jul 25, 2024

Choose a reason for hiding this comment

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

Should this default to control.DISABLED instead of ""? I thought it could only ever be the enum vals?

_, err = ts.client.ConfigureIndex(context.Background(), name, nil, nil)
require.ErrorContainsf(ts.T(), err, "must specify either podType or replicas", err.Error())
_, err = ts.client.ConfigureIndex(context.Background(), name, &ConfigureIndexParams{})
require.ErrorContainsf(ts.T(), err, "must specify either PodType, Replicas, or DeletionProtection", err.Error())
Copy link
Contributor

Choose a reason for hiding this comment

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

I might just be accidentally overlooking it here, but should there also be a test simply testing deletion protection on its own? Like, if you pass in control.ENABLED, and then try to delete an index, you should not be able to, right?

Copy link
Contributor

@aulorbe aulorbe left a comment

Choose a reason for hiding this comment

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

Generally, this looks good to me! I like making the params into a struct and then passing that.

But I think you might want to add more tests for deletion protection. I see just 1 addition to a test that's already there (the one where you don't pass replicas, podType, or deletionProtection in), but I don't think that's enough... is it possible to add more, like I say here? (LMK if I'm just missing something and there are more tests!)

And more testing thoughts here #50 (comment)

@austin-denoble austin-denoble force-pushed the adenoble/implement-deletion-protection branch from 6677b88 to a1a119b Compare July 26, 2024 23:51
@austin-denoble
Copy link
Contributor Author

But I think you might want to add more tests for deletion protection. I see just 1 addition to a test that's already there (the one where you don't pass replicas, podType, or deletionProtection in), but I don't think that's enough... is it possible to add more, like I say here? (LMK if I'm just missing something and there are more tests!)

And more testing thoughts here #50 (comment)

Good call, tests added. For now they're testing pod and serverless explicitly.

@@ -1324,6 +1394,14 @@ func valueOrFallback[T comparable](value, fallback T) T {
}
}

func pointerOrNil[T comparable](value T) *T {
Copy link
Contributor

Choose a reason for hiding this comment

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

frickin' Go 🙄

err = ts.client.DeleteIndex(context.Background(), name)
require.ErrorContainsf(ts.T(), err, "failed to delete index: Deletion protection is enabled for this index", err.Error())

// make sure configuring the index without specifying DeletionProtection maintains "enabled" state
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice!

Copy link
Contributor

Choose a reason for hiding this comment

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

(I actually didn't know it worked like this, super cool)

Copy link
Contributor

@aulorbe aulorbe left a comment

Choose a reason for hiding this comment

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

looks great!

@austin-denoble austin-denoble merged commit 08d2c76 into main Jul 27, 2024
3 checks passed
@austin-denoble austin-denoble deleted the adenoble/implement-deletion-protection branch July 27, 2024 03:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants