chore(community-templates): remove github file restriction

pull/19425/head
Bucky Schwarz 2020-08-24 11:04:54 -07:00 committed by Bucky Schwarz
parent eb2dd5af7b
commit 70b7287c9e
9 changed files with 114 additions and 68 deletions

View File

@ -32,19 +32,7 @@ describe('Community Templates', () => {
cy.getByTestID('lookup-template-button').click()
cy.getByTestID('notification-error').should('be.visible')
//lookup template errors on bad url
cy.getByTestID('lookup-template-input').type('www.badURL.com')
cy.getByTestID('lookup-template-button').click()
cy.getByTestID('notification-error').should('be.visible')
//lookup template errors on bad file type
cy.getByTestID('lookup-template-input').clear()
cy.getByTestID('lookup-template-input').type('variables.html')
cy.getByTestID('lookup-template-button').click()
cy.getByTestID('notification-error').should('be.visible')
//lookup template errors on github folder
cy.getByTestID('lookup-template-input').clear()
cy.getByTestID('lookup-template-input').type(
'https://github.com/influxdata/community-templates/tree/master/kafka'
)

View File

@ -13,8 +13,8 @@ export const ADD_TEMPLATE_SUMMARY = 'ADD_TEMPLATE_SUMMARY'
export const GET_TEMPLATE_SUMMARIES_FOR_ORG = 'GET_TEMPLATE_SUMMARIES_FOR_ORG'
export const POPULATE_TEMPLATE_SUMMARIES = 'POPULATE_TEMPLATE_SUMMARIES'
export const REMOVE_TEMPLATE_SUMMARY = 'REMOVE_TEMPLATE_SUMMARY'
export const SET_COMMUNITY_TEMPLATE_TO_INSTALL =
'SET_COMMUNITY_TEMPLATE_TO_INSTALL'
export const SET_STAGED_TEMPLATE = 'SET_STAGED_TEMPLATE'
export const SET_STAGED_TEMPLATE_URL = 'SET_STAGED_TEMPLATE_URL'
export const SET_EXPORT_TEMPLATE = 'SET_EXPORT_TEMPLATE'
export const SET_TEMPLATE_SUMMARY = 'SET_TEMPLATE_SUMMARY'
export const SET_TEMPLATES_STATUS = 'SET_TEMPLATES_STATUS'
@ -32,6 +32,7 @@ export type Action =
| ReturnType<typeof setTemplatesStatus>
| ReturnType<typeof setTemplateSummary>
| ReturnType<typeof setStagedCommunityTemplate>
| ReturnType<typeof setStagedTemplateUrl>
| ReturnType<typeof toggleTemplateResourceInstall>
| ReturnType<typeof setStacks>
| ReturnType<typeof removeStack>
@ -93,10 +94,16 @@ export const setTemplateSummary = (
export const setStagedCommunityTemplate = (template: CommunityTemplate) =>
({
type: SET_COMMUNITY_TEMPLATE_TO_INSTALL,
type: SET_STAGED_TEMPLATE,
template,
} as const)
export const setStagedTemplateUrl = (templateUrl: string) =>
({
type: SET_STAGED_TEMPLATE_URL,
templateUrl,
} as const)
export const toggleTemplateResourceInstall = (
resourceType: string,
templateMetaName: string,

View File

@ -18,7 +18,7 @@ import {ComponentStatus} from '@influxdata/clockface'
// Utils
import {getByID} from 'src/resources/selectors'
import {getGithubUrlFromTemplateDetails} from 'src/templates/utils'
import {getTemplateNameFromUrl} from 'src/templates/utils'
import {reportError} from 'src/shared/utils/errors'
import {
@ -41,11 +41,9 @@ interface State {
type ReduxProps = ConnectedProps<typeof connector>
type RouterProps = RouteComponentProps<{
directory: string
orgID: string
templateName: string
templateExtension: string
}>
type Props = ReduxProps & RouterProps
class UnconnectedTemplateImportOverlay extends PureComponent<Props> {
@ -54,12 +52,13 @@ class UnconnectedTemplateImportOverlay extends PureComponent<Props> {
}
public componentDidMount() {
const {directory, org, templateExtension, templateName} = this.props
if (!this.props.stagedTemplateUrl) {
this.onDismiss()
return
}
this.reviewTemplateResources(
org.id,
directory,
templateName,
templateExtension
this.props.org.id,
this.props.stagedTemplateUrl
)
}
@ -70,26 +69,18 @@ class UnconnectedTemplateImportOverlay extends PureComponent<Props> {
onInstall={this.handleInstallTemplate}
resourceCount={this.props.resourceCount}
status={this.state.status}
templateName={this.props.templateName}
templateName={getTemplateNameFromUrl(this.props.stagedTemplateUrl).name}
updateStatus={this.updateOverlayStatus}
/>
)
}
private reviewTemplateResources = async (
orgID,
directory,
templateName,
templateExtension
orgID: string,
templateUrl: string
) => {
const yamlLocation = getGithubUrlFromTemplateDetails(
directory,
templateName,
templateExtension
)
try {
const summary = await reviewTemplate(orgID, yamlLocation)
const summary = await reviewTemplate(orgID, templateUrl)
this.props.setStagedCommunityTemplate(summary)
return summary
@ -102,28 +93,18 @@ class UnconnectedTemplateImportOverlay extends PureComponent<Props> {
}
private onDismiss = () => {
const {history} = this.props
history.goBack()
this.props.history.push(`/orgs/${this.props.org.id}/settings/templates`)
}
private updateOverlayStatus = (status: ComponentStatus) =>
this.setState(() => ({status}))
private handleInstallTemplate = async () => {
const {directory, org, templateExtension, templateName} = this.props
const yamlLocation = getGithubUrlFromTemplateDetails(
directory,
templateName,
templateExtension
)
let summary
try {
summary = await installTemplate(
org.id,
yamlLocation,
this.props.org.id,
this.props.stagedTemplateUrl,
this.props.resourcesToSkip
)
} catch (err) {
@ -132,16 +113,19 @@ class UnconnectedTemplateImportOverlay extends PureComponent<Props> {
}
try {
await updateStackName(summary.stackID, templateName)
const templateDetails = getTemplateNameFromUrl(
this.props.stagedTemplateUrl
)
await updateStackName(summary.stackID, templateDetails.name)
event('template_install', {templateName: templateName})
event('template_install', {templateName: templateDetails.name})
this.props.notify(communityTemplateInstallSucceeded(templateName))
this.props.notify(communityTemplateInstallSucceeded(templateDetails.name))
} catch (err) {
this.props.notify(communityTemplateRenameFailed())
reportError(err, {name: 'The community template rename failed'})
} finally {
this.props.fetchAndSetStacks(org.id)
this.props.fetchAndSetStacks(this.props.org.id)
this.onDismiss()
}
}
@ -156,15 +140,13 @@ const mstp = (state: AppState, props: RouterProps) => {
return {
org,
directory: props.match.params.directory,
templateName: props.match.params.templateName,
templateExtension: props.match.params.templateExtension,
flags: state.flags.original,
resourceCount: getTotalResourceCount(
state.resources.templates.stagedCommunityTemplate.summary
),
resourcesToSkip:
state.resources.templates.stagedCommunityTemplate.resourcesToSkip,
stagedTemplateUrl: state.resources.templates.stagedTemplateUrl,
}
}

View File

@ -35,15 +35,18 @@ import {communityTemplatesImportPath} from 'src/templates/containers/TemplatesIn
import GetResources from 'src/resources/components/GetResources'
import {getOrg} from 'src/organizations/selectors'
import {setStagedTemplateUrl} from 'src/templates/actions/creators'
// Utils
import {pageTitleSuffixer} from 'src/shared/utils/pageTitles'
import {
getGithubUrlFromTemplateDetails,
getTemplateDetails,
getTemplateNameFromUrl,
} from 'src/templates/utils'
import {reportError} from 'src/shared/utils/errors'
import {communityTemplateUnsupportedFormatError} from 'src/shared/copy/notifications'
// Types
import {AppState, ResourceType} from 'src/types'
@ -168,7 +171,7 @@ class UnconnectedTemplatesIndex extends Component<Props> {
</Page>
<Switch>
<Route
path={`${templatesPath}/import/:directory/:templateName/:templateExtension`}
path={`${templatesPath}/import`}
component={CommunityTemplateImportOverlay}
/>
</Switch>
@ -183,12 +186,14 @@ class UnconnectedTemplatesIndex extends Component<Props> {
}
try {
const {directory, templateExtension, templateName} = getTemplateDetails(
this.state.templateUrl
)
event('template_click_lookup', {templateName: templateName})
this.props.setStagedTemplateUrl(this.state.templateUrl)
event('template_click_lookup', {
templateName: getTemplateNameFromUrl(this.state.templateUrl).name,
})
this.props.history.push(
`/orgs/${this.props.org.id}/settings/templates/import/${directory}/${templateName}/${templateExtension}`
`/orgs/${this.props.org.id}/settings/templates/import`
)
} catch (err) {
this.props.notify(communityTemplateUnsupportedFormatError())
@ -217,6 +222,7 @@ const mstp = (state: AppState) => {
const mdtp = {
notify,
setStagedTemplateUrl,
}
const connector = connect(mstp, mdtp)

View File

@ -46,6 +46,7 @@ const stagedCommunityTemplate: CommunityTemplate = {}
const initialState = () => ({
stagedCommunityTemplate,
stagedTemplateUrl: '',
status,
byID: {
['1']: templateSummary,
@ -99,6 +100,7 @@ describe('templates reducer', () => {
allIDs,
exportTemplate,
stagedCommunityTemplate,
stagedTemplateUrl: '',
stacks: [],
}
const actual = reducer(state, removeTemplateSummary(state.allIDs[1]))

View File

@ -4,12 +4,13 @@ import {
ADD_TEMPLATE_SUMMARY,
POPULATE_TEMPLATE_SUMMARIES,
REMOVE_TEMPLATE_SUMMARY,
SET_COMMUNITY_TEMPLATE_TO_INSTALL,
SET_EXPORT_TEMPLATE,
SET_TEMPLATE_SUMMARY,
SET_TEMPLATES_STATUS,
TOGGLE_TEMPLATE_RESOURCE_INSTALL,
SET_STACKS,
SET_STAGED_TEMPLATE,
SET_STAGED_TEMPLATE_URL,
SET_TEMPLATES_STATUS,
SET_TEMPLATE_SUMMARY,
TOGGLE_TEMPLATE_RESOURCE_INSTALL,
} from 'src/templates/actions/creators'
import {
CommunityTemplate,
@ -37,6 +38,7 @@ const defaultCommunityTemplate = (): CommunityTemplate => {
export const defaultState = (): TemplatesState => ({
stagedCommunityTemplate: defaultCommunityTemplate(),
stagedTemplateUrl: '',
status: RemoteDataState.NotStarted,
byID: {},
allIDs: [],
@ -75,7 +77,14 @@ export const templatesReducer = (
return
}
case SET_COMMUNITY_TEMPLATE_TO_INSTALL: {
case SET_STAGED_TEMPLATE_URL: {
const {templateUrl} = action
draftState.stagedTemplateUrl = templateUrl
return
}
case SET_STAGED_TEMPLATE: {
const {template} = action
const stagedCommunityTemplate = {

View File

@ -1,4 +1,5 @@
import {
getTemplateNameFromUrl,
findIncludedsFromRelationships,
findIncludedFromRelationship,
findIncludedVariables,
@ -46,3 +47,45 @@ describe('Templates utils', () => {
})
})
})
describe('the Community Template url utilities', () => {
it('returns the template name and extension from an arbitrary url', () => {
const {name, extension} = getTemplateNameFromUrl(
'https://github.com/influxdata/influxdb/blob/master/pkger/testdata/dashboard_params.yml'
)
expect(name).toBe('dashboard_params')
expect(extension).toBe('yml')
})
it('returns the template name and extension from the official community templates github repo', () => {
const {name, extension} = getTemplateNameFromUrl(
'https://github.com/influxdata/community-templates/blob/master/csgo/csgo.yml'
)
expect(name).toBe('csgo')
expect(extension).toBe('yml')
})
it('returns the template name and extension from the official community templates github repo when the extension is not yml', () => {
const {name, extension} = getTemplateNameFromUrl(
'https://github.com/influxdata/community-templates/blob/master/csgo/csgo.json'
)
expect(name).toBe('csgo')
expect(extension).toBe('json')
})
it('returns the template name and extension from arbitrary urls', () => {
const {name, extension} = getTemplateNameFromUrl(
'https://www.example.com/csgo/csgo.json'
)
expect(name).toBe('csgo')
expect(extension).toBe('json')
})
it('handles non secure arbitrary urls', () => {
const {name, extension} = getTemplateNameFromUrl(
'http://www.example.com/blog/cats/catstuff/memes/csgo/downsampling.yml'
)
expect(name).toBe('downsampling')
expect(extension).toBe('yml')
})
})

View File

@ -101,6 +101,14 @@ const getTemplateDetailsFromFileSource = (_source: string): TemplateDetails => {
}
}
export const getTemplateNameFromUrl = (
url: string
): {name: string; extension: string} => {
const fullName = url.split('/').pop()
const [name, extension] = fullName.split('.')
return {name, extension}
}
export const getTemplateDetails = (source: string): TemplateDetails => {
if (source.includes('https')) {
return getTemplateDetailsFromGithubSource(source)

View File

@ -36,6 +36,7 @@ export type CommunityTemplate = any
export interface TemplatesState extends NormalizedState<TemplateSummary> {
exportTemplate: {status: RemoteDataState; item: DocumentCreate}
stagedCommunityTemplate: CommunityTemplate
stagedTemplateUrl: string
stacks: InstalledStack[]
}