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

[Feature]: App Developer can run cf create-user-provided-service to store service credentials in a user-provided service instance #430

Closed
tcdowney opened this issue Jan 10, 2022 · 1 comment
Assignees
Labels

Comments

@tcdowney
Copy link
Member

tcdowney commented Jan 10, 2022

Blockers/Dependencies

Background

Note: User-provided Service Instance == UPSI

As an App Developer
I want to be able to create UPSIs
So that I can manually configure my apps with service credentials

Check out the Cloud Foundry User-Provided Service Instance docs for more information on this feature.


Acceptance Criteria

Creating a Service Instance with type user-provided (without params)

GIVEN I have targeted an org / space
WHEN I run cf create-user-provided-service my-upsi
THEN I see it was created successfully

15:29 $ cf cups my-upsi -v
Creating user provided service my-upsi in org org / space space as admin...
OK

AND I see the following request/response

Request: POST /v3/service_instances
Request Body:

{
  "name": "my-upsi",
  "relationships": {
    "space": {
      "data": {
        "guid": "9ed0bece-8e24-4d9f-9350-49f5762b9e33"
      }
    }
  },
  "type": "user-provided"
}

Response:

HTTP/1.1 201 Created

{
  "created_at": "2022-01-10T22:29:12Z",
  "guid": "8eb4bca4-f06c-438a-87b9-7877aa02fc37",
  "last_operation": {
    "created_at": "2022-01-10T22:29:12Z",
    "description": "Operation succeeded",
    "state": "succeeded",
    "type": "create",
    "updated_at": "2022-01-10T22:29:12Z"
  },
  "links": {
    "credentials": {
      "href": "https://api.example.com/v3/service_instances/8eb4bca4-f06c-438a-87b9-7877aa02fc37/credentials"
    },
    "self": {
      "href": "https://api.example.com/v3/service_instances/8eb4bca4-f06c-438a-87b9-7877aa02fc37"
    },
    "service_credential_bindings": {
      "href": "https://api.example.com/v3/service_credential_bindings?service_instance_guids=8eb4bca4-f06c-438a-87b9-7877aa02fc37"
    },
    "service_route_bindings": {
      "href": "https://api.example.com/v3/service_route_bindings?service_instance_guids=8eb4bca4-f06c-438a-87b9-7877aa02fc37"
    },
    "space": {
      "href": "https://api.example.com/v3/spaces/9ed0bece-8e24-4d9f-9350-49f5762b9e33"
    }
  },
  "metadata": {
    "annotations": {},
    "labels": {}
  },
  "name": "my-upsi",
  "relationships": {
    "space": {
      "data": {
        "guid": "9ed0bece-8e24-4d9f-9350-49f5762b9e33"
      }
    }
  },
  "route_service_url": null,
  "syslog_drain_url": null,
  "tags": [],
  "type": "user-provided",
  "updated_at": "2022-01-10T22:29:12Z"
}

AND I can use kubectl get cfserviceinstances -n <space-guid> to see that a CFServiceInstance resource was created that matches what I asked for and that an empty Secret was created.


Creating a Service Instance with type user-provided (with params)

GIVEN I have targeted an org / space
WHEN I run cf create-user-provided-service my-upsi -p '{"username":"admin","password":"pa55woRD"}'
THEN I see it was created successfully

15:29 $ cf cups my-upsi -p '{"username":"admin","password":"pa55woRD"}' -v
Creating user provided service my-upsi in org org / space space as admin...
OK

AND I see the following request/response

Request: POST /v3/service_instances
Request Body:

{
  "credentials": {
    "password": "pa55woRD",
    "username": "admin"
  },
  "name": "my-upsi",
  "relationships": {
    "space": {
      "data": {
        "guid": "9ed0bece-8e24-4d9f-9350-49f5762b9e33"
      }
    }
  },
  "type": "user-provided"
}

Response:

{
  "created_at": "2022-01-10T22:34:29Z",
  "guid": "0942349b-b69b-41e3-aaa8-65a4091a9ef5",
  "last_operation": {
    "created_at": "2022-01-10T22:34:29Z",
    "description": "Operation succeeded",
    "state": "succeeded",
    "type": "create",
    "updated_at": "2022-01-10T22:34:29Z"
  },
  "links": {
    "credentials": {
      "href": "https://api.example.com/v3/service_instances/0942349b-b69b-41e3-aaa8-65a4091a9ef5/credentials"
    },
    "self": {
      "href": "https://api.example.com/v3/service_instances/0942349b-b69b-41e3-aaa8-65a4091a9ef5"
    },
    "service_credential_bindings": {
      "href": "https://api.example.com/v3/service_credential_bindings?service_instance_guids=0942349b-b69b-41e3-aaa8-65a4091a9ef5"
    },
    "service_route_bindings": {
      "href": "https://api.example.com/v3/service_route_bindings?service_instance_guids=0942349b-b69b-41e3-aaa8-65a4091a9ef5"
    },
    "space": {
      "href": "https://api.example.com/v3/spaces/9ed0bece-8e24-4d9f-9350-49f5762b9e33"
    }
  },
  "metadata": {
    "annotations": {},
    "labels": {}
  },
  "name": "my-upsi",
  "relationships": {
    "space": {
      "data": {
        "guid": "9ed0bece-8e24-4d9f-9350-49f5762b9e33"
      }
    }
  },
  "route_service_url": null,
  "syslog_drain_url": null,
  "tags": [],
  "type": "user-provided",
  "updated_at": "2022-01-10T22:34:29Z"
}

AND I can use kubectl get cfserviceinstances -n <space-guid> to see that a CFServiceInstance resource was created that matches what I asked for and that a Secret was created containing the username/password combo I provided.

These should look similar to how they're defined in the proposal doc:

Example CFServiceInstance

---
apiVersion: services.cloudfoundry.org/v1alpha1
kind: CFServiceInstance

metadata:
  
  name: 7e0dec79-2f4e-43ee-a682-3c3f4b8e7fd1 # service instance guid
  namespace: 9ed0bece-8e24-4d9f-9350-49f5762b9e33 # space guid
  labels:
    servicebinding.io/provisioned-service: "true"
spec:
  name: my-upsi # service instance name requested by dev
  secretName: cf-service-credentials-7e0dec79-2f4e-43ee-a682-3c3f4b8e7fd1
  type: user-provided

Example Secret

---
apiVersion: v1
kind: Secret
metadata:
  name: cf-service-credentials-7e0dec79-2f4e-43ee-a682-3c3f4b8e7fd1
  namespace: 9ed0bece-8e24-4d9f-9350-49f5762b9e33 # space guid
type: servicebinding.io/user-provided
stringData:
  password: pa55woRD
  username: admin

Creating a Service Instance with type managed

GIVEN I have targeted an org/space
WHEN I I attempt to create a "regular"/ managed service instance (cf create-service)
THEN I get a 422 error with a message saying that managed services are not supported


Creating a Service Instance with route_service_url set

GIVEN I have targeted an org/space
WHEN I I attempt to create a Route Service UPSI with the -r flag
THEN I get a 422 error with a message saying that route services are not supported


Creating a Service Instance with syslog_drain_url set

GIVEN I have targeted an org/space
WHEN I I attempt to create a Syslog Drain Service UPSI with the -l flag
THEN I get a 422 error with a message saying that syslog drain services are not supported


Dev Notes

@tcdowney
Copy link
Member Author

@davewalter @akrishna90

I hope it's ok that there's no explicit A/C for this, but POST /v3/service_instances call accepts an array of string "tags" that get included into VCAP_SERVICES. The only validation I could find for them is that the total length across all tags should be under 2048 characters:

https://github.com/cloudfoundry/cloud_controller_ng/blob/02e0035da375c20cafa807f895b2de60fbd4a862/app/models/services/service_instance.rb#L257-L261

akrishna90 added a commit that referenced this issue Jan 25, 2022
akrishna90 added a commit that referenced this issue Jan 25, 2022
akrishna90 added a commit that referenced this issue Jan 26, 2022
akrishna90 added a commit that referenced this issue Jan 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Archived in project
Development

No branches or pull requests

3 participants