Skip to content

Commit

Permalink
Move extsvc config JSON Schemas to separate files (sourcegraph#2178)
Browse files Browse the repository at this point in the history
This helps with sourcegraph#2067 and clarifies the relationship between site config and external service config.

Test plan:

- Verify that equivalent Go `./schema` code is codegenned (vs. before this PR, by looking at the diff).
- For the web app, ensure that in the site admin external service Monaco editors for each kind of service, you get hovers and validation as before.
- For the backend, ensure that server-side validation occurs when you try to save external service JSON in site admin. (This is covered by Go unit tests.)
  • Loading branch information
sqs authored Feb 15, 2019
1 parent aead128 commit 047e49b
Show file tree
Hide file tree
Showing 38 changed files with 1,093 additions and 1,228 deletions.
1 change: 0 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ testdata
doc/
shared/src/types/abort-controller/index.d.ts
client/browser/src/extension/*.json
schema/
cmd/management-console/assets/
**/.cache
shared/dev/**/*.js
Expand Down
5 changes: 0 additions & 5 deletions client/browser/src/globals.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,6 @@ interface Window {
require: any
}

declare module '*.json' {
const value: any
export default value
}

/**
* For Web Worker entrypoints using Webpack's worker-loader.
*
Expand Down
29 changes: 10 additions & 19 deletions cmd/frontend/db/external_services.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,21 @@ type externalServices struct{}
// ExternalServiceKinds contains a map of all supported kinds of
// external services.
var ExternalServiceKinds = map[string]ExternalServiceKind{
"AWSCODECOMMIT": {CodeHost: true, Definition: "AWSCodeCommitConnection"},
"BITBUCKETSERVER": {CodeHost: true, Definition: "BitbucketServerConnection"},
"GITHUB": {CodeHost: true, Definition: "GitHubConnection"},
"GITLAB": {CodeHost: true, Definition: "GitLabConnection"},
"GITOLITE": {CodeHost: true, Definition: "GitoliteConnection"},
"PHABRICATOR": {CodeHost: true, Definition: "PhabricatorConnection"},
"OTHER": {CodeHost: true, Definition: "OtherExternalServiceConnection"},
"AWSCODECOMMIT": {CodeHost: true, JSONSchema: schema.AWSCodeCommitSchemaJSON},
"BITBUCKETSERVER": {CodeHost: true, JSONSchema: schema.BitbucketServerSchemaJSON},
"GITHUB": {CodeHost: true, JSONSchema: schema.GitHubSchemaJSON},
"GITLAB": {CodeHost: true, JSONSchema: schema.GitLabSchemaJSON},
"GITOLITE": {CodeHost: true, JSONSchema: schema.GitoliteSchemaJSON},
"PHABRICATOR": {CodeHost: true, JSONSchema: schema.PhabricatorSchemaJSON},
"OTHER": {CodeHost: true, JSONSchema: schema.OtherExternalServiceSchemaJSON},
}

// ExternalServiceKind describes a kind of external service.
type ExternalServiceKind struct {
// True if the external service can host repositories.
CodeHost bool
// JSON Schema definition name in site.schema.json
Definition string

JSONSchema string // JSON Schema for the external service's configuration
}

// ExternalServicesListOptions contains options for listing external services.
Expand Down Expand Up @@ -76,15 +76,7 @@ func (e *externalServices) validateConfig(kind, config string) error {
// serveExternalServiceConfigs to handle this case.

sl := gojsonschema.NewSchemaLoader()
err := sl.AddSchemas(gojsonschema.NewStringLoader(schema.SiteSchemaJSON))
if err != nil {
return errors.Wrap(err, "failed to add site schema to schema loader")
}

sc, err := sl.Compile(gojsonschema.NewStringLoader(
fmt.Sprintf(`{"$ref": "site.schema.json#/definitions/%s"}`, ext.Definition),
))

sc, err := sl.Compile(gojsonschema.NewStringLoader(ext.JSONSchema))
if err != nil {
return errors.Wrapf(err, "failed to compile schema for external service of kind %q", kind)
}
Expand All @@ -94,7 +86,6 @@ func (e *externalServices) validateConfig(kind, config string) error {
return errors.Wrapf(err, "failed to normalize JSON")
}

sc.SetRootSchemaName(ext.Definition)
res, err := sc.Validate(gojsonschema.NewBytesLoader(normalized))
if err != nil {
return errors.Wrap(err, "failed to validate config against schema")
Expand Down
51 changes: 51 additions & 0 deletions schema/aws_codecommit.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "aws_codecommit.schema.json#",
"title": "AWSCodeCommitConnection",
"description": "Configuration for a connection to AWS CodeCommit.",
"type": "object",
"additionalProperties": false,
"required": ["region", "accessKeyID", "secretAccessKey"],
"properties": {
"region": {
"description": "The AWS region in which to access AWS CodeCommit. See the list of supported regions at https://docs.aws.amazon.com/codecommit/latest/userguide/regions.html#regions-git.",
"type": "string",
"default": "us-east-1",
"pattern": "^[a-z\\d-]+$",
"enum": [
"ap-northeast-1",
"ap-northeast-2",
"ap-south-1",
"ap-southeast-1",
"ap-southeast-2",
"ca-central-1",
"eu-central-1",
"eu-west-1",
"eu-west-2",
"eu-west-3",
"sa-east-1",
"us-east-1",
"us-east-2",
"us-west-1",
"us-west-2"
]
},
"accessKeyID": {
"description": "The AWS access key ID to use when listing and updating repositories from AWS CodeCommit. Must have the AWSCodeCommitReadOnly IAM policy.",
"type": "string"
},
"secretAccessKey": {
"description": "The AWS secret access key (that corresponds to the AWS access key ID set in `accessKeyID`).",
"type": "string"
},
"repositoryPathPattern": {
"description": "The pattern used to generate a the corresponding Sourcegraph repository name for an AWS CodeCommit repository. In the pattern, the variable \"{name}\" is replaced with the repository's name.\n\nFor example, if your Sourcegraph instance is at https://src.example.com, then a repositoryPathPattern of \"awsrepos/{name}\" would mean that a AWS CodeCommit repository named \"myrepo\" is available on Sourcegraph at https://src.example.com/awsrepos/myrepo.\n\nIt is important that the Sourcegraph repository name generated with this pattern be unique to this code host. If different code hosts generate repository names that collide, Sourcegraph's behavior is undefined.",
"type": "string",
"default": "{name}"
},
"initialRepositoryEnablement": {
"description": "Defines whether repositories from AWS CodeCommit should be enabled and cloned when they are first seen by Sourcegraph. If false, the site admin must explicitly enable AWS CodeCommit repositories (in the site admin area) to clone them and make them searchable on Sourcegraph. If true, they will be enabled and cloned immediately (subject to rate limiting by AWS); site admins can still disable them explicitly, and they'll remain disabled.",
"type": "boolean"
}
}
}
57 changes: 57 additions & 0 deletions schema/aws_codecommit_stringdata.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

74 changes: 74 additions & 0 deletions schema/bitbucket_server.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "bitbucket_server.schema.json#",
"title": "BitbucketServerConnection",
"description": "Configuration for a connection to Bitbucket Server.",
"type": "object",
"additionalProperties": false,
"required": ["url"],
"oneOf": [
{
"required": ["token"],
"properties": {
"username": { "type": "null" },
"password": { "type": "null" }
}
},
{
"required": ["username", "password"],
"properties": {
"token": { "type": "null" }
}
}
],
"properties": {
"url": {
"description": "URL of a Bitbucket Server instance, such as https://bitbucket.example.com.",
"type": "string",
"pattern": "^https?://",
"not": {
"type": "string",
"pattern": "example\\.com"
},
"format": "uri",
"examples": ["https://bitbucket.example.com"]
},
"token": {
"description": "A Bitbucket Server personal access token with Read scope. Create one at https://[your-bitbucket-hostname]/plugins/servlet/access-tokens/add.\n\nFor Bitbucket Server instances that don't support personal access tokens (Bitbucket Server version 5.4 and older), specify user-password credentials in the \"username\" and \"password\" fields.",
"type": "string",
"minLength": 1
},
"username": {
"description": "The username to use when authenticating to the Bitbucket Server instance. Also set the corresponding \"password\" field.\n\nFor Bitbucket Server instances that support personal access tokens (Bitbucket Server version 5.5 and newer), it is recommended to provide a token instead (in the \"token\" field).",
"type": "string"
},
"password": {
"description": "The password to use when authenticating to the Bitbucket Server instance. Also set the corresponding \"username\" field.\n\nFor Bitbucket Server instances that support personal access tokens (Bitbucket Server version 5.5 and newer), it is recommended to provide a token instead (in the \"token\" field).",
"type": "string"
},
"gitURLType": {
"description": "The type of Git URLs to use for cloning and fetching Git repositories on this Bitbucket Server instance.\n\nIf \"http\", Sourcegraph will access Bitbucket Server repositories using Git URLs of the form http(s)://bitbucket.example.com/scm/myproject/myrepo.git (using https: if the Bitbucket Server instance uses HTTPS).\n\nIf \"ssh\", Sourcegraph will access Bitbucket Server repositories using Git URLs of the form ssh://[email protected]/myproject/myrepo.git. See the documentation for how to provide SSH private keys and known_hosts: https://docs.sourcegraph.com/admin/repo/auth#repositories-that-need-http-s-or-ssh-authentication.",
"type": "string",
"enum": ["http", "ssh"],
"default": "http"
},
"certificate": {
"description": "TLS certificate of a Bitbucket Server instance. To get the certificate run `openssl s_client -connect HOST:443 -showcerts < /dev/null 2> /dev/null | openssl x509 -outform PEM`",
"type": "string",
"pattern": "^-----BEGIN CERTIFICATE-----\n"
},
"repositoryPathPattern": {
"description": "The pattern used to generate the corresponding Sourcegraph repository name for a Bitbucket Server repository.\n\n - \"{host}\" is replaced with the Bitbucket Server URL's host (such as bitbucket.example.com)\n - \"{projectKey}\" is replaced with the Bitbucket repository's parent project key (such as \"PRJ\")\n - \"{repositorySlug}\" is replaced with the Bitbucket repository's slug key (such as \"my-repo\").\n\nFor example, if your Bitbucket Server is https://bitbucket.example.com and your Sourcegraph is https://src.example.com, then a repositoryPathPattern of \"{host}/{projectKey}/{repositorySlug}\" would mean that a Bitbucket Server repository at https://bitbucket.example.com/projects/PRJ/repos/my-repo is available on Sourcegraph at https://src.example.com/bitbucket.example.com/PRJ/my-repo.\n\nIt is important that the Sourcegraph repository name generated with this pattern be unique to this code host. If different code hosts generate repository names that collide, Sourcegraph's behavior is undefined.",
"type": "string",
"default": "{host}/{projectKey}/{repositorySlug}"
},
"excludePersonalRepositories": {
"description": "Whether or not personal repositories should be excluded or not. When true, Sourcegraph will ignore personal repositories it may have access to. See https://docs.sourcegraph.com/integration/bitbucket_server#excluding-personal-repositories for more information. Default: false.",
"type": "boolean"
},
"initialRepositoryEnablement": {
"description": "Defines whether repositories from this Bitbucket Server instance should be enabled and cloned when they are first seen by Sourcegraph. If false, the site admin must explicitly enable Bitbucket Server repositories (in the site admin area) to clone them and make them searchable on Sourcegraph. If true, they will be enabled and cloned immediately (subject to rate limiting by Bitbucket Server); site admins can still disable them explicitly, and they'll remain disabled.",
"type": "boolean"
}
}
}
80 changes: 80 additions & 0 deletions schema/bitbucket_server_stringdata.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 047e49b

Please sign in to comment.