summaryrefslogtreecommitdiffstats
path: root/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/role/PathGroup.java
blob: 0c804d07205e7b52ea71b07b589155abefc3217e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.controller.role;

import com.yahoo.restapi.Path;

import java.util.EnumSet;
import java.util.Optional;
import java.util.Set;

/**
 * This declares and groups all known REST API paths in the controller.
 *
 * When creating a new API, its paths must be added here and a policy must be declared in {@link Policy}.
 *
 * @author mpolden
 */
public enum PathGroup {

    /** Paths used for system management by operators */
    operator("/controller/v1/{*}",
             "/provision/v2/{*}",
             "/flags/v1/{*}",
             "/os/v1/{*}",
             "/cost/v1/{*}",
             "/zone/v2/{*}",
             "/nodes/v2/{*}",
             "/orchestrator/v1/{*}"),

    /** Paths used when onboarding and creating a new tenants */
    onboardingUser("/application/v4/user"),

    // Tenant parameter is ignored here as context for the role is not defined until after a tenant has been created
    onboardingTenant("/application/v4/tenant/{ignored}"),

    /** Read-only paths used when onboarding tenants */
    onboardingTenantInformation("/athenz/v1/",
                                "/athenz/v1/domains"),


    /** Paths used by tenant/application administrators */
    tenant("/application/v4/",
           "/application/v4/property/",
           "/application/v4/tenant/",
           "/application/v4/tenant-pipeline/",
           "/application/v4/tenant/{tenant}",
           "/application/v4/tenant/{tenant}/application/",
           "/application/v4/tenant/{tenant}/application/{application}",
           "/application/v4/tenant/{tenant}/application/{application}/deploying/{*}",
           "/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/job/{job}/{*}",
           "/application/v4/tenant/{tenant}/application/{application}/environment/dev/{*}",
           "/application/v4/tenant/{tenant}/application/{application}/environment/perf/{*}",
           "/application/v4/tenant/{tenant}/application/{application}/environment/prod/region/{region}/instance/{instance}/global-rotation/override"),

    /** Paths used for deployments by build service(s) */
    buildService("/application/v4/tenant/{tenant}/application/{application}/jobreport",
                 "/application/v4/tenant/{tenant}/application/{application}/submit",
                 "/application/v4/tenant/{tenant}/application/{application}/promote",
                 "/application/v4/tenant/{tenant}/application/{application}/environment/prod/{*}",
                 "/application/v4/tenant/{tenant}/application/{application}/environment/test/{*}",
                 "/application/v4/tenant/{tenant}/application/{application}/environment/staging/{*}"),

    /** Read-only paths providing information related to deployments */
    deploymentStatus("/badge/v1/{*}",
                     "/deployment/v1/{*}",
                     "/zone/v1/{*}"),

    /** Paths used by some dashboard */
    dashboard("/",
              "/d/{*}");

    final Set<String> pathSpecs;

    PathGroup(String... pathSpecs) {
        this.pathSpecs = Set.of(pathSpecs);
    }

    /** Returns path if it matches any spec in this group, with match groups set by the match. */
    private Optional<Path> get(String path) {
        Path matcher = new Path(path);
        for (String spec : pathSpecs) // Iterate to be sure the Path's state is that of the match.
            if (matcher.matches(spec)) return Optional.of(matcher);
        return Optional.empty();
    }

    /** All known path groups */
    public static Set<PathGroup> all() {
        return EnumSet.allOf(PathGroup.class);
    }

    /** Returns whether this group matches path in given context */
    public boolean matches(String path, Context context) {
        return get(path).map(p -> {
            boolean match = true;
            String tenant = p.get("tenant");
            if (tenant != null && context.tenant().isPresent()) {
                match = context.tenant().get().value().equals(tenant);
            }
            String application = p.get("application");
            if (application != null && context.application().isPresent()) {
                match &= context.application().get().value().equals(application);
            }
            return match;
        }).orElse(false);
    }

}