[go: nahoru, domu]

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

Hold back Functions refactor until after I/O #3379

Merged
merged 1 commit into from
May 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,7 @@ var api = {
"FIREBASE_FUNCTIONS_V2_URL",
"https://cloudfunctions.googleapis.com"
),
runOrigin: utils.envOverride("CLOUD_RUN_URL", "https://run.googleapis.com"),
functionsUploadRegion: utils.envOverride("FIREBASE_FUNCTIONS_UPLOAD_REGION", "us-central1"),
functionsDefaultRegion: utils.envOverride("FIREBASE_FUNCTIONS_DEFAULT_REGION", "us-central1"),
cloudschedulerOrigin: utils.envOverride(
"FIREBASE_CLOUDSCHEDULER_URL",
"https://cloudscheduler.googleapis.com"
Expand Down
55 changes: 28 additions & 27 deletions src/commands/functions-delete.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { Command } from "../command";
import * as clc from "cli-color";
import * as cloudfunctions from "../gcp/cloudfunctions";
import * as functionsConfig from "../functionsConfig";
import { deleteFunctions } from "../functionsDelete";
import * as getProjectId from "../getProjectId";
import * as helper from "../functionsDeployHelper";
import { promptOnce } from "../prompt";
import * as helper from "../deploy/functions/functionsDeployHelper";
import { requirePermissions } from "../requirePermissions";
import * as utils from "../utils";
import * as args from "../deploy/functions/args";
import * as backend from "../deploy/functions/backend";

export default new Command("functions:delete [filters...]")
.description("delete one or more Cloud Functions by name or group name.")
Expand All @@ -19,48 +18,50 @@ export default new Command("functions:delete [filters...]")
)
.option("-f, --force", "No confirmation. Otherwise, a confirmation prompt will appear.")
.before(requirePermissions, ["cloudfunctions.functions.list", "cloudfunctions.functions.delete"])
.action(async (filters: string[], options: { force: boolean; region?: string }) => {
.action(async (filters, options) => {
if (!filters.length) {
return utils.reject("Must supply at least function or group name.");
}

const context = {
projectId: getProjectId(options),
} as args.Context;
const projectId = getProjectId(options);

// Dot notation can be used to indicate function inside of a group
const filterChunks = filters.map((filter: string) => {
return filter.split(".");
});
const [config, existingBackend] = await Promise.all([
functionsConfig.getFirebaseConfig(options),
backend.existingBackend(context),
]);
await backend.checkAvailability(context, /* want=*/ backend.empty());
const config = await functionsConfig.getFirebaseConfig(options);
const appEngineLocation = functionsConfig.getAppEngineLocation(config);

const functionsToDelete = existingBackend.cloudFunctions.filter((fn) => {
const regionMatches = options.region ? fn.region === options.region : true;
const nameMatches = helper.functionMatchesAnyGroup(fn, filterChunks);
const res = await cloudfunctions.listAllFunctions(projectId);
if (res.unreachable) {
utils.logLabeledWarning(
"functions",
`Unable to reach the following Cloud Functions regions:\n${res.unreachable.join(
"\n"
)}\nCloud Functions in these regions will not be deleted.`
);
}
const functionsToDelete = res.functions.filter((fn) => {
const regionMatches = options.region ? helper.getRegion(fn.name) === options.region : true;
const nameMatches = helper.functionMatchesAnyGroup(fn.name, filterChunks);
return regionMatches && nameMatches;
});
if (functionsToDelete.length === 0) {
return utils.reject(
`The specified filters do not match any existing functions in project ${clc.bold(
context.projectId
projectId
)}.`,
{ exit: 1 }
);
}

const schedulesToDelete = existingBackend.schedules.filter((schedule) => {
functionsToDelete.some(backend.sameFunctionName(schedule.targetService));
});
const topicsToDelete = existingBackend.topics.filter((topic) => {
functionsToDelete.some(backend.sameFunctionName(topic.targetService));
});
const scheduledFnNamesToDelete = functionsToDelete
.filter((fn) => {
return fn.labels?.["deployment-scheduled"] === "true";
})
.map((fn) => fn.name);
const fnNamesToDelete = functionsToDelete.map((fn) => fn.name);

const deleteList = functionsToDelete
const deleteList = fnNamesToDelete
.map((func) => {
return "\t" + helper.getFunctionLabel(func);
})
Expand All @@ -81,9 +82,9 @@ export default new Command("functions:delete [filters...]")
return utils.reject("Command aborted.", { exit: 1 });
}
return await deleteFunctions(
functionsToDelete,
schedulesToDelete,
topicsToDelete,
fnNamesToDelete,
scheduledFnNamesToDelete,
projectId,
appEngineLocation
);
});
31 changes: 20 additions & 11 deletions src/deploy/functions/args.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { ReadStream } from "fs";

import * as backend from "./backend";
import * as gcfV2 from "../../gcp/cloudfunctionsv2";

// These types should proably be in a root deploy.ts, but we can only boil the ocean one bit at a time.

import { ReadStream } from "fs";
import * as gcf from "../../gcp/cloudfunctions";
import * as deploymentPlanner from "./deploymentPlanner";

// Payload holds the output types of what we're building.
export interface Payload {
functions?: {
backend: backend.Backend;
byRegion: deploymentPlanner.RegionMap;
triggers: deploymentPlanner.CloudFunctionTrigger[];
};
}

Expand All @@ -26,8 +26,8 @@ export interface Options {
config: {
// Note: it might be worth defining overloads for config values we use in
// deploy/functions.
get(key: string, defaultValue?: unknown): unknown;
set(key: string, value: unknown): void;
get(key: string, defaultValue?: any): any;
set(key: string, value: any): void;
has(key: string): boolean;
path(pathName: string): string;

Expand All @@ -44,6 +44,12 @@ export interface Options {
force: boolean;
}

export interface FunctionsSource {
file: string;
stream: ReadStream;
size: number;
}

// Context holds cached values of what we've looked up in handling this request.
// For non-trivial values, use helper functions that cache automatically and/or hide implementation
// details.
Expand All @@ -52,14 +58,17 @@ export interface Context {
filters: string[][];

// Filled in the "prepare" phase.
functionsSource?: string;
runtimeChoice?: backend.Runtime;
functionsSource?: FunctionsSource;
// TODO: replace with backend.Runtime once it is committed.
runtimeChoice?: gcf.Runtime;
runtimeConfigEnabled?: boolean;
firebaseConfig?: FirebaseConfig;

// Filled in the "deploy" phase.
uploadUrl?: string;
storageSource?: gcfV2.StorageSource;

// TOOD: move to caching function w/ helper
existingFunctions?: gcf.CloudFunction[];
}

export interface FirebaseConfig {
Expand Down
Loading