aboutsummaryrefslogtreecommitdiffstats
path: root/config-provisioning/src/main/java/com/yahoo/config/provision/ZoneEndpoint.java
blob: bf1159668fd9457575a0413e1160e6bce9aceba2 (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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.config.provision;

import ai.vespa.validation.Validation;

import java.util.List;
import java.util.Objects;

/**
 * Settings for a zone endpoint of a deployment.
 *
 * @author jonmv
 */
public class ZoneEndpoint {

    /**
     * Endpoint service generation.
     * <p>
     * This is used to transition to a new set of endpoint services, with new domain names.
     * The procedure is:
     * <ol>
     *     <li>Start using new endpoint names (in controller code), for <em>all</em> applications.</li>
     *     <li>Bump the generation counter here; this causes new services to be provisioned.</li>
     *     <li>Controller configures the new services with the new endpoint names.</li>
     *     <li>Let users migrate to the new endpoint names.</li>
     *     <li>Currently missing: clean up obsolete, unused endpoint services.</li>
     * </ol>
     */
    public static final int generation = 0;
    public static final ZoneEndpoint defaultEndpoint = new ZoneEndpoint(true, false, List.of());
    public static final ZoneEndpoint privateEndpoint = new ZoneEndpoint(false, false, List.of());

    private final boolean isPublicEndpoint;
    private final boolean isPrivateEndpoint;
    private final List<AllowedUrn> allowedUrns;

    public ZoneEndpoint(boolean isPublicEndpoint, boolean isPrivateEndpoint, List<AllowedUrn> allowedUrns) {
        this.isPublicEndpoint = isPublicEndpoint;
        this.isPrivateEndpoint = isPrivateEndpoint;
        this.allowedUrns = List.copyOf(allowedUrns);
    }

    /** Whether this has an endpoint which is visible from the public internet. */
    public boolean isPublicEndpoint() {
        return isPublicEndpoint;
    }

    /** Whether this has an endpoint which is visible through private DNS of the cloud. */
    public boolean isPrivateEndpoint() {
        return isPrivateEndpoint;
    }

    /** List of allowed URNs, for specified private access types. */
    public List<AllowedUrn> allowedUrns() {
        return allowedUrns;
    }

    /** List of URNs for the given access type. */
    public List<String> allowedUrnsWith(AccessType type) {
        return allowedUrns.stream().filter(urn -> urn.type == type).map(AllowedUrn::urn).toList();
    }

    public boolean isDefault() {
        return equals(defaultEndpoint);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ZoneEndpoint that = (ZoneEndpoint) o;
        return isPublicEndpoint == that.isPublicEndpoint && isPrivateEndpoint == that.isPrivateEndpoint && allowedUrns.equals(that.allowedUrns);
    }

    @Override
    public int hashCode() {
        return Objects.hash(isPublicEndpoint, isPrivateEndpoint, allowedUrns);
    }

    @Override
    public String toString() {
        return "ZoneEndpoint{" +
               "isPublicEndpoint=" + isPublicEndpoint +
               ", isPrivateEndpoint=" + isPrivateEndpoint +
               ", allowedUrns=" + allowedUrns +
               '}';
    }

    public enum AccessType {
        awsPrivateLink,
        gcpServiceConnect,
    }

    /** A URN allowed to access this (private) endpoint, through a {@link AccessType} method. */
    public static class AllowedUrn {

        private final AccessType type;
        private final String urn;

        public AllowedUrn(AccessType type, String urn) {
            this.type = Objects.requireNonNull(type);
            this.urn = Validation.requireNonBlank(urn, "URN");
        }

        /** Type of private connection. */
        public AccessType type() {
            return type;
        }

        /** URN allowed to access this private endpoint. */
        public String urn() {
            return urn;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            AllowedUrn that = (AllowedUrn) o;
            return type == that.type && urn.equals(that.urn);
        }

        @Override
        public int hashCode() {
            return Objects.hash(type, urn);
        }

        @Override
        public String toString() {
            return "'" + urn + "' through '" +
                   switch (type) {
                       case awsPrivateLink -> "aws-private-link";
                       case gcpServiceConnect -> "gcp-service-connect";
                   } + "'";
        }

    }

}