Skip to content

Commit

Permalink
Allow CLI user to delete private domain.
Browse files Browse the repository at this point in the history
- checks to make sure domain is private and returns error message if
user attempts to delete-private-domain a shared domain.

[finishes #162998032]

Authored-by: Piyali Banerjee <pbanerjee@pivotal.io>
  • Loading branch information
piyalibanerjee committed May 2, 2019
1 parent 278d35c commit c69cbbf
Show file tree
Hide file tree
Showing 8 changed files with 617 additions and 9 deletions.
34 changes: 34 additions & 0 deletions actor/v7action/domain.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"code.cloudfoundry.org/cli/actor/actionerror"
"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3"
"code.cloudfoundry.org/cli/types"
"fmt"
)

type Domain ccv3.Domain
Expand Down Expand Up @@ -58,6 +59,39 @@ func (actor Actor) DeleteSharedDomain(domainName string) (Warnings, error) {
return allWarnings, err
}

func (actor Actor) DeletePrivateDomain(domainName string) (Warnings, error) {
allWarnings := Warnings{}
domain, warnings, err := actor.GetDomainByName(domainName)

allWarnings = append(allWarnings, warnings...)

if err != nil {
return allWarnings, err
}
_, apiWarnings, err := actor.CloudControllerClient.DeleteDomain(domain.GUID)

actorWarnings := Warnings(apiWarnings)
allWarnings = append(allWarnings, actorWarnings...)

return allWarnings, err
}

func (actor Actor) CheckSharedDomain(domainName string) (Warnings, error) {
allWarnings := Warnings{}
domain, warnings, err := actor.GetDomainByName(domainName)

allWarnings = append(allWarnings, warnings...)

if err != nil {
return allWarnings, err
}
if domain.Shared() {
err = fmt.Errorf(``)
}

return allWarnings, err
}

func (actor Actor) GetOrganizationDomains(orgGuid string) ([]Domain, Warnings, error) {
ccv3Domains, warnings, err := actor.CloudControllerClient.GetOrganizationDomains(orgGuid)

Expand Down
48 changes: 48 additions & 0 deletions actor/v7action/domain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,26 @@ var _ = Describe("Domain Actions", func() {
})
})

Describe("check if shared domain", func() {
When("deleting attempting to delete a shared domain", func() {
BeforeEach(func() {
fakeCloudControllerClient.GetDomainsReturns(
[]ccv3.Domain{
{Name: "the-domain.com", GUID: "shared-domain-guid"},
},
ccv3.Warnings{"get-domains-warning"},
nil,
)
})

It("delegates to the cloud controller client", func() {
warnings, executeErr := actor.CheckSharedDomain("the-domain.com")
Expect(executeErr).To(MatchError("Domain the-domain.com is a shared domain, not a private domain."))
Expect(warnings).To(ConsistOf("get-domains-warning"))
})
})
})

Describe("delete shared domain", func() {
BeforeEach(func() {
fakeCloudControllerClient.GetDomainsReturns(
Expand All @@ -101,6 +121,34 @@ var _ = Describe("Domain Actions", func() {
})
})

Describe("delete private domain", func() {
When("deleting a private domain", func() {
BeforeEach(func() {
fakeCloudControllerClient.GetDomainsReturns(
[]ccv3.Domain{
{Name: "the-domain.com", OrganizationGUID: "org-guid", GUID: "private-domain-guid"},
},
ccv3.Warnings{"get-domains-warning"},
nil,
)
})

It("delegates to the cloud controller client", func() {
fakeCloudControllerClient.DeleteDomainReturns(ccv3.JobURL("https://job.com"), ccv3.Warnings{"delete-warning"}, errors.New("delete-error"))

warnings, executeErr := actor.DeletePrivateDomain("the-domain.com")
Expect(executeErr).To(MatchError("delete-error"))
Expect(warnings).To(ConsistOf("get-domains-warning", "delete-warning"))

Expect(fakeCloudControllerClient.DeleteDomainCallCount()).To(Equal(1))
passedDomainGuid := fakeCloudControllerClient.DeleteDomainArgsForCall(0)

Expect(passedDomainGuid).To(Equal("private-domain-guid"))
})
})

})

Describe("list domains for org", func() {
var (
ccv3Domains []ccv3.Domain
Expand Down
2 changes: 1 addition & 1 deletion command/common/command_list_v7.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ type commandList struct {
CreateUser v6.CreateUserCommand `command:"create-user" description:"Create a new user"`
Curl v6.CurlCommand `command:"curl" description:"Executes a request to the targeted API endpoint"`
DeleteBuildpack v7.DeleteBuildpackCommand `command:"delete-buildpack" description:"Delete a buildpack"`
DeleteDomain v6.DeleteDomainCommand `command:"delete-domain" description:"Delete a domain"`
DeleteIsolationSegment v6.DeleteIsolationSegmentCommand `command:"delete-isolation-segment" description:"Delete an isolation segment"`
DeleteLabel v7.DeleteLabelCommand `command:"delete-label" description:"Delete a label (key-value pairs) for an API resource"`
DeleteOrg v6.DeleteOrgCommand `command:"delete-org" description:"Delete an org"`
DeleteOrphanedRoutes v6.DeleteOrphanedRoutesCommand `command:"delete-orphaned-routes" description:"Delete all orphaned routes in the currently targeted space (i.e. those that are not mapped to an app)"`
DeletePrivateDomain v7.DeletePrivateDomainCommand `command:"delete-private-domain" description:"Delete a private domain"`
DeleteQuota v6.DeleteQuotaCommand `command:"delete-quota" description:"Delete a quota"`
DeleteRoute v6.DeleteRouteCommand `command:"delete-route" description:"Delete a route"`
DeleteSecurityGroup v6.DeleteSecurityGroupCommand `command:"delete-security-group" description:"Deletes a security group"`
Expand Down
1 change: 1 addition & 0 deletions command/v7/create_private_domain_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ func (cmd CreatePrivateDomainCommand) Execute(args []string) error {
}

cmd.UI.DisplayOK()

cmd.UI.DisplayText("TIP: Domain '{{.Domain}}' is a private domain. Run 'cf share-private-domain' to share this domain with a different org.",
map[string]interface{}{
"Domain": domain,
Expand Down
109 changes: 109 additions & 0 deletions command/v7/delete_private_domain_command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package v7

import (
"code.cloudfoundry.org/cli/actor/actionerror"
"code.cloudfoundry.org/cli/actor/sharedaction"
"code.cloudfoundry.org/cli/actor/v7action"
"code.cloudfoundry.org/cli/command"
"code.cloudfoundry.org/cli/command/flag"
"code.cloudfoundry.org/cli/command/v7/shared"
)

//go:generate counterfeiter . DeletePrivateDomainActor

type DeletePrivateDomainActor interface {
DeletePrivateDomain(domainName string) (v7action.Warnings, error)
CheckSharedDomain(domainName string) (v7action.Warnings, error)
}

type DeletePrivateDomainCommand struct {
RequiredArgs flag.Domain `positional-args:"yes"`
Force bool `short:"f" description:"Force deletion without confirmation"`
usage interface{} `usage:"CF_NAME delete-private-domain DOMAIN [-f]"`
relatedCommands interface{} `related_commands:"delete-shared-domain, domains, unshare-private-domain"`

UI command.UI
Config command.Config
SharedActor command.SharedActor
Actor DeletePrivateDomainActor
}

func (cmd *DeletePrivateDomainCommand) Setup(config command.Config, ui command.UI) error {
cmd.UI = ui
cmd.Config = config
cmd.SharedActor = sharedaction.NewActor(config)

ccClient, _, err := shared.NewClients(config, ui, true, "")
if err != nil {
return err
}
cmd.Actor = v7action.NewActor(ccClient, config, nil, nil)

return nil
}

func (cmd DeletePrivateDomainCommand) Execute(args []string) error {
domain := cmd.RequiredArgs.Domain
err := cmd.SharedActor.CheckTarget(true, false)
if err != nil {
return err
}

currentUser, err := cmd.Config.CurrentUser()
if err != nil {
return err
}

shareCheckWarnings, shareCheckErr := cmd.Actor.CheckSharedDomain(domain)

if shareCheckErr != nil {
cmd.UI.DisplayText("Domain '{{.DomainName}}' is a shared domain, not a private domain.", map[string]interface{}{
"DomainName": domain,
})
cmd.UI.DisplayWarnings(shareCheckWarnings)
return shareCheckErr
}

cmd.UI.DisplayText("Deleting the private domain will remove associated routes which will make apps with this domain unreachable.")

if !cmd.Force {
response, promptErr := cmd.UI.DisplayBoolPrompt(false, "Really delete the private domain {{.DomainName}}?", map[string]interface{}{
"DomainName": domain,
})

if promptErr != nil {
return promptErr
}

if !response {
cmd.UI.DisplayText("'{{.DomainName}}' has not been deleted.", map[string]interface{}{
"DomainName": domain,
})
return nil
}
}
cmd.UI.DisplayTextWithFlavor("Deleting private domain {{.DomainName}} as {{.Username}}...", map[string]interface{}{
"DomainName": domain,
"Username": currentUser.Name,
})

warnings, err := cmd.Actor.DeletePrivateDomain(domain)
cmd.UI.DisplayWarnings(warnings)
if err != nil {
switch err.(type) {
case actionerror.DomainNotFoundError:
cmd.UI.DisplayTextWithFlavor("Domain {{.DomainName}} not found", map[string]interface{}{
"DomainName": domain,
})

default:
return err
}
}

cmd.UI.DisplayOK()

cmd.UI.DisplayText("TIP: Run 'cf domains' to view available domains.")

return nil
}
Loading

0 comments on commit c69cbbf

Please sign in to comment.