diff --git a/github/config.go b/github/config.go index 031baeab54..08bed87986 100644 --- a/github/config.go +++ b/github/config.go @@ -3,6 +3,7 @@ package github import ( "context" "crypto/tls" + "fmt" "net/http" "net/url" @@ -16,6 +17,7 @@ type Config struct { Organization string BaseURL string Insecure bool + Individual bool } type Organization struct { @@ -27,7 +29,7 @@ type Organization struct { // Client configures and returns a fully initialized GithubClient func (c *Config) Client() (interface{}, error) { var org Organization - org.name = c.Organization + ts := oauth2.StaticTokenSource( &oauth2.Token{AccessToken: c.Token}, ) @@ -39,6 +41,14 @@ func (c *Config) Client() (interface{}, error) { ctx = context.WithValue(ctx, oauth2.HTTPClient, insecureClient) } + if c.Individual { + org.name = "" + } else if c.Organization != "" { + org.name = c.Organization + } else { + return nil, fmt.Errorf("If `individual` is false, `organization` is required.") + } + tc := oauth2.NewClient(ctx, ts) tc.Transport = NewEtagTransport(tc.Transport) diff --git a/github/data_source_github_repositories.go b/github/data_source_github_repositories.go index f8ed1b8473..ad8d914879 100644 --- a/github/data_source_github_repositories.go +++ b/github/data_source_github_repositories.go @@ -43,6 +43,11 @@ func dataSourceGithubRepositories() *schema.Resource { } func dataSourceGithubRepositoriesRead(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client query := d.Get("query").(string) diff --git a/github/data_source_github_repository.go b/github/data_source_github_repository.go index 5c0dc9c92e..a463da2f28 100644 --- a/github/data_source_github_repository.go +++ b/github/data_source_github_repository.go @@ -103,8 +103,12 @@ func dataSourceGithubRepository() *schema.Resource { } func dataSourceGithubRepositoryRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*Organization).client + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client orgName := meta.(*Organization).name var repoName string diff --git a/github/provider.go b/github/provider.go index 29ce952766..9eb9d0086c 100644 --- a/github/provider.go +++ b/github/provider.go @@ -17,7 +17,7 @@ func Provider() terraform.ResourceProvider { }, "organization": { Type: schema.TypeString, - Required: true, + Optional: true, DefaultFunc: schema.EnvDefaultFunc("GITHUB_ORGANIZATION", nil), Description: descriptions["organization"], }, @@ -33,6 +33,12 @@ func Provider() terraform.ResourceProvider { Default: false, Description: descriptions["insecure"], }, + "individual": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: descriptions["individual"], + }, }, ResourcesMap: map[string]*schema.Resource{ @@ -77,12 +83,15 @@ func init() { descriptions = map[string]string{ "token": "The OAuth token used to connect to GitHub.", - "organization": "The GitHub organization name to manage.", + "organization": "The GitHub organization name to manage. " + + "If `individual` is false, organization is required.", "base_url": "The GitHub Base API URL", "insecure": "Whether server should be accessed " + "without verifying the TLS certificate.", + + "individual": "Whether to run outside an organization.", } } @@ -93,6 +102,7 @@ func providerConfigure(p *schema.Provider) schema.ConfigureFunc { Organization: d.Get("organization").(string), BaseURL: d.Get("base_url").(string), Insecure: d.Get("insecure").(bool), + Individual: d.Get("individual").(bool), } meta, err := config.Client() diff --git a/github/provider_test.go b/github/provider_test.go index 015f5ec122..bd83181d8f 100644 --- a/github/provider_test.go +++ b/github/provider_test.go @@ -65,6 +65,35 @@ func testAccPreCheck(t *testing.T) { } } +func TestProvider_individual(t *testing.T) { + individualProviderConfig := `provider "github" { + organization = "" + individual = true +} +` + username := "hashibot" + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testAccCheckGithubMembershipDestroy, + Steps: []resource.TestStep{ + { + Config: individualProviderConfig + testAccCheckGithubUserDataSourceConfig(username), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet("data.github_user.test", "name"), + resource.TestCheckResourceAttr("data.github_user.test", "name", "HashiBot"), + ), + }, + { + Config: individualProviderConfig + testAccGithubMembershipConfig(username), + ExpectError: regexp.MustCompile("This resource requires GitHub organization to be set on the provider."), + }, + }, + }) +} + func TestProvider_insecure(t *testing.T) { // Use ephemeral port range (49152–65535) port := fmt.Sprintf("%d", 49152+rand.Intn(16382)) diff --git a/github/resource_github_branch_protection.go b/github/resource_github_branch_protection.go index 7b5ca70f15..3d2e91b9f7 100644 --- a/github/resource_github_branch_protection.go +++ b/github/resource_github_branch_protection.go @@ -139,6 +139,11 @@ func resourceGithubBranchProtection() *schema.Resource { } func resourceGithubBranchProtectionCreate(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client orgName := meta.(*Organization).name @@ -169,6 +174,11 @@ func resourceGithubBranchProtectionCreate(d *schema.ResourceData, meta interface } func resourceGithubBranchProtectionRead(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client repoName, branch, err := parseTwoPartID(d.Id()) @@ -223,6 +233,11 @@ func resourceGithubBranchProtectionRead(d *schema.ResourceData, meta interface{} } func resourceGithubBranchProtectionUpdate(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client repoName, branch, err := parseTwoPartID(d.Id()) if err != nil { @@ -266,6 +281,11 @@ func resourceGithubBranchProtectionUpdate(d *schema.ResourceData, meta interface } func resourceGithubBranchProtectionDelete(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client repoName, branch, err := parseTwoPartID(d.Id()) if err != nil { diff --git a/github/resource_github_issue_label.go b/github/resource_github_issue_label.go index 5617d5c8c8..f510ce2524 100644 --- a/github/resource_github_issue_label.go +++ b/github/resource_github_issue_label.go @@ -60,6 +60,11 @@ func resourceGithubIssueLabel() *schema.Resource { // same function for two schema funcs. func resourceGithubIssueLabelCreateOrUpdate(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client orgName := meta.(*Organization).name repoName := d.Get("repository").(string) @@ -130,6 +135,11 @@ func resourceGithubIssueLabelCreateOrUpdate(d *schema.ResourceData, meta interfa } func resourceGithubIssueLabelRead(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client repoName, name, err := parseTwoPartID(d.Id()) if err != nil { @@ -171,6 +181,11 @@ func resourceGithubIssueLabelRead(d *schema.ResourceData, meta interface{}) erro } func resourceGithubIssueLabelDelete(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client orgName := meta.(*Organization).name @@ -179,7 +194,7 @@ func resourceGithubIssueLabelDelete(d *schema.ResourceData, meta interface{}) er ctx := context.WithValue(context.Background(), ctxId, d.Id()) log.Printf("[DEBUG] Deleting label: %s (%s/%s)", name, orgName, repoName) - _, err := client.Issues.DeleteLabel(ctx, + _, err = client.Issues.DeleteLabel(ctx, orgName, repoName, name) return err } diff --git a/github/resource_github_membership.go b/github/resource_github_membership.go index 4955387ba3..e52884de9e 100644 --- a/github/resource_github_membership.go +++ b/github/resource_github_membership.go @@ -41,6 +41,11 @@ func resourceGithubMembership() *schema.Resource { } func resourceGithubMembershipCreateOrUpdate(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client orgName := meta.(*Organization).name @@ -69,6 +74,11 @@ func resourceGithubMembershipCreateOrUpdate(d *schema.ResourceData, meta interfa } func resourceGithubMembershipRead(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client orgName := meta.(*Organization).name @@ -107,12 +117,17 @@ func resourceGithubMembershipRead(d *schema.ResourceData, meta interface{}) erro } func resourceGithubMembershipDelete(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client orgName := meta.(*Organization).name ctx := context.WithValue(context.Background(), ctxId, d.Id()) log.Printf("[DEBUG] Deleting membership: %s", d.Id()) - _, err := client.Organizations.RemoveOrgMembership(ctx, + _, err = client.Organizations.RemoveOrgMembership(ctx, d.Get("username").(string), orgName) return err diff --git a/github/resource_github_organization_project.go b/github/resource_github_organization_project.go index e9b081af98..6da40a0436 100644 --- a/github/resource_github_organization_project.go +++ b/github/resource_github_organization_project.go @@ -43,6 +43,11 @@ func resourceGithubOrganizationProject() *schema.Resource { } func resourceGithubOrganizationProjectCreate(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client orgName := meta.(*Organization).name name := d.Get("name").(string) @@ -66,6 +71,11 @@ func resourceGithubOrganizationProjectCreate(d *schema.ResourceData, meta interf } func resourceGithubOrganizationProjectRead(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client orgName := meta.(*Organization).name @@ -105,6 +115,11 @@ func resourceGithubOrganizationProjectRead(d *schema.ResourceData, meta interfac } func resourceGithubOrganizationProjectUpdate(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client orgName := meta.(*Organization).name @@ -131,8 +146,12 @@ func resourceGithubOrganizationProjectUpdate(d *schema.ResourceData, meta interf } func resourceGithubOrganizationProjectDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*Organization).client + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client orgName := meta.(*Organization).name projectID, err := strconv.ParseInt(d.Id(), 10, 64) if err != nil { diff --git a/github/resource_github_organization_webhook.go b/github/resource_github_organization_webhook.go index 318db5ca99..835d1f84dd 100644 --- a/github/resource_github_organization_webhook.go +++ b/github/resource_github_organization_webhook.go @@ -73,6 +73,11 @@ func resourceGithubOrganizationWebhookObject(d *schema.ResourceData) *github.Hoo } func resourceGithubOrganizationWebhookCreate(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client orgName := meta.(*Organization).name @@ -91,6 +96,11 @@ func resourceGithubOrganizationWebhookCreate(d *schema.ResourceData, meta interf } func resourceGithubOrganizationWebhookRead(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client orgName := meta.(*Organization).name @@ -130,6 +140,11 @@ func resourceGithubOrganizationWebhookRead(d *schema.ResourceData, meta interfac } func resourceGithubOrganizationWebhookUpdate(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client orgName := meta.(*Organization).name @@ -152,6 +167,11 @@ func resourceGithubOrganizationWebhookUpdate(d *schema.ResourceData, meta interf } func resourceGithubOrganizationWebhookDelete(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client orgName := meta.(*Organization).name diff --git a/github/resource_github_project_column.go b/github/resource_github_project_column.go index 7d9d262b2b..2383f62b02 100644 --- a/github/resource_github_project_column.go +++ b/github/resource_github_project_column.go @@ -40,6 +40,11 @@ func resourceGithubProjectColumn() *schema.Resource { } func resourceGithubProjectColumnCreate(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client options := github.ProjectColumnOptions{ diff --git a/github/resource_github_repository.go b/github/resource_github_repository.go index 75b998565c..91cd737516 100644 --- a/github/resource_github_repository.go +++ b/github/resource_github_repository.go @@ -163,6 +163,11 @@ func resourceGithubRepositoryObject(d *schema.ResourceData) *github.Repository { } func resourceGithubRepositoryCreate(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client if _, ok := d.GetOk("default_branch"); ok { @@ -192,6 +197,11 @@ func resourceGithubRepositoryCreate(d *schema.ResourceData, meta interface{}) er } func resourceGithubRepositoryRead(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client orgName := meta.(*Organization).name repoName := d.Id() @@ -244,6 +254,11 @@ func resourceGithubRepositoryRead(d *schema.ResourceData, meta interface{}) erro } func resourceGithubRepositoryUpdate(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client repoReq := resourceGithubRepositoryObject(d) @@ -279,13 +294,18 @@ func resourceGithubRepositoryUpdate(d *schema.ResourceData, meta interface{}) er } func resourceGithubRepositoryDelete(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client repoName := d.Id() orgName := meta.(*Organization).name ctx := context.WithValue(context.Background(), ctxId, d.Id()) log.Printf("[DEBUG] Deleting repository: %s/%s", orgName, repoName) - _, err := client.Repositories.Delete(ctx, orgName, repoName) + _, err = client.Repositories.Delete(ctx, orgName, repoName) return err } diff --git a/github/resource_github_repository_collaborator.go b/github/resource_github_repository_collaborator.go index 1e0c13011d..8a732be0cb 100644 --- a/github/resource_github_repository_collaborator.go +++ b/github/resource_github_repository_collaborator.go @@ -48,6 +48,11 @@ func resourceGithubRepositoryCollaborator() *schema.Resource { } func resourceGithubRepositoryCollaboratorCreate(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client orgName := meta.(*Organization).name @@ -57,7 +62,7 @@ func resourceGithubRepositoryCollaboratorCreate(d *schema.ResourceData, meta int log.Printf("[DEBUG] Creating repository collaborator: %s (%s/%s)", username, orgName, repoName) - _, err := client.Repositories.AddCollaborator(ctx, + _, err = client.Repositories.AddCollaborator(ctx, orgName, repoName, username, @@ -75,6 +80,11 @@ func resourceGithubRepositoryCollaboratorCreate(d *schema.ResourceData, meta int } func resourceGithubRepositoryCollaboratorRead(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client orgName := meta.(*Organization).name @@ -143,6 +153,11 @@ func resourceGithubRepositoryCollaboratorRead(d *schema.ResourceData, meta inter } func resourceGithubRepositoryCollaboratorDelete(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client orgName := meta.(*Organization).name diff --git a/github/resource_github_repository_deploy_key.go b/github/resource_github_repository_deploy_key.go index 3c362d2a40..8f30f04bb6 100644 --- a/github/resource_github_repository_deploy_key.go +++ b/github/resource_github_repository_deploy_key.go @@ -54,6 +54,11 @@ func resourceGithubRepositoryDeployKey() *schema.Resource { } func resourceGithubRepositoryDeployKeyCreate(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client repoName := d.Get("repository").(string) @@ -82,6 +87,11 @@ func resourceGithubRepositoryDeployKeyCreate(d *schema.ResourceData, meta interf } func resourceGithubRepositoryDeployKeyRead(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client owner := meta.(*Organization).name @@ -126,6 +136,11 @@ func resourceGithubRepositoryDeployKeyRead(d *schema.ResourceData, meta interfac } func resourceGithubRepositoryDeployKeyDelete(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client owner := meta.(*Organization).name diff --git a/github/resource_github_repository_project.go b/github/resource_github_repository_project.go index a9e501c28a..ec6af9801d 100644 --- a/github/resource_github_repository_project.go +++ b/github/resource_github_repository_project.go @@ -57,6 +57,11 @@ func resourceGithubRepositoryProject() *schema.Resource { } func resourceGithubRepositoryProjectCreate(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client orgName := meta.(*Organization).name @@ -82,6 +87,11 @@ func resourceGithubRepositoryProjectCreate(d *schema.ResourceData, meta interfac } func resourceGithubRepositoryProjectRead(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client orgName := meta.(*Organization).name diff --git a/github/resource_github_repository_webhook.go b/github/resource_github_repository_webhook.go index 2f7e54bcb0..d45b9a632c 100644 --- a/github/resource_github_repository_webhook.go +++ b/github/resource_github_repository_webhook.go @@ -92,6 +92,11 @@ func resourceGithubRepositoryWebhookObject(d *schema.ResourceData) *github.Hook } func resourceGithubRepositoryWebhookCreate(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client orgName := meta.(*Organization).name @@ -110,6 +115,11 @@ func resourceGithubRepositoryWebhookCreate(d *schema.ResourceData, meta interfac } func resourceGithubRepositoryWebhookRead(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client orgName := meta.(*Organization).name @@ -148,6 +158,11 @@ func resourceGithubRepositoryWebhookRead(d *schema.ResourceData, meta interface{ } func resourceGithubRepositoryWebhookUpdate(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client orgName := meta.(*Organization).name diff --git a/github/resource_github_team.go b/github/resource_github_team.go index b35d1dafa1..05b26aa4cc 100644 --- a/github/resource_github_team.go +++ b/github/resource_github_team.go @@ -56,6 +56,11 @@ func resourceGithubTeam() *schema.Resource { } func resourceGithubTeamCreate(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client orgName := meta.(*Organization).name diff --git a/github/resource_github_team_repository.go b/github/resource_github_team_repository.go index 9eaac6a9ad..e8c757063c 100644 --- a/github/resource_github_team_repository.go +++ b/github/resource_github_team_repository.go @@ -46,6 +46,11 @@ func resourceGithubTeamRepository() *schema.Resource { } func resourceGithubTeamRepositoryCreate(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client teamIdString := d.Get("team_id").(string) @@ -79,6 +84,11 @@ func resourceGithubTeamRepositoryCreate(d *schema.ResourceData, meta interface{} } func resourceGithubTeamRepositoryRead(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client teamIdString, repoName, err := parseTwoPartID(d.Id()) @@ -130,6 +140,11 @@ func resourceGithubTeamRepositoryRead(d *schema.ResourceData, meta interface{}) } func resourceGithubTeamRepositoryUpdate(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client teamIdString := d.Get("team_id").(string) @@ -163,6 +178,11 @@ func resourceGithubTeamRepositoryUpdate(d *schema.ResourceData, meta interface{} } func resourceGithubTeamRepositoryDelete(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client teamIdString := d.Get("team_id").(string) diff --git a/github/resource_organization_block.go b/github/resource_organization_block.go index c86265a0df..10db28f9af 100644 --- a/github/resource_organization_block.go +++ b/github/resource_organization_block.go @@ -34,13 +34,18 @@ func resourceOrganizationBlock() *schema.Resource { } func resourceOrganizationBlockCreate(d *schema.ResourceData, meta interface{}) error { + err := checkOrganization(meta) + if err != nil { + return err + } + client := meta.(*Organization).client orgName := meta.(*Organization).name ctx := context.Background() username := d.Get("username").(string) log.Printf("[DEBUG] Creating organization block: %s (%s)", username, orgName) - _, err := client.Organizations.BlockUser(ctx, orgName, username) + _, err = client.Organizations.BlockUser(ctx, orgName, username) if err != nil { return err } diff --git a/github/util.go b/github/util.go index d53e7cb1b1..2e991dad47 100644 --- a/github/util.go +++ b/github/util.go @@ -12,6 +12,14 @@ const ( maxPerPage = 100 ) +func checkOrganization(meta interface{}) error { + if meta.(*Organization).name == "" { + return fmt.Errorf("This resource requires GitHub organization to be set on the provider.") + } + + return nil +} + func caseInsensitive() schema.SchemaDiffSuppressFunc { return func(k, old, new string, d *schema.ResourceData) bool { return strings.ToLower(old) == strings.ToLower(new) diff --git a/website/docs/index.html.markdown b/website/docs/index.html.markdown index a59e5770e3..54927997c4 100644 --- a/website/docs/index.html.markdown +++ b/website/docs/index.html.markdown @@ -52,3 +52,5 @@ The following arguments are supported in the `provider` block: There is a number of ways to obtain trusted certificate for free, e.g. from [Let's Encrypt](https://letsencrypt.org/). Such trusted certificate *does not require* this option to be enabled. Defaults to `false`. + +* `individual`: (Optional) Whether to run outside an organization. \ No newline at end of file