// DeleteDashboard checks to see if the authorizer on context has write access to the dashboard provided.
506910
func (s *DashboardService) DeleteDashboard(ctx context.Context, id influxdb.ID) error {
	b, err := s.s.FindDashboardByID(ctx, id)
	if err != nil {
		return err
	}

	if err := authorizeWriteDashboard(ctx, b.OrganizationID, id); err != nil {
		return err
	}

	return s.s.DeleteDashboard(ctx, id)
}
154529
func (s *DashboardService) UpdateDashboard(ctx context.Context, id platform.ID, upd platform.DashboardUpdate) (*platform.Dashboard, error) {
	//op := s.OpPrefix + platform.OpUpdateDashboard
	u, err := newURL(s.Addr, dashboardIDPath(id))
	if err != nil {
		return nil, err
	}

	b, err := json.Marshal(upd)
	if err != nil {
		return nil, err
	}

	req, err := http.NewRequest("PATCH", u.String(), bytes.NewReader(b))
	if err != nil {
		return nil, err
	}

	req.Header.Set("Content-Type", "application/json")
	SetToken(s.Token, req)

	hc := newClient(u.Scheme, s.InsecureSkipVerify)

	resp, err := hc.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if err := CheckError(resp); err != nil {
		return nil, err
	}

	var d platform.Dashboard
	if err := json.NewDecoder(resp.Body).Decode(&d); err != nil {
		return nil, err
	}
	if len(d.Cells) == 0 {
		d.Cells = nil
	}

	return &d, nil
}
404556
func (s *Service) ReplaceDashboardCell(w http.ResponseWriter, r *http.Request) {
	id, err := paramID("id", r)
	if err != nil {
		Error(w, http.StatusUnprocessableEntity, err.Error(), s.Logger)
		return
	}

	ctx := r.Context()
	dash, err := s.Store.Dashboards(ctx).Get(ctx, chronograf.DashboardID(id))
	if err != nil {
		notFound(w, id, s.Logger)
		return
	}

	cid := httprouter.ParamsFromContext(ctx).ByName("cid")
	cellid := -1
	for i, cell := range dash.Cells {
		if cell.ID == cid {
			cellid = i
			break
		}
	}
	if cellid == -1 {
		notFound(w, cid, s.Logger)
		return
	}

	var cell chronograf.DashboardCell
	if err := json.NewDecoder(r.Body).Decode(&cell); err != nil {
		invalidJSON(w, s.Logger)
		return
	}

	for i, a := range cell.Axes {
		if len(a.Bounds) == 0 {
			a.Bounds = []string{"", ""}
			cell.Axes[i] = a
		}
	}

	if err := ValidDashboardCellRequest(&cell); err != nil {
		invalidData(w, err, s.Logger)
		return
	}
	cell.ID = cid

	dash.Cells[cellid] = cell
	if err := s.Store.Dashboards(ctx).Update(ctx, dash); err != nil {
		msg := fmt.Sprintf("Error updating cell %s in dashboard %d: %v", cid, id, err)
		Error(w, http.StatusInternalServerError, msg, s.Logger)
		return
	}

	res := newCellResponse(dash.ID, cell)
	encodeJSON(w, http.StatusOK, res, s.Logger)
}
724395
func deployDashboard(client *sshClient, network string, conf *config, config *dashboardInfos, nocache bool) ([]byte, error) {
	// Generate the content to upload to the server
	workdir := fmt.Sprintf("%d", rand.Int63())
	files := make(map[string][]byte)

	dockerfile := new(bytes.Buffer)
	template.Must(template.New("").Parse(dashboardDockerfile)).Execute(dockerfile, map[string]interface{}{
		"Network": network,
	})
	files[filepath.Join(workdir, "Dockerfile")] = dockerfile.Bytes()

	composefile := new(bytes.Buffer)
	template.Must(template.New("").Parse(dashboardComposefile)).Execute(composefile, map[string]interface{}{
		"Network":      network,
		"Port":         config.port,
		"VHost":        config.host,
		"EthstatsPage": config.ethstats,
		"ExplorerPage": config.explorer,
		"WalletPage":   config.wallet,
		"FaucetPage":   config.faucet,
	})
	files[filepath.Join(workdir, "docker-compose.yaml")] = composefile.Bytes()

	statsLogin := fmt.Sprintf("yournode:%s", conf.ethstats)
	if !config.trusted {
		statsLogin = ""
	}
	indexfile := new(bytes.Buffer)
	bootCpp := make([]string, len(conf.bootnodes))
	for i, boot := range conf.bootnodes {
		bootCpp[i] = "required:" + strings.TrimPrefix(boot, "enode://")
	}
	bootHarmony := make([]string, len(conf.bootnodes))
	for i, boot := range conf.bootnodes {
		bootHarmony[i] = fmt.Sprintf("-Dpeer.active.%d.url=%s", i, boot)
	}
	bootPython := make([]string, len(conf.bootnodes))
	for i, boot := range conf.bootnodes {
		bootPython[i] = "'" + boot + "'"
	}
	template.Must(template.New("").Parse(dashboardContent)).Execute(indexfile, map[string]interface{}{
		"Network":           network,
		"NetworkID":         conf.Genesis.Config.ChainID,
		"NetworkTitle":      strings.Title(network),
		"EthstatsPage":      config.ethstats,
		"ExplorerPage":      config.explorer,
		"WalletPage":        config.wallet,
		"FaucetPage":        config.faucet,
		"GethGenesis":       network + ".json",
		"Bootnodes":         conf.bootnodes,
		"BootnodesFlat":     strings.Join(conf.bootnodes, ","),
		"Ethstats":          statsLogin,
		"Ethash":            conf.Genesis.Config.Ethash != nil,
		"CppGenesis":        network + "-cpp.json",
		"CppBootnodes":      strings.Join(bootCpp, " "),
		"HarmonyGenesis":    network + "-harmony.json",
		"HarmonyBootnodes":  strings.Join(bootHarmony, " "),
		"ParityGenesis":     network + "-parity.json",
		"PythonGenesis":     network + "-python.json",
		"PythonBootnodes":   strings.Join(bootPython, ","),
		"Homestead":         conf.Genesis.Config.HomesteadBlock,
		"Tangerine":         conf.Genesis.Config.EIP150Block,
		"Spurious":          conf.Genesis.Config.EIP155Block,
		"Byzantium":         conf.Genesis.Config.ByzantiumBlock,
		"Constantinople":    conf.Genesis.Config.ConstantinopleBlock,
		"ConstantinopleFix": conf.Genesis.Config.PetersburgBlock,
	})
	files[filepath.Join(workdir, "index.html")] = indexfile.Bytes()

	// Marshal the genesis spec files for go-ethereum and all the other clients
	genesis, _ := conf.Genesis.MarshalJSON()
	files[filepath.Join(workdir, network+".json")] = genesis

	if conf.Genesis.Config.Ethash != nil {
		cppSpec, err := newAlethGenesisSpec(network, conf.Genesis)
		if err != nil {
			return nil, err
		}
		cppSpecJSON, _ := json.Marshal(cppSpec)
		files[filepath.Join(workdir, network+"-cpp.json")] = cppSpecJSON

		harmonySpecJSON, _ := conf.Genesis.MarshalJSON()
		files[filepath.Join(workdir, network+"-harmony.json")] = harmonySpecJSON

		paritySpec, err := newParityChainSpec(network, conf.Genesis, conf.bootnodes)
		if err != nil {
			return nil, err
		}
		paritySpecJSON, _ := json.Marshal(paritySpec)
		files[filepath.Join(workdir, network+"-parity.json")] = paritySpecJSON

		pyethSpec, err := newPyEthereumGenesisSpec(network, conf.Genesis)
		if err != nil {
			return nil, err
		}
		pyethSpecJSON, _ := json.Marshal(pyethSpec)
		files[filepath.Join(workdir, network+"-python.json")] = pyethSpecJSON
	} else {
		for _, client := range []string{"cpp", "harmony", "parity", "python"} {
			files[filepath.Join(workdir, network+"-"+client+".json")] = []byte{}
		}
	}
	files[filepath.Join(workdir, "puppeth.png")] = dashboardMascot

	// Upload the deployment files to the remote server (and clean up afterwards)
	if out, err := client.Upload(files); err != nil {
		return out, err
	}
	defer client.Run("rm -rf " + workdir)

	// Build and deploy the dashboard service
	if nocache {
		return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s build --pull --no-cache && docker-compose -p %s up -d --force-recreate --timeout 60", workdir, network, network))
	}
	return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s up -d --build --force-recreate --timeout 60", workdir, network))
}
517959
func (s *Service) DeleteDashboard(ctx context.Context, id platform.ID) error {
	op := OpPrefix + platform.OpDeleteDashboard
	if _, err := s.FindDashboardByID(ctx, id); err != nil {
		return &platform.Error{
			Err: err,
			Op:  op,
		}
	}
	s.dashboardKV.Delete(id.String())
	err := s.deleteLabel(ctx, platform.LabelFilter{ResourceID: id})
	if err != nil {
		return &platform.Error{
			Err: err,
			Op:  op,
		}
	}
	return nil
}
1008168
func (s *Service) RemoveDashboard(w http.ResponseWriter, r *http.Request) {
	id, err := paramID("id", r)
	if err != nil {
		Error(w, http.StatusUnprocessableEntity, err.Error(), s.Logger)
		return
	}

	ctx := r.Context()
	e, err := s.Store.Dashboards(ctx).Get(ctx, chronograf.DashboardID(id))
	if err != nil {
		notFound(w, id, s.Logger)
		return
	}

	if err := s.Store.Dashboards(ctx).Delete(ctx, e); err != nil {
		unknownErrorWithMessage(w, err, s.Logger)
		return
	}
	w.WriteHeader(http.StatusNoContent)
}
643209
func (s *ProjectsService) ListDashboards(projectName string) (*[]DashboardInfo, *Response, error) {
	u := fmt.Sprintf("projects/%s/dashboards/", url.QueryEscape(projectName))

	req, err := s.client.NewRequest("GET", u, nil)
	if err != nil {
		return nil, nil, err
	}

	v := new([]DashboardInfo)
	resp, err := s.client.Do(req, v)
	if err != nil {
		return nil, resp, err
	}

	return v, resp, err
}
644647
func (c *Client) GetDashboard() (*tumblr.Dashboard, error) {
	return c.GetDashboardWithParams(url.Values{})
}
1301016
func (l *ShardedNoTS) DeleteShard(tenantID string) error {
	delete(l.cache, tenantID)
	delete(l.itemCount, tenantID)

	return nil
}
375860
func (s *Service) UpdateDashboard(ctx context.Context, id platform.ID, upd platform.DashboardUpdate) (*platform.Dashboard, error) {
	op := OpPrefix + platform.OpUpdateDashboard
	if err := upd.Valid(); err != nil {
		return nil, &platform.Error{
			Err: err,
			Op:  op,
		}
	}

	d, err := s.FindDashboardByID(ctx, id)
	if err != nil {
		return nil, &platform.Error{
			Err: err,
			Op:  op,
		}
	}

	if err := upd.Apply(d); err != nil {
		return nil, &platform.Error{
			Err: err,
			Op:  op,
		}
	}

	if err := s.PutDashboardWithMeta(ctx, d); err != nil {
		return nil, &platform.Error{
			Err: err,
			Op:  op,
		}
	}

	return d, nil
}
563886
func GetDashboardPermissionsForUser(query *m.GetDashboardPermissionsForUserQuery) error {
	if len(query.DashboardIds) == 0 {
		return m.ErrCommandValidationFailed
	}

	if query.OrgRole == m.ROLE_ADMIN {
		var permissions = make([]*m.DashboardPermissionForUser, 0)
		for _, d := range query.DashboardIds {
			permissions = append(permissions, &m.DashboardPermissionForUser{
				DashboardId:    d,
				Permission:     m.PERMISSION_ADMIN,
				PermissionName: m.PERMISSION_ADMIN.String(),
			})
		}
		query.Result = permissions

		return nil
	}

	params := make([]interface{}, 0)

	// check dashboards that have ACLs via user id, team id or role
	sql := `SELECT d.id AS dashboard_id, MAX(COALESCE(da.permission, pt.permission)) AS permission
	FROM dashboard AS d
		LEFT JOIN dashboard_acl as da on d.folder_id = da.dashboard_id or d.id = da.dashboard_id
		LEFT JOIN team_member as ugm on ugm.team_id =  da.team_id
		LEFT JOIN org_user ou ON ou.role = da.role AND ou.user_id = ?
	`
	params = append(params, query.UserId)

	//check the user's role for dashboards that do not have hasAcl set
	sql += `LEFT JOIN org_user ouRole ON ouRole.user_id = ? AND ouRole.org_id = ?`
	params = append(params, query.UserId)
	params = append(params, query.OrgId)

	sql += `
		LEFT JOIN (SELECT 1 AS permission, 'Viewer' AS role
			UNION SELECT 2 AS permission, 'Editor' AS role
			UNION SELECT 4 AS permission, 'Admin' AS role) pt ON ouRole.role = pt.role
	WHERE
	d.Id IN (?` + strings.Repeat(",?", len(query.DashboardIds)-1) + `) `
	for _, id := range query.DashboardIds {
		params = append(params, id)
	}

	sql += ` AND
	d.org_id = ? AND
	  (
		(d.has_acl = ?  AND (da.user_id = ? OR ugm.user_id = ? OR ou.id IS NOT NULL))
		OR (d.has_acl = ? AND ouRole.id IS NOT NULL)
	)
	group by d.id
	order by d.id asc`
	params = append(params, query.OrgId)
	params = append(params, dialect.BooleanStr(true))
	params = append(params, query.UserId)
	params = append(params, query.UserId)
	params = append(params, dialect.BooleanStr(false))

	err := x.SQL(sql, params...).Find(&query.Result)

	for _, p := range query.Result {
		p.PermissionName = p.Permission.String()
	}

	return err
}
1189361
func (s *PutDeliverabilityDashboardOptionInput) SetDashboardEnabled(v bool) *PutDeliverabilityDashboardOptionInput {
	s.DashboardEnabled = &v
	return s
}
330740
func (api *API) ZoneAnalyticsDashboard(zoneID string, options ZoneAnalyticsOptions) (ZoneAnalyticsData, error) {
	uri := "/zones/" + zoneID + "/analytics/dashboard" + "?" + options.encode()
	res, err := api.makeRequest("GET", uri, nil)
	if err != nil {
		return ZoneAnalyticsData{}, errors.Wrap(err, errMakeRequestError)
	}
	var r zoneAnalyticsDataResponse
	err = json.Unmarshal(res, &r)
	if err != nil {
		return ZoneAnalyticsData{}, errors.Wrap(err, errUnmarshalError)
	}
	return r.Result, nil
}
1198458
func (s *DashboardOperationLogService) GetDashboardOperationLog(ctx context.Context, id platform.ID, opts platform.FindOptions) ([]*platform.OperationLogEntry, int, error) {
	return s.GetDashboardOperationLogFn(ctx, id, opts)
}
170962
func (s *DashboardService) FindDashboardByID(ctx context.Context, id influxdb.ID) (*influxdb.Dashboard, error) {
	b, err := s.s.FindDashboardByID(ctx, id)
	if err != nil {
		return nil, err
	}

	if err := authorizeReadDashboard(ctx, b.OrganizationID, id); err != nil {
		return nil, err
	}

	return b, nil
}
164312
func DeleteDashboardSnapshotByDeleteKey(c *m.ReqContext) Response {
	key := c.Params(":deleteKey")

	query := &m.GetDashboardSnapshotQuery{DeleteKey: key}

	err := bus.Dispatch(query)
	if err != nil {
		return Error(500, "Failed to get dashboard snapshot", err)
	}

	if query.Result.External {
		err := deleteExternalDashboardSnapshot(query.Result.ExternalDeleteUrl)
		if err != nil {
			return Error(500, "Failed to delete external dashboard", err)
		}
	}

	cmd := &m.DeleteDashboardSnapshotCommand{DeleteKey: query.Result.DeleteKey}

	if err := bus.Dispatch(cmd); err != nil {
		return Error(500, "Failed to delete dashboard snapshot", err)
	}

	return JSON(200, util.DynMap{"message": "Snapshot deleted. It might take an hour before it's cleared from any CDN caches."})
}
971915
func SortDashboards(by string, ds []*Dashboard) {
	var sorter func(i, j int) bool
	switch by {
	case "CreatedAt":
		sorter = func(i, j int) bool {
			return ds[j].Meta.CreatedAt.After(ds[i].Meta.CreatedAt)
		}
	case "UpdatedAt":
		sorter = func(i, j int) bool {
			return ds[j].Meta.UpdatedAt.After(ds[i].Meta.UpdatedAt)
		}
	case "Name":
		sorter = func(i, j int) bool {
			return ds[i].Name < ds[j].Name
		}
	default:
		sorter = func(i, j int) bool {
			return ds[i].ID < ds[j].ID
		}
	}

	sort.Slice(ds, sorter)
}