// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.network.security;

import com.cloud.async.AsyncInstanceCreateStatus;
import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity;

public interface SecurityRule extends Identity, InternalIdentity {

    public static class SecurityRuleType {
        public static final SecurityRuleType IngressRule = new SecurityRuleType("ingress");
        public static final SecurityRuleType EgressRule = new SecurityRuleType("egress");

        public SecurityRuleType(String type) {
            this._type = type;
        }

        public String getType(){
            return _type;
        }
        private String _type;
    }

    long getSecurityGroupId();

    int getStartPort();

    int getEndPort();

    String getType();

    SecurityRuleType getRuleType();

    String getProtocol();

    AsyncInstanceCreateStatus getCreateStatus();

    Long getAllowedNetworkId();

    String getAllowedSourceIpCidr();
}
